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.         $currentRouteScopeAnnotation $this->extractCurrentScopeAnnotation($event);
  51.         $masterRequest $this->getMasterRequest();
  52.         foreach ($currentRouteScopeAnnotation->getScopes() 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.         $controllerClass = \get_class($controllerCallable->getClosureThis());
  67.         return $controllerClass;
  68.     }
  69.     private function isWhitelistedController(ControllerEvent $event): bool
  70.     {
  71.         $controllerClass $this->extractControllerClass($event);
  72.         foreach ($this->whitelists as $whitelist) {
  73.             $isWhitelisted $whitelist->applies($controllerClass);
  74.             if ($isWhitelisted) {
  75.                 return true;
  76.             }
  77.         }
  78.         return false;
  79.     }
  80.     private function extractCurrentScopeAnnotation(ControllerEvent $event): RouteScopeAnnotation
  81.     {
  82.         $currentRequest $event->getRequest();
  83.         $currentRouteScopeAnnotation $currentRequest->get(PlatformRequest::ATTRIBUTE_ROUTE_SCOPE);
  84.         if ($currentRouteScopeAnnotation === null) {
  85.             throw new InvalidRouteScopeException($currentRequest->attributes->get('_route'));
  86.         }
  87.         return $currentRouteScopeAnnotation;
  88.     }
  89.     private function getMasterRequest(): Request
  90.     {
  91.         $masterRequest $this->requestStack->getMasterRequest();
  92.         if (!$masterRequest) {
  93.             throw new \InvalidArgumentException('Unable to check the request scope without master request');
  94.         }
  95.         return $masterRequest;
  96.     }
  97. }