/** * Set the active theme if there is a portal. * * @param GetResponseEvent $event */ public function onKernelRequest(GetResponseEvent $event) { $portal = $this->requestAnalyzer->getPortal(); if (null === $portal) { return; } $themeKey = $portal->getWebspace()->getTheme()->getKey(); $this->activeTheme->setName($themeKey); }
/** * Renders the correct title of the current page. The correct title is either the title provided by the SEO * extension, or the title of the content, if the SEO extension does not provide one. * * @deprecated use the twig include function to render the seo */ public function renderSeoTags(\Twig_Environment $twig, array $seoExtension, array $content, array $urls, $shadowBaseLocale) { $template = 'SuluWebsiteBundle:Extension:seo.html.twig'; @trigger_error('This twig extension is deprecated and should not be used anymore, include the "%s".', $template); $defaultLocale = null; $portal = $this->requestAnalyzer->getPortal(); if ($portal) { $defaultLocale = $portal->getXDefaultLocalization()->getLocale(); } return $twig->render($template, ['seo' => $seoExtension, 'content' => $content, 'urls' => $urls, 'defaultLocale' => $defaultLocale, 'shadowBaseLocale' => $shadowBaseLocale]); }
/** * {@inheritdoc} */ public function resolve(RequestAnalyzerInterface $requestAnalyzer) { // determine default locale (if one exists) $defaultLocalization = $requestAnalyzer->getPortal()->getDefaultLocalization(); $defaultLocale = $defaultLocalization ? $defaultLocalization->getLocalization() : null; $currentLocale = null; $currentLocalization = $requestAnalyzer->getCurrentLocalization(); if ($currentLocalization) { $currentLocale = $currentLocalization->getLocale(); } return ['request' => ['webspaceKey' => $requestAnalyzer->getWebspace()->getKey(), 'portalKey' => $requestAnalyzer->getPortal()->getKey(), 'defaultLocale' => $defaultLocale, 'locale' => $currentLocale, 'portalUrl' => $requestAnalyzer->getPortalUrl(), 'resourceLocatorPrefix' => $requestAnalyzer->getResourceLocatorPrefix(), 'resourceLocator' => $requestAnalyzer->getResourceLocator(), 'get' => $requestAnalyzer->getGetParameters(), 'post' => $requestAnalyzer->getPostParameters(), 'analyticsKey' => $requestAnalyzer->getAnalyticsKey()]]; }
/** * Finds the correct route for the current request. * It loads the correct data with the content mapper. * * @param Request $request A request against which to match. * * @return \Symfony\Component\Routing\RouteCollection with all Routes that * could potentially match $request. Empty collection if nothing can * match. */ public function getRouteCollectionForRequest(Request $request) { $collection = new RouteCollection(); $htmlExtension = '.html'; $resourceLocator = $this->requestAnalyzer->getResourceLocator(); if ($this->requestAnalyzer->getMatchType() == RequestAnalyzerInterface::MATCH_TYPE_REDIRECT || $this->requestAnalyzer->getMatchType() == RequestAnalyzerInterface::MATCH_TYPE_PARTIAL) { // redirect webspace correctly with language $collection->add('redirect_' . uniqid(), $this->getRedirectWebSpaceRoute($request)); } elseif ($request->getRequestFormat() === 'html' && substr($request->getPathInfo(), -strlen($htmlExtension)) === $htmlExtension) { // redirect *.html to * (without url) $collection->add('redirect_' . uniqid(), $this->getRedirectRoute($request, $this->getUrlWithoutEndingTrailingSlash($resourceLocator))); } else { // just show the page $portal = $this->requestAnalyzer->getPortal(); $language = $this->requestAnalyzer->getCurrentLocalization()->getLocalization(); try { // load content by url ignore ending trailing slash $content = $this->contentMapper->loadByResourceLocator(rtrim($resourceLocator, '/'), $portal->getWebspace()->getKey(), $language); if (preg_match('/\\/$/', $resourceLocator) && $this->requestAnalyzer->getResourceLocatorPrefix() && $content->getNodeState() === StructureInterface::STATE_PUBLISHED) { // redirect page to page without slash at the end $collection->add('redirect_' . uniqid(), $this->getRedirectWebSpaceRoute($request)); } elseif ($content->getNodeType() === Structure::NODE_TYPE_INTERNAL_LINK && $content->getNodeState() === StructureInterface::STATE_PUBLISHED) { // redirect internal link $collection->add($content->getKey() . '_' . uniqid(), $this->getRedirectRoute($request, $this->requestAnalyzer->getResourceLocatorPrefix() . $content->getResourceLocator())); } elseif ($content->getNodeType() === Structure::NODE_TYPE_EXTERNAL_LINK && $content->getNodeState() === StructureInterface::STATE_PUBLISHED) { $collection->add($content->getKey() . '_' . uniqid(), $this->getRedirectRoute($request, $content->getResourceLocator())); } elseif ($content->getNodeState() === StructureInterface::STATE_TEST || !$content->getHasTranslation() || !$this->checkResourceLocator()) { // error 404 page not published throw new ResourceLocatorNotFoundException(); } else { // show the page $collection->add($content->getKey() . '_' . uniqid(), $this->getStructureRoute($request, $content)); } } catch (ResourceLocatorNotFoundException $exc) { // just do not add any routes to the collection } catch (ResourceLocatorMovedException $exc) { // old url resource was moved $collection->add($exc->getNewResourceLocatorUuid() . '_' . uniqid(), $this->getRedirectRoute($request, $this->requestAnalyzer->getResourceLocatorPrefix() . $exc->getNewResourceLocator())); } catch (RepositoryException $exc) { // just do not add any routes to the collection } } return $collection; }
/** * Returns alternate link HTML tags with href-lang attributes. * * @param array $urls * * @return string */ public function getAlternateLinks($urls) { // determine default and current values $webspaceKey = $this->requestAnalyzer->getWebspace()->getKey(); $currentPortal = $this->requestAnalyzer->getPortal(); $defaultLocale = null; if ($currentPortal !== null && ($defaultLocale = $currentPortal->getDefaultLocalization()) !== null) { $defaultLocale = $defaultLocale->getLocalization(); } $result = []; foreach ($urls as $locale => $url) { if ($url !== null) { if ($locale === $defaultLocale) { $result[] = $this->getAlternate($url, $webspaceKey, $locale, true); } $result[] = $this->getAlternate($url, $webspaceKey, $locale); } } return implode(PHP_EOL, $result); }
protected function setUp() { parent::setUp(); $this->requestAnalyzer = $this->prophesize(RequestAnalyzerInterface::class); $webspace = new Webspace(); $webspace->setKey('sulu_test'); $locale = new Localization(); $locale->setLanguage('en'); $portal = new Portal(); $portal->setDefaultLocalization($locale); $this->requestAnalyzer->getWebspace()->willReturn($webspace); $this->requestAnalyzer->getPortal()->willReturn($portal); $this->requestAnalyzer->getCurrentLocalization()->willReturn($locale); $this->contentPath = $this->prophesize(ContentPathInterface::class); $this->contentPath->getContentPath('/test', 'sulu_test', 'de')->willReturn('/de/test'); $this->contentPath->getContentPath('/test-en', 'sulu_test', 'en')->willReturn('/en/test-en'); $this->contentPath->getContentPath('/test-en-us', 'sulu_test', 'en-us')->willReturn('/en/test-en-us'); $this->contentPath->getContentPath('/test-en-us', 'sulu_test', 'en_us')->willReturn('/en/test-en-us'); $this->contentPath->getContentPath('/test-fr', 'sulu_test', 'fr')->willReturn('/fr/test-fr'); }
/** * @dataProvider provideSeoData * * @param $seoExtension * @param $content * @param $urls * @param $defaultLocale * @param $shadowBaseLocale * @param $expectedResults * @param array $unexpectedResults */ public function testRenderSeoTags($seoExtension, $content, $urls, $defaultLocale, $shadowBaseLocale, $expectedResults, $unexpectedResults = []) { /** @var Localization $localization */ $localization = $this->prophesize(Localization::class); $localization->getLocalization()->willReturn($defaultLocale); /** @var Portal $portal */ $portal = $this->prophesize(Portal::class); $portal->getDefaultLocalization()->willReturn($localization->reveal()); $this->requestAnalyzer->getPortal()->willReturn($portal->reveal()); $webspace = $this->prophesize(Webspace::class); $this->requestAnalyzer->getWebspace()->willReturn($webspace); $this->contentPath->getContentPath(Argument::cetera())->will(function ($arguments) { return '/' . str_replace('_', '-', $arguments[2]) . $arguments[0]; }); $result = $this->seoTwigExtension->renderSeoTags($seoExtension, $content, $urls, $shadowBaseLocale); foreach ($expectedResults as $expectedResult) { $this->assertContains($expectedResult, $result); } foreach ($unexpectedResults as $unexpectedResult) { $this->assertNotContains($unexpectedResult, $result); } }
/** * Returns alternate link HTML tags with href-lang attributes. * * @param array $urls * * @return string * * @deprecated since 1.1 use SeoTwigExtension::renderSeoTags - sulu_seo */ public function getAlternateLinks($urls) { // determine default and current values $webspaceKey = $this->requestAnalyzer->getWebspace()->getKey(); $currentPortal = $this->requestAnalyzer->getPortal(); $defaultLocale = null; if ($currentPortal !== null && ($defaultLocale = $currentPortal->getXDefaultLocalization()) !== null) { $defaultLocale = $defaultLocale->getLocalization(); } $result = []; foreach ($urls as $locale => $url) { // url = '/' means that there is no translation for this page // the only exception is the homepage where the requested resource-locator is '/' if ($url !== '/' || $this->requestAnalyzer->getResourceLocator() === '/') { if ($locale === $defaultLocale) { $result[] = $this->getAlternate($url, $webspaceKey, $locale, true); } $result[] = $this->getAlternate($url, $webspaceKey, $locale); } } return implode(PHP_EOL, $result); }
/** * Renders the alternate links for this page, this means all the localizations in which this page is available. In * addition the default localization is also rendered. * * @param string[] $urls All the localized URLs for the current page * @param string $webspaceKey The key of the current webspace * * @return string The rendered HTML tags */ private function renderAlternateLinks(array $urls, $webspaceKey) { $html = ''; $portal = $this->requestAnalyzer->getPortal(); $defaultLocale = null; if ($portal) { $defaultLocale = $portal->getDefaultLocalization()->getLocalization(); $html .= $this->renderAlternateLink($urls[$defaultLocale], $webspaceKey, $defaultLocale, true); } foreach ($urls as $locale => $url) { $html .= $this->renderAlternateLink($url, $webspaceKey, $locale); } return $html; }
/** * @return array */ protected function getUrls() { $request = $this->requestStack->getCurrentRequest(); $urls = []; if ($request->get('_route')) { $portalInformations = $this->webspaceManager->getPortalInformations($this->environment); $routeParams = $request->get('_route_params'); $routeName = $request->get('_route'); foreach ($portalInformations as $portalInformation) { if ($portalInformation->getPortalKey() === $this->requestAnalyzer->getPortal()->getKey() && $portalInformation->getType() === RequestAnalyzerInterface::MATCH_TYPE_FULL) { if (isset($routeParams['prefix'])) { $routeParams['prefix'] = $portalInformation->getPrefix(); } $url = $this->router->generate($routeName, $routeParams, true); $urls[$portalInformation->getLocale()] = $url; } } } return $urls; }
/** * Renders the alternate links for this page, this means all the localizations in which this page is available. In * addition the default localization is also rendered. * * @param string[] $urls All the localized URLs for the current page * @param string $webspaceKey The key of the current webspace * * @return string The rendered HTML tags */ private function renderAlternateLinks(array $urls, $webspaceKey) { $html = ''; $defaultLocale = null; $portal = $this->requestAnalyzer->getPortal(); if ($portal) { $defaultLocale = $portal->getXDefaultLocalization()->getLocalization(); } foreach ($urls as $locale => $url) { // url = '/' means that there is no translation for this page // the only exception is the homepage where the requested resource-locator is false if ($url !== '/' || $this->requestAnalyzer->getResourceLocator() === false) { if ($defaultLocale === $locale) { $html .= $this->renderAlternateLink($url, $webspaceKey, $locale, true); } $html .= $this->renderAlternateLink($url, $webspaceKey, $locale); } } return $html; }
/** * {@inheritdoc} */ public function getDefaultLocale() { $request = $this->requestStack->getCurrentRequest(); if (null === $request) { return $this->requestAnalyzer->getPortal()->getDefaultLocalization(); } $defaultLocalization = $this->requestAnalyzer->getPortal()->getDefaultLocalization()->getLocale(Localization::LCID); $localizations = [$defaultLocalization]; foreach ($this->requestAnalyzer->getPortal()->getLocalizations() as $localization) { if ($localization->getLocale(Localization::LCID) !== $defaultLocalization) { $localizations[] = $localization->getLocale(Localization::LCID); } } $preferredLocale = $this->requestStack->getCurrentRequest()->getPreferredLanguage($localizations); foreach ($this->requestAnalyzer->getPortal()->getLocalizations() as $localization) { if ($localization->getLocale(Localization::LCID) === $preferredLocale) { return $localization; } } return $this->requestAnalyzer->getPortal()->getDefaultLocalization(); }
/** * Finds the correct route for the current request. * It loads the correct data with the content mapper. * * @param Request $request A request against which to match * * @return \Symfony\Component\Routing\RouteCollection with all Routes that * could potentially match $request. Empty collection if nothing can * match */ public function getRouteCollectionForRequest(Request $request) { $collection = new RouteCollection(); // no portal information without localization supported if ($this->requestAnalyzer->getCurrentLocalization() === null && $this->requestAnalyzer->getMatchType() !== RequestAnalyzerInterface::MATCH_TYPE_PARTIAL && $this->requestAnalyzer->getMatchType() !== RequestAnalyzerInterface::MATCH_TYPE_REDIRECT) { return $collection; } $htmlExtension = '.html'; $resourceLocator = $this->requestAnalyzer->getResourceLocator(); if ($this->requestAnalyzer->getMatchType() == RequestAnalyzerInterface::MATCH_TYPE_REDIRECT || $this->requestAnalyzer->getMatchType() == RequestAnalyzerInterface::MATCH_TYPE_PARTIAL) { // redirect webspace correctly with locale $collection->add('redirect_' . uniqid(), $this->getRedirectWebSpaceRoute()); } elseif ($request->getRequestFormat() === 'html' && substr($request->getPathInfo(), -strlen($htmlExtension)) === $htmlExtension) { // redirect *.html to * (without url) $collection->add('redirect_' . uniqid(), $this->getRedirectRoute($request, $this->getUrlWithoutEndingTrailingSlash($resourceLocator))); } else { // just show the page $portal = $this->requestAnalyzer->getPortal(); $locale = $this->requestAnalyzer->getCurrentLocalization()->getLocalization(); $resourceLocatorStrategy = $this->resourceLocatorStrategyPool->getStrategyByWebspaceKey($portal->getWebspace()->getKey()); try { // load content by url ignore ending trailing slash /** @var PageDocument $document */ $document = $this->documentManager->find($resourceLocatorStrategy->loadByResourceLocator(rtrim($resourceLocator, '/'), $portal->getWebspace()->getKey(), $locale), $locale, ['load_ghost_content' => false]); if (!$document->getTitle()) { // If the title is empty the document does not exist in this locale // Necessary because of https://github.com/sulu/sulu/issues/2724, otherwise locale could be checked return $collection; } if (preg_match('/\\/$/', $resourceLocator) && $this->requestAnalyzer->getResourceLocatorPrefix()) { // redirect page to page without slash at the end $collection->add('redirect_' . uniqid(), $this->getRedirectRoute($request, $this->requestAnalyzer->getResourceLocatorPrefix() . rtrim($resourceLocator, '/'))); } elseif ($document->getRedirectType() === RedirectType::INTERNAL) { // redirect internal link $redirectUrl = $this->requestAnalyzer->getResourceLocatorPrefix() . $document->getRedirectTarget()->getResourceSegment(); if ($request->getQueryString()) { $redirectUrl .= '?' . $request->getQueryString(); } $collection->add($document->getStructureType() . '_' . $document->getUuid(), $this->getRedirectRoute($request, $redirectUrl)); } elseif ($document->getRedirectType() === RedirectType::EXTERNAL) { $collection->add($document->getStructureType() . '_' . $document->getUuid(), $this->getRedirectRoute($request, $document->getRedirectExternal())); } elseif (!$this->checkResourceLocator()) { return $collection; } else { // convert the page to a StructureBridge because of BC /** @var PageBridge $structure */ $structure = $this->structureManager->wrapStructure($this->documentInspector->getMetadata($document)->getAlias(), $this->documentInspector->getStructureMetadata($document)); $structure->setDocument($document); // show the page $collection->add($document->getStructureType() . '_' . $document->getUuid(), $this->getStructureRoute($request, $structure)); } } catch (ResourceLocatorNotFoundException $exc) { // just do not add any routes to the collection } catch (ResourceLocatorMovedException $exc) { // old url resource was moved $collection->add($exc->getNewResourceLocatorUuid() . '_' . uniqid(), $this->getRedirectRoute($request, $this->requestAnalyzer->getResourceLocatorPrefix() . $exc->getNewResourceLocator())); } catch (RepositoryException $exc) { // just do not add any routes to the collection } } return $collection; }
/** * {@inheritdoc} */ public function getDefaultLocale() { return $this->requestAnalyzer->getPortal()->getDefaultLocalization(); }