src/EventSubscriber/ModuleAccessSubscriber.php line 35

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Module\Attribute\RequiresModule;
  4. use App\Service\ModuleAccessService;
  5. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  6. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  7. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  8. /**
  9.  * Egzekwuje wyłączanie modułów po stronie serwera.
  10.  */
  11. final readonly class ModuleAccessSubscriber implements EventSubscriberInterface
  12. {
  13.     /**
  14.      * EasyAdmin podmienia wykonywany kontroler w AdminRouterSubscriber::onKernelController
  15.      * z priorytetem 128, przy wyższym priorytecie moduły nie działałyby
  16.      * dla żadnego okna EasyAdmina.
  17.      */
  18.     public const PRIORITY = 0;
  19.     public function __construct(private ModuleAccessService $moduleAccess)
  20.     {
  21.     }
  22.     /**
  23.      * @return array<string, array{0: string, 1: int}>
  24.      */
  25.     public static function getSubscribedEvents(): array
  26.     {
  27.         return [ControllerEvent::class => ['onKernelController', self::PRIORITY]];
  28.     }
  29.     public function onKernelController(ControllerEvent $event): void
  30.     {
  31.         $module = $this->resolveModule($event->getController());
  32.         if ($module !== null && !$this->moduleAccess->isEnabled($module)) {
  33.             throw new NotFoundHttpException(\sprintf('Moduł "%s" jest wyłączony na tej instalacji.', $module));
  34.         }
  35.     }
  36.     /**
  37.      * Atrybut z metody ma pierwszeństwo przed atrybutem z klasy.
  38.      */
  39.     private function resolveModule(mixed $controller): ?string
  40.     {
  41.         if (\is_array($controller)) {
  42.             [$object, $method] = $controller;
  43.         } elseif (\is_object($controller) && \method_exists($controller, '__invoke')) {
  44.             $object = $controller;
  45.             $method = '__invoke';
  46.         } else {
  47.             return null;
  48.         }
  49.         if (!\is_object($object)) {
  50.             return null;
  51.         }
  52.         $reflection = new \ReflectionObject($object);
  53.         if ($reflection->hasMethod($method)) {
  54.             $attributes = $reflection->getMethod($method)->getAttributes(RequiresModule::class);
  55.             if ($attributes !== []) {
  56.                 return $attributes[0]->newInstance()->module;
  57.             }
  58.         }
  59.         $attributes = $reflection->getAttributes(RequiresModule::class);
  60.         return $attributes === [] ? null : $attributes[0]->newInstance()->module;
  61.     }
  62. }