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

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