src/InstallBundle/Listener/RequestListener.php line 93

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of SolidInvoice project.
  5.  *
  6.  * (c) Pierre du Plessis <open-source@solidworx.co>
  7.  *
  8.  * This source file is subject to the MIT license that is bundled
  9.  * with this source code in the file LICENSE.
  10.  */
  11. namespace SolidInvoice\InstallBundle\Listener;
  12. use SolidInvoice\InstallBundle\Exception\ApplicationInstalledException;
  13. use SolidInvoice\UserBundle\Repository\UserRepositoryInterface;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpFoundation\RedirectResponse;
  16. use Symfony\Component\HttpKernel\Event\RequestEvent;
  17. use Symfony\Component\HttpKernel\HttpKernelInterface;
  18. use Symfony\Component\HttpKernel\KernelEvents;
  19. use Symfony\Component\Routing\RouterInterface;
  20. use function in_array;
  21. /**
  22.  * Listener class to intercept requests
  23.  * and redirect to the installer if necessary.
  24.  * @see \SolidInvoice\InstallBundle\Tests\Listener\RequestListenerTest
  25.  */
  26. final class RequestListener implements EventSubscriberInterface
  27. {
  28.     public const INSTALLER_ROUTE '_install_check_requirements';
  29.     /**
  30.      * Core routes.
  31.      *
  32.      * @var list<string>
  33.      */
  34.     private array $allowRoutes self::INSTALL_ROUTES;
  35.     /**
  36.      * @var list<string>
  37.      */
  38.     private const INSTALL_ROUTES = [
  39.         self::INSTALLER_ROUTE,
  40.         '_install_config',
  41.         '_install_install',
  42.         ...self::SETUP_ROUTES
  43.     ];
  44.     /**
  45.      * @var list<string>
  46.      */
  47.     private const SETUP_ROUTES = [
  48.         '_install_setup',
  49.         '_install_finish',
  50.     ];
  51.     /**
  52.      * @var list<string>
  53.      */
  54.     private const DEBUG_ROUTES = [
  55.         '_wdt',
  56.         '_profiler',
  57.         '_profiler_search',
  58.         '_profiler_search_bar',
  59.         '_profiler_search_results',
  60.         '_profiler_router',
  61.     ];
  62.     public static function getSubscribedEvents(): array
  63.     {
  64.         return [
  65.             KernelEvents::REQUEST => ['onKernelRequest'10],
  66.         ];
  67.     }
  68.     public function __construct(
  69.         private readonly RouterInterface $router,
  70.         private readonly UserRepositoryInterface $userRepository,
  71.         private readonly ?string $installed,
  72.         private readonly bool $debug false
  73.     ) {
  74.         if ($this->debug) {
  75.             $this->allowRoutes array_merge($this->allowRoutesself::DEBUG_ROUTES);
  76.         }
  77.     }
  78.     /**
  79.      * @throws ApplicationInstalledException
  80.      */
  81.     public function onKernelRequest(RequestEvent $event): void
  82.     {
  83.         if (HttpKernelInterface::MAIN_REQUEST !== $event->getRequestType()) {
  84.             return;
  85.         }
  86.         $request $event->getRequest();
  87.         $session $request->getSession();
  88.         $route $request->get('_route');
  89.         if (null !== $this->installed && '' !== $this->installed) {
  90.             // If the application is installed, but we don't have any users
  91.             // Redirect to the setup page
  92.             if ($this->userRepository->getUserCount() === 0) {
  93.                 if (! in_array($route, [...self::SETUP_ROUTES, ...($this->debug self::DEBUG_ROUTES : [])], true)) {
  94.                     $this->redirectToRoute($event'_install_setup');
  95.                 }
  96.                 return;
  97.             }
  98.             // If the application is installed, and we already have users, and the installer route is requested
  99.             // then throw an exception
  100.             if (in_array($routeself::INSTALL_ROUTEStrue) && ! $session->has('installation_step')) {
  101.                 throw new ApplicationInstalledException();
  102.             }
  103.         } elseif (! in_array($route$this->allowRoutestrue)) {
  104.             $this->redirectToRoute($eventself::INSTALLER_ROUTE);
  105.         }
  106.     }
  107.     private function redirectToRoute(RequestEvent $eventstring $route): void
  108.     {
  109.         $response = new RedirectResponse($this->router->generate($route));
  110.         $event->setResponse($response);
  111.         $event->stopPropagation();
  112.     }
  113. }