/** * Find a URI segment in the content dimension presets for the given "language" dimension values * * This will do a reverse lookup from actual dimension values to a preset and fall back to the default preset if none * can be found. * * @param array $dimensionsValues An array of dimensions and their values, indexed by dimension name * @param boolean $currentNodeIsSiteNode If the current node is actually the site node * @return string * @throws \Exception */ protected function getUriSegmentForDimensions(array $dimensionsValues, $currentNodeIsSiteNode) { $uriSegment = ''; $allDimensionPresetsAreDefault = TRUE; foreach ($this->contentDimensionPresetSource->getAllPresets() as $dimensionName => $dimensionPresets) { $preset = NULL; if (isset($dimensionsValues[$dimensionName])) { $preset = $this->contentDimensionPresetSource->findPresetByDimensionValues($dimensionName, $dimensionsValues[$dimensionName]); } $defaultPreset = $this->contentDimensionPresetSource->getDefaultPreset($dimensionName); if ($preset === NULL) { $preset = $defaultPreset; } if ($preset !== $defaultPreset) { $allDimensionPresetsAreDefault = FALSE; } if (!isset($preset['uriSegment'])) { throw new \Exception(sprintf('No "uriSegment" configured for content dimension preset "%s" for dimension "%s". Please check the content dimension configuration in Settings.yaml', $preset['identifier'], $dimensionName), 1395824520); } $uriSegment .= $preset['uriSegment'] . '_'; } if ($allDimensionPresetsAreDefault && $currentNodeIsSiteNode) { return '/'; } else { return ltrim(trim($uriSegment, '_') . '/', '/'); } }
/** * @param ComponentContext $componentContext * @return void */ public function handle(ComponentContext $componentContext) { $httpRequest = $componentContext->getHttpRequest(); $requestPath = $httpRequest->getUri()->getPath(); $firstRequestPathSegment = explode('/', ltrim($requestPath, '/'))[0]; //Check if url contains user, if so, don't detect language if (strpos($requestPath, '@user-')) { return; } if (isset($this->options['allowedMethods']) && !in_array($httpRequest->getMethod(), $this->options['allowedMethods'])) { //the current HTTP method is not within the allow methods, abort! return; } $preset = null; if (!isset($this->options['ignoreSegments']) || !in_array($firstRequestPathSegment, $this->options['ignoreSegments'])) { $preset = $this->findPreset($firstRequestPathSegment); if ($preset !== null) { //uri contains a valid language segment => no need for us to proceed return; } } else { //the configuration told us to ignore this segment => no need for us to proceed return; } $defaultPreset = $this->contentDimensionPresetSource->getDefaultPreset('language'); $referer = $httpRequest->getHeaders()->get('Referer'); $refererInfo = $this->parseUriInfo($referer); $currentInfo = $this->parseUriInfo((string) $httpRequest->getUri()); $varnishInfo = isset($this->varnishSettings['varnishUrl']) ? $this->parseUriInfo($this->varnishSettings['varnishUrl']) : null; if ($refererInfo['host'] == $currentInfo['host'] || $varnishInfo !== null && $refererInfo['host'] == $varnishInfo['host']) { $firstRefererRequestPathSegment = explode('/', ltrim($refererInfo['requestPath'], '/'))[0]; $refererPreset = $preset = $this->findPreset($firstRefererRequestPathSegment); if (empty($firstRequestPathSegment) && $refererPreset !== null && empty(ltrim(str_replace($firstRefererRequestPathSegment, '', $refererInfo['requestPath']), '/'))) { $preset = $defaultPreset; } else { $preset = $refererPreset; } } else { $detectedLocale = $this->localeDetector->detectLocaleFromHttpHeader($httpRequest->getHeader('Accept-Language')); if ($detectedLocale instanceof Locale) { $preset = $this->findPreset($detectedLocale->getLanguage()); if ($preset !== null && empty(trim($requestPath, " \t\n\r\v/")) && $preset['uriSegment'] == $defaultPreset['uriSegment']) { //we're on the homepage, and the browsers language is equal to the default language => no need for us to proceed return; } } } if ($preset === null) { $preset = $defaultPreset; } if ($preset === null) { throw new Exception("Couldn't resolve the language and default language is not set. Check your language config."); return; } $uri = $httpRequest->getUri(); if (isset($this->httpSettings['baseUri'])) { $baseInfo = $this->parseUriInfo($this->httpSettings['baseUri']); $uri->setHost($baseInfo['host']); } if (isset($this->httpSettings['port'])) { $uri->setPort($this->httpSettings['port']); } if (isset($this->httpSettings['username'])) { $uri->setUsername($this->httpSettings['username']); } if (isset($this->httpSettings['password'])) { $uri->setUsername($this->httpSettings['password']); } $uri->setPath('/' . $preset['uriSegment'] . $requestPath); $response = $componentContext->getHttpResponse(); $response->setContent(sprintf('<html><head><meta http-equiv="refresh" content="0;url=%s"/></head></html>', htmlentities((string) $uri, ENT_QUOTES, 'utf-8'))); $response->setHeader('Location', (string) $uri); $componentContext->setParameter(ComponentChain::class, 'cancel', TRUE); }