src/EventSubscriber/CheckRequirementsSubscriber.php line 76

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.     private $entityManager;
  30.     public function __construct(EntityManagerInterface $entityManager)
  31.     {
  32.         $this->entityManager $entityManager;
  33.     }
  34.     // Event Subscribers must define this method to declare the events they
  35.     // listen to. You can listen to several events, execute more than one method
  36.     // for each event and set the priority of each event too.
  37.     // See https://symfony.com/doc/current/event_dispatcher.html#creating-an-event-subscriber
  38.     public static function getSubscribedEvents(): array
  39.     {
  40.         return [
  41.             // Errors are one of the events defined by the Console. See the
  42.             // rest here: https://symfony.com/doc/current/components/console/events.html
  43.             ConsoleEvents::ERROR => 'handleConsoleError',
  44.             // See: https://symfony.com/doc/current/components/http_kernel.html#component-http-kernel-event-table
  45.             KernelEvents::EXCEPTION => 'handleKernelException',
  46.         ];
  47.     }
  48.     /**
  49.      * This method checks if there has been an error in a command related to
  50.      * the database and then, it checks if the 'sqlite3' PHP extension is enabled
  51.      * or not to display a better error message.
  52.      */
  53.     public function handleConsoleError(ConsoleErrorEvent $event): void
  54.     {
  55.         $commandNames = ['doctrine:fixtures:load''doctrine:database:create''doctrine:schema:create''doctrine:database:drop'];
  56.         if ($event->getCommand() && \in_array($event->getCommand()->getName(), $commandNamestrue)) {
  57.             if ($this->isSQLitePlatform() && !\extension_loaded('sqlite3')) {
  58.                 $io = new SymfonyStyle($event->getInput(), $event->getOutput());
  59.                 $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.');
  60.             }
  61.         }
  62.     }
  63.     /**
  64.      * This method checks if the triggered exception is related to the database
  65.      * and then, it checks if the required 'sqlite3' PHP extension is enabled.
  66.      */
  67.     public function handleKernelException(ExceptionEvent $event): void
  68.     {
  69.         $exception $event->getThrowable();
  70.         // Since any exception thrown during a Twig template rendering is wrapped
  71.         // in a Twig_Error_Runtime, we must get the original exception.
  72.         $previousException $exception->getPrevious();
  73.         // Driver exception may happen in controller or in twig template rendering
  74.         $isDriverException = ($exception instanceof DriverException || $previousException instanceof DriverException);
  75.         // Check if SQLite is enabled
  76.         if ($isDriverException && $this->isSQLitePlatform() && !\extension_loaded('sqlite3')) {
  77.             $event->setThrowable(new \Exception('PHP extension "sqlite3" must be enabled because, by default, the Symfony Demo application uses SQLite to store its information.'));
  78.         }
  79.     }
  80.     /**
  81.      * Checks if the application is using SQLite as its database.
  82.      */
  83.     private function isSQLitePlatform(): bool
  84.     {
  85.         $databasePlatform $this->entityManager->getConnection()->getDatabasePlatform();
  86.         return $databasePlatform 'sqlite' === $databasePlatform->getName() : false;
  87.     }
  88. }