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

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