platform/src/Storefront/Framework/Routing/Router.php line 61

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