vendor/sulu/sulu/src/Sulu/Bundle/CustomUrlBundle/Request/CustomUrlRequestProcessor.php line 76

  1. <?php
  2. /*
  3.  * This file is part of Sulu.
  4.  *
  5.  * (c) Sulu GmbH
  6.  *
  7.  * This source file is subject to the MIT license that is bundled
  8.  * with this source code in the file LICENSE.
  9.  */
  10. namespace Sulu\Bundle\CustomUrlBundle\Request;
  11. use Sulu\Component\Content\Document\WorkflowStage;
  12. use Sulu\Component\CustomUrl\Generator\GeneratorInterface;
  13. use Sulu\Component\CustomUrl\Manager\CustomUrlManagerInterface;
  14. use Sulu\Component\Localization\Localization;
  15. use Sulu\Component\Webspace\Analyzer\Attributes\RequestAttributes;
  16. use Sulu\Component\Webspace\Analyzer\Attributes\RequestProcessorInterface;
  17. use Sulu\Component\Webspace\Analyzer\RequestAnalyzer;
  18. use Sulu\Component\Webspace\Manager\WebspaceManagerInterface;
  19. use Sulu\Component\Webspace\PortalInformation;
  20. use Symfony\Component\HttpFoundation\Request;
  21. /**
  22.  * Set localization in case of custom-url route.
  23.  */
  24. class CustomUrlRequestProcessor implements RequestProcessorInterface
  25. {
  26.     /**
  27.      * @var CustomUrlManagerInterface
  28.      */
  29.     private $customUrlManager;
  30.     /**
  31.      * @var GeneratorInterface
  32.      */
  33.     private $generator;
  34.     /**
  35.      * @var WebspaceManagerInterface
  36.      */
  37.     private $webspaceManager;
  38.     /**
  39.      * @var string
  40.      */
  41.     private $environment;
  42.     public function __construct(
  43.         CustomUrlManagerInterface $customUrlManager,
  44.         GeneratorInterface $generator,
  45.         WebspaceManagerInterface $webspaceManager,
  46.         $environment
  47.     ) {
  48.         $this->customUrlManager $customUrlManager;
  49.         $this->generator $generator;
  50.         $this->webspaceManager $webspaceManager;
  51.         $this->environment $environment;
  52.     }
  53.     public function process(Request $requestRequestAttributes $requestAttributes)
  54.     {
  55.         $pathInfo $request->getPathInfo();
  56.         $position \strrpos($pathInfo'.');
  57.         if ($position) {
  58.             $pathInfo \substr($pathInfo0$position);
  59.         }
  60.         $queryString $request->getQueryString();
  61.         if (!empty($queryString)) {
  62.             $queryString '?' $queryString;
  63.         }
  64.         $url $this->decodeUrl(\rtrim(\sprintf('%s%s%s'$request->getHost(), $pathInfo$queryString), '/'));
  65.         $portalInformations $this->webspaceManager->findPortalInformationsByUrl($url$this->environment);
  66.         if (=== \count($portalInformations)) {
  67.             return new RequestAttributes();
  68.         }
  69.         /** @var PortalInformation[] $portalInformations */
  70.         $portalInformations \array_filter(
  71.             $portalInformations,
  72.             function(PortalInformation $portalInformation) {
  73.                 return RequestAnalyzer::MATCH_TYPE_WILDCARD === $portalInformation->getType();
  74.             }
  75.         );
  76.         foreach ($portalInformations as $portalInformation) {
  77.             if (!$portalInformation->getWebspace()) {
  78.                 continue;
  79.             }
  80.             if (null !== $attributes $this->matchCustomUrl($url$portalInformation$request)) {
  81.                 return new RequestAttributes($attributes);
  82.             }
  83.         }
  84.         return new RequestAttributes();
  85.     }
  86.     public function validate(RequestAttributes $attributes)
  87.     {
  88.         return true;
  89.     }
  90.     /**
  91.      * Matches given url to portal-information.
  92.      */
  93.     private function matchCustomUrl(string $urlPortalInformation $portalInformationRequest $request): array
  94.     {
  95.         $webspace $portalInformation->getWebspace();
  96.         $routeDocument $this->customUrlManager->findRouteByUrl(
  97.             \rawurldecode($url),
  98.             $webspace->getKey()
  99.         );
  100.         if (!$routeDocument) {
  101.             return [];
  102.         } elseif ($routeDocument->isHistory()) {
  103.             // redirect happen => no portal is needed
  104.             return ['customUrlRoute' => $routeDocument];
  105.         }
  106.         $customUrlDocument $this->customUrlManager->findByUrl(
  107.             \rawurldecode($url),
  108.             $webspace->getKey(),
  109.             $routeDocument->getTargetDocument()->getTargetLocale()
  110.         );
  111.         if (null === $customUrlDocument
  112.             || false === $customUrlDocument->isPublished()
  113.             || null === $customUrlDocument->getTargetDocument()
  114.             || WorkflowStage::PUBLISHED !== $customUrlDocument->getTargetDocument()->getWorkflowStage()
  115.         ) {
  116.             // error happen because this custom-url is not published => no portal is needed
  117.             return ['customUrlRoute' => $routeDocument'customUrl' => $customUrlDocument];
  118.         }
  119.         $localization Localization::createFromString($customUrlDocument->getTargetLocale());
  120.         $portalInformations $this->webspaceManager->findPortalInformationsByWebspaceKeyAndLocale(
  121.             $portalInformation->getWebspace()->getKey(),
  122.             $localization->getLocale(),
  123.             $this->environment
  124.         );
  125.         if (=== \count($portalInformations)) {
  126.             return ['customUrlRoute' => $routeDocument'customUrl' => $customUrlDocument];
  127.         }
  128.         return [
  129.             'portalInformation' => $portalInformation,
  130.             'localization' => $localization,
  131.             'locale' => $localization->getLocale(),
  132.             'customUrlRoute' => $routeDocument,
  133.             'customUrl' => $customUrlDocument,
  134.             'urlExpression' => $this->generator->generate(
  135.                 $customUrlDocument->getBaseDomain(),
  136.                 $customUrlDocument->getDomainParts()
  137.             ),
  138.         ];
  139.     }
  140.     /**
  141.      * Server encodes the url and symfony does not encode it
  142.      * Symfony decodes this data here https://github.com/symfony/symfony/blob/3.3/src/Symfony/Component/Routing/Matcher/UrlMatcher.php#L91.
  143.      */
  144.     private function decodeUrl(string $pathInfo): string
  145.     {
  146.         return \rawurldecode($pathInfo);
  147.     }
  148. }