vendor/shopware/storefront/Framework/Routing/Router.php line 64

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Storefront\Framework\Routing;
  3. use Shopware\Core\PlatformRequest;
  4. use Symfony\Bundle\FrameworkBundle\Routing\Router as SymfonyRouter;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\HttpFoundation\RequestStack;
  7. use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
  8. use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
  9. use Symfony\Component\Routing\RequestContext;
  10. use Symfony\Component\Routing\RouteCollection;
  11. use Symfony\Component\Routing\RouterInterface;
  12. use Symfony\Contracts\Service\ServiceSubscriberInterface;
  13. class Router implements RouterInterfaceRequestMatcherInterfaceWarmableInterfaceServiceSubscriberInterface
  14. {
  15.     /**
  16.      * @var int Used to indicate the router that we only need the path info without the sales channel prefix
  17.      */
  18.     public const PATH_INFO 10;
  19.     /**
  20.      * @var SymfonyRouter
  21.      */
  22.     private $decorated;
  23.     /**
  24.      * @var RequestStack
  25.      */
  26.     private $requestStack;
  27.     /**
  28.      * @internal
  29.      */
  30.     public function __construct(SymfonyRouter $decoratedRequestStack $requestStack)
  31.     {
  32.         $this->decorated $decorated;
  33.         $this->requestStack $requestStack;
  34.     }
  35.     /**
  36.      * @return array
  37.      */
  38.     public static function getSubscribedServices()
  39.     {
  40.         return SymfonyRouter::getSubscribedServices();
  41.     }
  42.     /**
  43.      * @return string[]
  44.      */
  45.     public function warmUp(string $cacheDir)
  46.     {
  47.         return $this->decorated->warmUp($cacheDir);
  48.     }
  49.     /**
  50.      * @return array
  51.      */
  52.     public function matchRequest(Request $request)
  53.     {
  54.         if (!$request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_ID)) {
  55.             return $this->decorated->matchRequest($request);
  56.         }
  57.         $server array_merge(
  58.             $request->server->all(),
  59.             ['REQUEST_URI' => $request->attributes->get(RequestTransformer::SALES_CHANNEL_RESOLVED_URI)]
  60.         );
  61.         $localClone $request->duplicate(nullnullnullnullnull$server);
  62.         return $this->decorated->matchRequest($localClone);
  63.     }
  64.     public function setContext(RequestContext $context)
  65.     {
  66.         return $this->decorated->setContext($context);
  67.     }
  68.     /**
  69.      * @return RequestContext
  70.      */
  71.     public function getContext()
  72.     {
  73.         return $this->decorated->getContext();
  74.     }
  75.     /**
  76.      * @return RouteCollection
  77.      */
  78.     public function getRouteCollection()
  79.     {
  80.         return $this->decorated->getRouteCollection();
  81.     }
  82.     /**
  83.      * @return string
  84.      */
  85.     public function generate(string $name, array $parameters = [], int $referenceType self::ABSOLUTE_PATH)
  86.     {
  87.         $basePath $this->getBasePath();
  88.         if ($referenceType === self::PATH_INFO) {
  89.             $route $this->decorated->generate($name$parametersself::ABSOLUTE_PATH);
  90.             return $this->removePrefix($route$basePath);
  91.         }
  92.         if (!$this->isStorefrontRoute($name)) {
  93.             return $this->decorated->generate($name$parameters$referenceType);
  94.         }
  95.         $salesChannelBaseUrl $this->getSalesChannelBaseUrl();
  96.         // we need to insert the sales channel base url between the baseUrl and the infoPath
  97.         switch ($referenceType) {
  98.             case self::NETWORK_PATH:
  99.             case self::ABSOLUTE_URL:
  100.                 $schema '';
  101.                 if ($referenceType === self::ABSOLUTE_URL) {
  102.                     $schema $this->getContext()->getScheme() . ':';
  103.                 }
  104.                 $schemaAuthority $schema '//' $this->getContext()->getHost();
  105.                 if ($this->getContext()->getHttpPort() !== 80) {
  106.                     $schemaAuthority .= ':' $this->getContext()->getHttpPort();
  107.                 } elseif ($this->getContext()->getHttpsPort() !== 443) {
  108.                     $schemaAuthority .= ':' $this->getContext()->getHttpsPort();
  109.                 }
  110.                 $generated $this->decorated->generate($name$parameters);
  111.                 $pathInfo $this->removePrefix($generated$basePath);
  112.                 $rewrite $schemaAuthority rtrim($basePath'/') . rtrim($salesChannelBaseUrl'/') . $pathInfo;
  113.                 break;
  114.             case self::RELATIVE_PATH:
  115.                 // remove base path from generated url (/shopware/public or /)
  116.                 $generated $this->removePrefix(
  117.                     $this->decorated->generate($name$parametersself::RELATIVE_PATH),
  118.                     $basePath
  119.                 );
  120.                 // url contains the base path and the base url
  121.                     // base url /shopware/public/de
  122.                 $rewrite ltrim($salesChannelBaseUrl'/') . $generated;
  123.                 break;
  124.             case self::ABSOLUTE_PATH:
  125.             default:
  126.                 $generated $this->removePrefix(
  127.                     $this->decorated->generate($name$parameters),
  128.                     $basePath
  129.                 );
  130.                 $rewrite $basePath rtrim($salesChannelBaseUrl'/') . $generated;
  131.                 break;
  132.         }
  133.         return $rewrite;
  134.     }
  135.     /**
  136.      * @return array
  137.      */
  138.     public function match($pathinfo)
  139.     {
  140.         return $this->decorated->match($pathinfo);
  141.     }
  142.     private function removePrefix(string $subjectstring $prefix): string
  143.     {
  144.         if (!$prefix || mb_strpos($subject$prefix) !== 0) {
  145.             return $subject;
  146.         }
  147.         return mb_substr($subjectmb_strlen($prefix));
  148.     }
  149.     private function getSalesChannelBaseUrl(): string
  150.     {
  151.         $request $this->requestStack->getMainRequest();
  152.         if (!$request) {
  153.             return '';
  154.         }
  155.         $url = (string) $request->attributes->get(RequestTransformer::SALES_CHANNEL_BASE_URL);
  156.         if (empty($url)) {
  157.             return $url;
  158.         }
  159.         return '/' trim($url'/') . '/';
  160.     }
  161.     private function getBasePath(): string
  162.     {
  163.         $request $this->requestStack->getMainRequest();
  164.         if (!$request) {
  165.             return '';
  166.         }
  167.         return $request->getBasePath();
  168.     }
  169.     private function isStorefrontRoute(string $name): bool
  170.     {
  171.         return strncmp($name'frontend.'9) === 0
  172.             || strncmp($name'widgets.'8) === 0
  173.             || strncmp($name'payment.'8) === 0;
  174.     }
  175. }