Upgraded drupal core with security updates
[yaffs-website] / web / core / modules / language / src / Plugin / LanguageNegotiation / LanguageNegotiationSession.php
1 <?php
2
3 namespace Drupal\language\Plugin\LanguageNegotiation;
4
5 use Drupal\Core\Language\LanguageInterface;
6 use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
7 use Drupal\Core\Render\BubbleableMetadata;
8 use Drupal\Core\Url;
9 use Drupal\language\LanguageNegotiationMethodBase;
10 use Drupal\language\LanguageSwitcherInterface;
11 use Symfony\Component\HttpFoundation\Request;
12
13 /**
14  * Identify language from a request/session parameter.
15  *
16  * @LanguageNegotiation(
17  *   id = Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationSession::METHOD_ID,
18  *   weight = -6,
19  *   name = @Translation("Session"),
20  *   description = @Translation("Language from a request/session parameter."),
21  *   config_route_name = "language.negotiation_session"
22  * )
23  */
24 class LanguageNegotiationSession extends LanguageNegotiationMethodBase implements OutboundPathProcessorInterface, LanguageSwitcherInterface {
25
26   /**
27    * Flag used to determine whether query rewriting is active.
28    *
29    * @var bool
30    */
31   protected $queryRewrite;
32
33   /**
34    * The query parameter name to rewrite.
35    *
36    * @var string
37    */
38   protected $queryParam;
39
40   /**
41    * The query parameter value to be set.
42    *
43    * @var string
44    */
45   protected $queryValue;
46
47   /**
48    * The language negotiation method id.
49    */
50   const METHOD_ID = 'language-session';
51
52   /**
53    * {@inheritdoc}
54    */
55   public function getLangcode(Request $request = NULL) {
56     $config = $this->config->get('language.negotiation')->get('session');
57     $param = $config['parameter'];
58     $langcode = $request && $request->query->get($param) ? $request->query->get($param) : NULL;
59     if (!$langcode && isset($_SESSION[$param])) {
60       $langcode = $_SESSION[$param];
61     }
62     return $langcode;
63   }
64
65   /**
66    * {@inheritdoc}
67    */
68   public function persist(LanguageInterface $language) {
69     // We need to update the session parameter with the request value only if we
70     // have an authenticated user.
71     $langcode = $language->getId();
72     if ($langcode && $this->languageManager) {
73       $languages = $this->languageManager->getLanguages();
74       if ($this->currentUser->isAuthenticated() && isset($languages[$langcode])) {
75         $config = $this->config->get('language.negotiation')->get('session');
76         $_SESSION[$config['parameter']] = $langcode;
77       }
78     }
79   }
80
81   /**
82    * {@inheritdoc}
83    */
84   public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
85     if ($request) {
86       // The following values are not supposed to change during a single page
87       // request processing.
88       if (!isset($this->queryRewrite)) {
89         if ($this->currentUser->isAnonymous()) {
90           $languages = $this->languageManager->getLanguages();
91           $config = $this->config->get('language.negotiation')->get('session');
92           $this->queryParam = $config['parameter'];
93           $this->queryValue = $request->query->has($this->queryParam) ? $request->query->get($this->queryParam) : NULL;
94           $this->queryRewrite = isset($languages[$this->queryValue]);
95         }
96         else {
97           $this->queryRewrite = FALSE;
98         }
99       }
100
101       // If the user is anonymous, the user language negotiation method is
102       // enabled, and the corresponding option has been set, we must preserve
103       // any explicit user language preference even with cookies disabled.
104       if ($this->queryRewrite) {
105         if (!isset($options['query'][$this->queryParam])) {
106           $options['query'][$this->queryParam] = $this->queryValue;
107         }
108         if ($bubbleable_metadata) {
109           // Cached URLs that have been processed by this outbound path
110           // processor must be:
111           $bubbleable_metadata
112             // - invalidated when the language negotiation config changes, since
113             //   another query parameter may be used to determine the language.
114             ->addCacheTags($this->config->get('language.negotiation')->getCacheTags())
115             // - varied by the configured query parameter.
116             ->addCacheContexts(['url.query_args:' . $this->queryParam]);
117         }
118       }
119     }
120     return $path;
121   }
122
123   /**
124    * {@inheritdoc}
125    */
126   public function getLanguageSwitchLinks(Request $request, $type, Url $url) {
127     $links = [];
128     $config = $this->config->get('language.negotiation')->get('session');
129     $param = $config['parameter'];
130     $language_query = isset($_SESSION[$param]) ? $_SESSION[$param] : $this->languageManager->getCurrentLanguage($type)->getId();
131     $query = [];
132     parse_str($request->getQueryString(), $query);
133
134     foreach ($this->languageManager->getNativeLanguages() as $language) {
135       $langcode = $language->getId();
136       $links[$langcode] = [
137         // We need to clone the $url object to avoid using the same one for all
138         // links. When the links are rendered, options are set on the $url
139         // object, so if we use the same one, they would be set for all links.
140         'url' => clone $url,
141         'title' => $language->getName(),
142         'attributes' => ['class' => ['language-link']],
143         'query' => $query,
144       ];
145       if ($language_query != $langcode) {
146         $links[$langcode]['query'][$param] = $langcode;
147       }
148       else {
149         $links[$langcode]['attributes']['class'][] = 'session-active';
150       }
151     }
152
153     return $links;
154   }
155
156 }