vendor/shopware/core/Framework/Routing/RouteScopeListener.php line 57

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Routing;
  3. use Shopware\Core\Framework\Log\Package;
  4. use Shopware\Core\Framework\Routing\Annotation\RouteScope as RouteScopeAnnotation;
  5. use Shopware\Core\Framework\Routing\Exception\InvalidRouteScopeException;
  6. use Shopware\Core\PlatformRequest;
  7. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpFoundation\RequestStack;
  10. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  11. use Symfony\Component\HttpKernel\KernelEvents;
  12. /**
  13.  * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0
  14.  */
  15. #[Package('core')]
  16. class RouteScopeListener implements EventSubscriberInterface
  17. {
  18.     private RequestStack $requestStack;
  19.     private RouteScopeRegistry $routeScopeRegistry;
  20.     /**
  21.      * @var RouteScopeWhitelistInterface[]
  22.      */
  23.     private array $whitelists;
  24.     /**
  25.      * @internal
  26.      *
  27.      * @param iterable<RouteScopeWhitelistInterface> $whitelists
  28.      */
  29.     public function __construct(
  30.         RouteScopeRegistry $routeScopeRegistry,
  31.         RequestStack $requestStack,
  32.         iterable $whitelists
  33.     ) {
  34.         $this->routeScopeRegistry $routeScopeRegistry;
  35.         $this->requestStack $requestStack;
  36.         $this->whitelists = \is_array($whitelists) ? $whitelists iterator_to_array($whitelists);
  37.     }
  38.     public static function getSubscribedEvents(): array
  39.     {
  40.         return [
  41.             KernelEvents::CONTROLLER => [
  42.                 ['checkScope'KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_SCOPE_VALIDATE],
  43.             ],
  44.         ];
  45.     }
  46.     /**
  47.      * Validate that any given controller invocation creates a valid scope with the original master request
  48.      */
  49.     public function checkScope(ControllerEvent $event): void
  50.     {
  51.         if ($this->isWhitelistedController($event)) {
  52.             return;
  53.         }
  54.         $scopes $this->extractCurrentScopeAnnotation($event);
  55.         $masterRequest $this->getMainRequest();
  56.         foreach ($scopes as $routeScopeName) {
  57.             $routeScope $this->routeScopeRegistry->getRouteScope($routeScopeName);
  58.             $pathAllowed $routeScope->isAllowedPath($masterRequest->getPathInfo());
  59.             $requestAllowed $routeScope->isAllowed($masterRequest);
  60.             if ($pathAllowed && $requestAllowed) {
  61.                 return;
  62.             }
  63.         }
  64.         throw new InvalidRouteScopeException($masterRequest->attributes->get('_route'));
  65.     }
  66.     private function extractControllerClass(ControllerEvent $event): ?string
  67.     {
  68.         $controllerCallable = \Closure::fromCallable($event->getController());
  69.         $controllerCallable = new \ReflectionFunction($controllerCallable);
  70.         $controller $controllerCallable->getClosureThis();
  71.         if (!$controller) {
  72.             return null;
  73.         }
  74.         return \get_class($controller);
  75.     }
  76.     private function isWhitelistedController(ControllerEvent $event): bool
  77.     {
  78.         $controllerClass $this->extractControllerClass($event);
  79.         if (!$controllerClass) {
  80.             return false;
  81.         }
  82.         foreach ($this->whitelists as $whitelist) {
  83.             if ($whitelist->applies($controllerClass)) {
  84.                 return true;
  85.             }
  86.         }
  87.         return false;
  88.     }
  89.     /**
  90.      * @return list<string>
  91.      */
  92.     private function extractCurrentScopeAnnotation(ControllerEvent $event): array
  93.     {
  94.         $currentRequest $event->getRequest();
  95.         /** @var RouteScopeAnnotation|list<string> $scopes */
  96.         $scopes $currentRequest->get(PlatformRequest::ATTRIBUTE_ROUTE_SCOPE, []);
  97.         if ($scopes instanceof RouteScopeAnnotation) {
  98.             return $scopes->getScopes();
  99.         }
  100.         if ($scopes !== []) {
  101.             return $scopes;
  102.         }
  103.         throw new InvalidRouteScopeException($currentRequest->attributes->get('_route'));
  104.     }
  105.     private function getMainRequest(): Request
  106.     {
  107.         $masterRequest $this->requestStack->getMainRequest();
  108.         if (!$masterRequest) {
  109.             throw new \InvalidArgumentException('Unable to check the request scope without master request');
  110.         }
  111.         return $masterRequest;
  112.     }
  113. }