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

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