vendor/pimcore/pimcore/lib/Routing/Staticroute/Router.php line 258

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Routing\Staticroute;
  15. use Pimcore\Bundle\CoreBundle\EventListener\Frontend\ElementListener;
  16. use Pimcore\Config;
  17. use Pimcore\Model\Site;
  18. use Pimcore\Model\Staticroute;
  19. use Psr\Log\LoggerAwareInterface;
  20. use Psr\Log\LoggerAwareTrait;
  21. use Symfony\Cmf\Component\Routing\VersatileGeneratorInterface;
  22. use Symfony\Component\HttpFoundation\Request;
  23. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  24. use Symfony\Component\Routing\Exception\RouteNotFoundException;
  25. use Symfony\Component\Routing\Generator\UrlGenerator;
  26. use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
  27. use Symfony\Component\Routing\RequestContext;
  28. use Symfony\Component\Routing\RouteCollection;
  29. use Symfony\Component\Routing\RouterInterface;
  30. /**
  31.  * @internal
  32.  *
  33.  * A custom router implementation handling pimcore static routes.
  34.  */
  35. final class Router implements RouterInterfaceRequestMatcherInterfaceVersatileGeneratorInterfaceLoggerAwareInterface
  36. {
  37.     use LoggerAwareTrait;
  38.     /**
  39.      * @var RequestContext
  40.      */
  41.     protected $context;
  42.     /**
  43.      * @var Staticroute[]
  44.      */
  45.     protected $staticRoutes;
  46.     /**
  47.      * @var array
  48.      */
  49.     protected $supportedNames;
  50.     /**
  51.      * Params which are treated as _locale if no _locale attribute is set
  52.      *
  53.      * @var array
  54.      */
  55.     protected $localeParams = [];
  56.     /**
  57.      * @var Config
  58.      */
  59.     protected $config;
  60.     /**
  61.      * @param RequestContext $context
  62.      * @param Config $config
  63.      */
  64.     public function __construct(RequestContext $contextConfig $config)
  65.     {
  66.         $this->context $context;
  67.         $this->config $config;
  68.     }
  69.     /**
  70.      * {@inheritdoc}
  71.      */
  72.     public function setContext(RequestContext $context)
  73.     {
  74.         $this->context $context;
  75.     }
  76.     /**
  77.      * {@inheritdoc}
  78.      */
  79.     public function getContext(): RequestContext
  80.     {
  81.         return $this->context;
  82.     }
  83.     /**
  84.      * @return array
  85.      */
  86.     public function getLocaleParams(): array
  87.     {
  88.         return $this->localeParams;
  89.     }
  90.     /**
  91.      * @param array $localeParams
  92.      */
  93.     public function setLocaleParams(array $localeParams)
  94.     {
  95.         $this->localeParams $localeParams;
  96.     }
  97.     /**
  98.      * {@inheritdoc}
  99.      */
  100.     public function supports($name)
  101.     {
  102.         return is_string($name) && in_array($name$this->getSupportedNames());
  103.     }
  104.     /**
  105.      * {@inheritdoc}
  106.      */
  107.     public function getRouteCollection(): RouteCollection
  108.     {
  109.         return new RouteCollection();
  110.     }
  111.     /**
  112.      * {@inheritdoc}
  113.      */
  114.     public function getRouteDebugMessage($name, array $parameters = []): string
  115.     {
  116.         return (string)$name;
  117.     }
  118.     /**
  119.      * {@inheritdoc}
  120.      */
  121.     public function generate(string $name, array $parameters = [], int $referenceType self::ABSOLUTE_PATH): string
  122.     {
  123.         // ABSOLUTE_URL = http://example.com
  124.         // NETWORK_PATH = //example.com
  125.         $needsHostname self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType;
  126.         $siteId null;
  127.         if (Site::isSiteRequest()) {
  128.             $siteId Site::getCurrentSite()->getId();
  129.         }
  130.         // check for a site in the options, if valid remove it from the options
  131.         $hostname null;
  132.         if (isset($parameters['site'])) {
  133.             $site $parameters['site'];
  134.             if (!empty($site)) {
  135.                 if ($site Site::getBy($site)) {
  136.                     unset($parameters['site']);
  137.                     $hostname $site->getMainDomain();
  138.                     if ($site->getId() !== $siteId) {
  139.                         $needsHostname true;
  140.                         $siteId $site->getId();
  141.                     }
  142.                 } else {
  143.                     $this->logger->warning('The site {site} does not exist for route {route}', [
  144.                         'site' => $siteId,
  145.                         'route' => $name,
  146.                     ]);
  147.                 }
  148.             } else {
  149.                 if ($needsHostname && !empty($this->config['general']['domain'])) {
  150.                     $hostname $this->config['general']['domain'];
  151.                 }
  152.             }
  153.         }
  154.         if (null === $hostname && $needsHostname) {
  155.             $hostname $this->context->getHost();
  156.         }
  157.         if ($name && $route Staticroute::getByName($name$siteId)) {
  158.             $encode = isset($parameters['encode']) ? (bool)$parameters['encode'] : true;
  159.             unset($parameters['encode']);
  160.             // assemble the route / url in Staticroute::assemble()
  161.             $url $route->assemble($parameters$encode);
  162.             $port '';
  163.             $scheme $this->context->getScheme();
  164.             if ('http' === $scheme && 80 !== $this->context->getHttpPort()) {
  165.                 $port ':'.$this->context->getHttpPort();
  166.             } elseif ('https' === $scheme && 443 !== $this->context->getHttpsPort()) {
  167.                 $port ':'.$this->context->getHttpsPort();
  168.             }
  169.             $schemeAuthority self::NETWORK_PATH === $referenceType || '' === $scheme '//' "$scheme://";
  170.             $schemeAuthority .= $hostname.$port;
  171.             if ($needsHostname) {
  172.                 $url $schemeAuthority.$this->context->getBaseUrl().$url;
  173.             } else {
  174.                 if (self::RELATIVE_PATH === $referenceType) {
  175.                     $url UrlGenerator::getRelativePath($this->context->getPathInfo(), $url);
  176.                 } else {
  177.                     $url $this->context->getBaseUrl().$url;
  178.                 }
  179.             }
  180.             return $url;
  181.         }
  182.         throw new RouteNotFoundException(sprintf(
  183.             'Could not generate URL for route %s as the static route wasn\'t found',
  184.             $name
  185.         ));
  186.     }
  187.     /**
  188.      * {@inheritdoc}
  189.      *
  190.      * @return array
  191.      */
  192.     public function matchRequest(Request $request): array
  193.     {
  194.         return $this->doMatch($request->getPathInfo(), $request);
  195.     }
  196.     /**
  197.      * {@inheritdoc}
  198.      *
  199.      * @return array
  200.      */
  201.     public function match($pathinfo): array
  202.     {
  203.         return $this->doMatch($pathinfo);
  204.     }
  205.     /**
  206.      * @param string $pathinfo
  207.      * @param Request|null $request
  208.      *
  209.      * @return array
  210.      */
  211.     protected function doMatch($pathinfoRequest $request null)
  212.     {
  213.         $pathinfo urldecode($pathinfo);
  214.         $params $this->context->getParameters();
  215.         foreach ($this->getStaticRoutes() as $route) {
  216.             if (null !== $request && null !== $route->getMethods() && !== count($route->getMethods())) {
  217.                 $method $request->getMethod();
  218.                 if (!in_array($method$route->getMethods(), true)) {
  219.                     continue;
  220.                 }
  221.             }
  222.             if ($routeParams $route->match($pathinfo$params)) {
  223.                 Staticroute::setCurrentRoute($route);
  224.                 // add the route object also as parameter to the request object, this is needed in
  225.                 // Pimcore_Controller_Action_Frontend::getRenderScript()
  226.                 // to determine if a call to an action was made through a staticroute or not
  227.                 // more on that infos see Pimcore_Controller_Action_Frontend::getRenderScript()
  228.                 $routeParams['pimcore_request_source'] = 'staticroute';
  229.                 $routeParams[ElementListener::FORCE_ALLOW_PROCESSING_UNPUBLISHED_ELEMENTS] = $this->config['routing']['allow_processing_unpublished_fallback_document'];
  230.                 $routeParams['_route'] = $route->getName();
  231.                 $routeParams $this->processRouteParams($routeParams);
  232.                 return $routeParams;
  233.             }
  234.         }
  235.         throw new ResourceNotFoundException(sprintf('No routes found for "%s".'$pathinfo));
  236.     }
  237.     /**
  238.      * @param array $routeParams
  239.      *
  240.      * @return array
  241.      */
  242.     protected function processRouteParams(array $routeParams)
  243.     {
  244.         $keys = [
  245.             'module',
  246.             'controller',
  247.             'action',
  248.         ];
  249.         $controllerParams = [];
  250.         foreach ($keys as $key) {
  251.             $value null;
  252.             if (isset($routeParams[$key])) {
  253.                 $value $routeParams[$key];
  254.             }
  255.             $controllerParams[$key] = $value;
  256.         }
  257.         $routeParams['_controller'] = $controllerParams['controller'];
  258.         // map common language properties (e.g. language) to _locale if not set
  259.         if (!isset($routeParams['_locale'])) {
  260.             foreach ($this->localeParams as $localeParam) {
  261.                 if (isset($routeParams[$localeParam])) {
  262.                     $routeParams['_locale'] = $routeParams[$localeParam];
  263.                     break;
  264.                 }
  265.             }
  266.         }
  267.         return $routeParams;
  268.     }
  269.     /**
  270.      * @return Staticroute[]
  271.      */
  272.     protected function getStaticRoutes()
  273.     {
  274.         if (null === $this->staticRoutes) {
  275.             /** @var Staticroute\Listing|Staticroute\Listing\Dao $list */
  276.             $list = new Staticroute\Listing();
  277.             $list->setOrder(function ($a$b) {
  278.                 // give site ids a higher priority
  279.                 if ($a->getSiteId() && !$b->getSiteId()) {
  280.                     return -1;
  281.                 }
  282.                 if (!$a->getSiteId() && $b->getSiteId()) {
  283.                     return 1;
  284.                 }
  285.                 if ($a->getPriority() == $b->getPriority()) {
  286.                     return 0;
  287.                 }
  288.                 return ($a->getPriority() < $b->getPriority()) ? : -1;
  289.             });
  290.             $this->staticRoutes $list->load();
  291.         }
  292.         return $this->staticRoutes;
  293.     }
  294.     /**
  295.      * @return array
  296.      */
  297.     protected function getSupportedNames()
  298.     {
  299.         if (null === $this->supportedNames) {
  300.             $this->supportedNames = [];
  301.             foreach ($this->getStaticRoutes() as $route) {
  302.                 $this->supportedNames[] = $route->getName();
  303.             }
  304.             $this->supportedNames array_unique($this->supportedNames);
  305.         }
  306.         return $this->supportedNames;
  307.     }
  308. }