src/EventSubscriber/CheckRequirementsSubscriber.php line 74

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace App\EventSubscriber;
  11. use Doctrine\DBAL\Exception\DriverException;
  12. use Doctrine\ORM\EntityManagerInterface;
  13. use Symfony\Component\Console\ConsoleEvents;
  14. use Symfony\Component\Console\Event\ConsoleErrorEvent;
  15. use Symfony\Component\Console\Style\SymfonyStyle;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  18. use Symfony\Component\HttpKernel\KernelEvents;
  19. /**
  20.  * This application uses by default an SQLite database to store its information.
  21.  * That's why the 'sqlite3' extension must be enabled in PHP. This event
  22.  * subscriber listens to console events and in case of an exception caused by
  23.  * a disabled 'sqlite3' extension, it displays a meaningful error message.
  24.  *
  25.  * @author Javier Eguiluz <javier.eguiluz@gmail.com>
  26.  */
  27. class CheckRequirementsSubscriber implements EventSubscriberInterface
  28. {
  29.     public function __construct(
  30.         private EntityManagerInterface $entityManager
  31.     ) {
  32.     }
  33.     // Event Subscribers must define this method to declare the events they
  34.     // listen to. You can listen to several events, execute more than one method
  35.     // for each event and set the priority of each event too.
  36.     // See https://symfony.com/doc/current/event_dispatcher.html#creating-an-event-subscriber
  37.     public static function getSubscribedEvents(): array
  38.     {
  39.         return [
  40.             // Errors are one of the events defined by the Console. See the
  41.             // rest here: https://symfony.com/doc/current/components/console/events.html
  42.             ConsoleEvents::ERROR => 'handleConsoleError',
  43.             // See: https://symfony.com/doc/current/components/http_kernel.html#component-http-kernel-event-table
  44.             KernelEvents::EXCEPTION => 'handleKernelException',
  45.         ];
  46.     }
  47.     /**
  48.      * This method checks if there has been an error in a command related to
  49.      * the database and then, it checks if the 'sqlite3' PHP extension is enabled
  50.      * or not to display a better error message.
  51.      */
  52.     public function handleConsoleError(ConsoleErrorEvent $event): void
  53.     {
  54.         $commandNames = ['doctrine:fixtures:load''doctrine:database:create''doctrine:schema:create''doctrine:database:drop'];
  55.         if ($event->getCommand() && \in_array($event->getCommand()->getName(), $commandNamestrue)) {
  56.             if ($this->isSQLitePlatform() && !\extension_loaded('sqlite3')) {
  57.                 $io = new SymfonyStyle($event->getInput(), $event->getOutput());
  58.                 $io->error('This command requires to have the "sqlite3" PHP extension enabled because, by default, the Symfony Demo application uses SQLite to store its information.');
  59.             }
  60.         }
  61.     }
  62.     /**
  63.      * This method checks if the triggered exception is related to the database
  64.      * and then, it checks if the required 'sqlite3' PHP extension is enabled.
  65.      */
  66.     public function handleKernelException(ExceptionEvent $event): void
  67.     {
  68.         $exception $event->getThrowable();
  69.         // Since any exception thrown during a Twig template rendering is wrapped
  70.         // in a Twig_Error_Runtime, we must get the original exception.
  71.         $previousException $exception->getPrevious();
  72.         // Driver exception may happen in controller or in twig template rendering
  73.         $isDriverException = ($exception instanceof DriverException || $previousException instanceof DriverException);
  74.         // Check if SQLite is enabled
  75.         if ($isDriverException && $this->isSQLitePlatform() && !\extension_loaded('sqlite3')) {
  76.             $event->setThrowable(new \Exception('PHP extension "sqlite3" must be enabled because, by default, the Symfony Demo application uses SQLite to store its information.'));
  77.         }
  78.     }
  79.     /**
  80.      * Checks if the application is using SQLite as its database.
  81.      */
  82.     private function isSQLitePlatform(): bool
  83.     {
  84.         $databasePlatform $this->entityManager->getConnection()->getDatabasePlatform();
  85.         return $databasePlatform 'sqlite' === $databasePlatform->getName() : false;
  86.     }
  87. }