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

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