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

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. class RouteScopeListener implements EventSubscriberInterface
  12. {
  13.     /**
  14.      * @var RequestStack
  15.      */
  16.     private $requestStack;
  17.     /**
  18.      * @var RouteScopeRegistry
  19.      */
  20.     private $routeScopeRegistry;
  21.     /**
  22.      * @var RouteScopeWhitelistInterface[]
  23.      */
  24.     private $whitelists;
  25.     public function __construct(
  26.         RouteScopeRegistry $routeScopeRegistry,
  27.         RequestStack $requestStack,
  28.         iterable $whitelists
  29.     ) {
  30.         $this->routeScopeRegistry $routeScopeRegistry;
  31.         $this->requestStack $requestStack;
  32.         $this->whitelists $whitelists;
  33.     }
  34.     public static function getSubscribedEvents(): array
  35.     {
  36.         return [
  37.             KernelEvents::CONTROLLER => [
  38.                 ['checkScope'KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_SCOPE_VALIDATE],
  39.             ],
  40.         ];
  41.     }
  42.     /**
  43.      * Validate that any given controller invocation creates a valid scope with the original master request
  44.      */
  45.     public function checkScope(ControllerEvent $event): void
  46.     {
  47.         if ($this->isWhitelistedController($event)) {
  48.             return;
  49.         }
  50.         $scopes $this->extractCurrentScopeAnnotation($event);
  51.         $masterRequest $this->getMainRequest();
  52.         foreach ($scopes as $routeScopeName) {
  53.             $routeScope $this->routeScopeRegistry->getRouteScope($routeScopeName);
  54.             $pathAllowed $routeScope->isAllowedPath($masterRequest->getPathInfo());
  55.             $requestAllowed $routeScope->isAllowed($masterRequest);
  56.             if ($pathAllowed && $requestAllowed) {
  57.                 return;
  58.             }
  59.         }
  60.         throw new InvalidRouteScopeException($masterRequest->attributes->get('_route'));
  61.     }
  62.     private function extractControllerClass(ControllerEvent $event): string
  63.     {
  64.         $controllerCallable \Closure::fromCallable($event->getController());
  65.         $controllerCallable = new \ReflectionFunction($controllerCallable);
  66.         return \get_class($controllerCallable->getClosureThis());
  67.     }
  68.     private function isWhitelistedController(ControllerEvent $event): bool
  69.     {
  70.         $controllerClass $this->extractControllerClass($event);
  71.         foreach ($this->whitelists as $whitelist) {
  72.             if ($whitelist->applies($controllerClass)) {
  73.                 return true;
  74.             }
  75.         }
  76.         return false;
  77.     }
  78.     private function extractCurrentScopeAnnotation(ControllerEvent $event): array
  79.     {
  80.         $currentRequest $event->getRequest();
  81.         /** @var RouteScopeAnnotation|array $scopes */
  82.         $scopes $currentRequest->get(PlatformRequest::ATTRIBUTE_ROUTE_SCOPE, []);
  83.         if ($scopes instanceof RouteScopeAnnotation) {
  84.             return $scopes->getScopes();
  85.         }
  86.         if ($scopes !== []) {
  87.             return $scopes;
  88.         }
  89.         throw new InvalidRouteScopeException($currentRequest->attributes->get('_route'));
  90.     }
  91.     private function getMainRequest(): Request
  92.     {
  93.         $masterRequest $this->requestStack->getMainRequest();
  94.         if (!$masterRequest) {
  95.             throw new \InvalidArgumentException('Unable to check the request scope without master request');
  96.         }
  97.         return $masterRequest;
  98.     }
  99. }