From 12e1f557097bae7db85707cf86d843fff744633d Mon Sep 17 00:00:00 2001 From: uikolas Date: Wed, 11 Jan 2017 22:12:26 +0200 Subject: [PATCH 1/8] Implemented to catch exception, when SQLite is not enabled and show better error message --- app/config/services.yml | 8 +++++ .../EventListener/SQLiteExceptionListener.php | 35 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/AppBundle/EventListener/SQLiteExceptionListener.php diff --git a/app/config/services.yml b/app/config/services.yml index bfe5ee2f7..d5628e93f 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -31,6 +31,14 @@ services: tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } + # There is an optional tag attribute called method which defines which method + # to execute when the event is triggered. By default the name of the method is on + "camel-cased event name". + # If the event is kernel.exception the method executed by default is onKernelException(). + app.driver_exception_listener: + class: AppBundle\EventListener\SQLiteExceptionListener + tags: + - { name: kernel.event_listener, event: kernel.exception } + # Event subscribers are similar to event listeners but they don't need to add # a separate tag for each listened event. Instead, the PHP class of the event # subscriber includes a method that returns the list of listened events. diff --git a/src/AppBundle/EventListener/SQLiteExceptionListener.php b/src/AppBundle/EventListener/SQLiteExceptionListener.php new file mode 100644 index 000000000..a64093002 --- /dev/null +++ b/src/AppBundle/EventListener/SQLiteExceptionListener.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace AppBundle\EventListener; + +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; + +/** + * Kernel exception events allows to handle specific exceptions, or show custom response. + * + * See https://symfony.com/doc/current/controller/error_pages.html#use-kernel-exception-event + * + * On this kernel exception event, check if SQLite extension is enabled. + * If not, show better error message. Instead of "could not find driver" + */ +class SQLiteExceptionListener +{ + /** + * @param GetResponseForExceptionEvent $event + */ + public function onKernelException(GetResponseForExceptionEvent $event) + { + if (!extension_loaded('sqlite3')) { + $event->setException(new \Exception('PHP extension "sqlite3" must be enabled because, by default, the Symfony Demo application uses SQLite to store its information.')); + } + } +} \ No newline at end of file From d5a8829f5a05fde68d0385391f77ea8626299600 Mon Sep 17 00:00:00 2001 From: uikolas Date: Thu, 12 Jan 2017 19:31:21 +0200 Subject: [PATCH 2/8] Edited to catch sqlite exception in one event subscriber --- app/config/services.yml | 10 +----- ...ber.php => CheckSQLiteEventSubscriber.php} | 18 +++++++++- .../EventListener/SQLiteExceptionListener.php | 35 ------------------- 3 files changed, 18 insertions(+), 45 deletions(-) rename src/AppBundle/EventListener/{ConsoleEventSubscriber.php => CheckSQLiteEventSubscriber.php} (74%) delete mode 100644 src/AppBundle/EventListener/SQLiteExceptionListener.php diff --git a/app/config/services.yml b/app/config/services.yml index d5628e93f..95e23ab55 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -31,20 +31,12 @@ services: tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } - # There is an optional tag attribute called method which defines which method - # to execute when the event is triggered. By default the name of the method is on + "camel-cased event name". - # If the event is kernel.exception the method executed by default is onKernelException(). - app.driver_exception_listener: - class: AppBundle\EventListener\SQLiteExceptionListener - tags: - - { name: kernel.event_listener, event: kernel.exception } - # Event subscribers are similar to event listeners but they don't need to add # a separate tag for each listened event. Instead, the PHP class of the event # subscriber includes a method that returns the list of listened events. # See http://symfony.com/doc/current/event_dispatcher.html#creating-an-event-subscriber app.console_subscriber: - class: AppBundle\EventListener\ConsoleEventSubscriber + class: AppBundle\EventListener\CheckSQLiteEventSubscriber tags: - { name: kernel.event_subscriber } diff --git a/src/AppBundle/EventListener/ConsoleEventSubscriber.php b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php similarity index 74% rename from src/AppBundle/EventListener/ConsoleEventSubscriber.php rename to src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php index c8f7503cc..5d02872ac 100644 --- a/src/AppBundle/EventListener/ConsoleEventSubscriber.php +++ b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php @@ -15,6 +15,8 @@ use Symfony\Component\Console\Event\ConsoleExceptionEvent; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; +use Symfony\Component\HttpKernel\KernelEvents; /** * This application uses by default an SQLite database to store its information. @@ -24,7 +26,7 @@ * * @author Javier Eguiluz */ -class ConsoleEventSubscriber implements EventSubscriberInterface +class CheckSQLiteEventSubscriber implements EventSubscriberInterface { // Event Subscribers must define this method to declare the events they // listen to. You can listen to several events, execute more than one method @@ -36,6 +38,8 @@ public static function getSubscribedEvents() // Exceptions are one of the events defined by the Console. See the // rest here: http://symfony.com/doc/current/components/console/events.html ConsoleEvents::EXCEPTION => 'handleDatabaseExceptions', + // See: http://api.symfony.com/3.2/Symfony/Component/HttpKernel/KernelEvents.html + KernelEvents::EXCEPTION => 'onKernelException' ]; } @@ -57,4 +61,16 @@ public function handleDatabaseExceptions(ConsoleExceptionEvent $event) } } } + + /** + * This method is triggered when kernel exception occurs. And checks if sqlite extension is enabled. + * + * @param GetResponseForExceptionEvent $event + */ + public function onKernelException(GetResponseForExceptionEvent $event) + { + if (!extension_loaded('sqlite3')) { + $event->setException(new \Exception('PHP extension "sqlite3" must be enabled because, by default, the Symfony Demo application uses SQLite to store its information.')); + } + } } diff --git a/src/AppBundle/EventListener/SQLiteExceptionListener.php b/src/AppBundle/EventListener/SQLiteExceptionListener.php deleted file mode 100644 index a64093002..000000000 --- a/src/AppBundle/EventListener/SQLiteExceptionListener.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace AppBundle\EventListener; - -use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; - -/** - * Kernel exception events allows to handle specific exceptions, or show custom response. - * - * See https://symfony.com/doc/current/controller/error_pages.html#use-kernel-exception-event - * - * On this kernel exception event, check if SQLite extension is enabled. - * If not, show better error message. Instead of "could not find driver" - */ -class SQLiteExceptionListener -{ - /** - * @param GetResponseForExceptionEvent $event - */ - public function onKernelException(GetResponseForExceptionEvent $event) - { - if (!extension_loaded('sqlite3')) { - $event->setException(new \Exception('PHP extension "sqlite3" must be enabled because, by default, the Symfony Demo application uses SQLite to store its information.')); - } - } -} \ No newline at end of file From cda028cd5465ae0c3f0658619824063e962942ed Mon Sep 17 00:00:00 2001 From: uikolas Date: Thu, 12 Jan 2017 19:35:50 +0200 Subject: [PATCH 3/8] Small Code standard fix --- src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php index 5d02872ac..f937ef795 100644 --- a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php +++ b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php @@ -39,7 +39,7 @@ public static function getSubscribedEvents() // rest here: http://symfony.com/doc/current/components/console/events.html ConsoleEvents::EXCEPTION => 'handleDatabaseExceptions', // See: http://api.symfony.com/3.2/Symfony/Component/HttpKernel/KernelEvents.html - KernelEvents::EXCEPTION => 'onKernelException' + KernelEvents::EXCEPTION => 'onKernelException', ]; } From e284efffe951e4e26e9419b762225575f804f19f Mon Sep 17 00:00:00 2001 From: uikolas Date: Thu, 12 Jan 2017 20:33:53 +0200 Subject: [PATCH 4/8] Added to check if driver exception occurred --- .../EventListener/CheckSQLiteEventSubscriber.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php index f937ef795..5d0985dd9 100644 --- a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php +++ b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php @@ -11,6 +11,7 @@ namespace AppBundle\EventListener; +use Doctrine\DBAL\Exception\DriverException; use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleExceptionEvent; use Symfony\Component\Console\Style\SymfonyStyle; @@ -69,7 +70,12 @@ public function handleDatabaseExceptions(ConsoleExceptionEvent $event) */ public function onKernelException(GetResponseForExceptionEvent $event) { - if (!extension_loaded('sqlite3')) { + $exception = $event->getException(); + // Since any exception thrown during a Twig template rendering is wrapped in a Twig_Error_Runtime. + // We must get the original exception. + $previousException = $exception->getPrevious(); + + if ($previousException instanceof DriverException && !extension_loaded('sqlite3')) { $event->setException(new \Exception('PHP extension "sqlite3" must be enabled because, by default, the Symfony Demo application uses SQLite to store its information.')); } } From b19f5d4b8e3a92cc31bb6a22bea40d063085273f Mon Sep 17 00:00:00 2001 From: uikolas Date: Thu, 12 Jan 2017 20:46:55 +0200 Subject: [PATCH 5/8] Added to check main exception --- src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php index 5d0985dd9..af9d3efbb 100644 --- a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php +++ b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php @@ -75,7 +75,10 @@ public function onKernelException(GetResponseForExceptionEvent $event) // We must get the original exception. $previousException = $exception->getPrevious(); - if ($previousException instanceof DriverException && !extension_loaded('sqlite3')) { + // Driver exception may happen in controller or in twig template rendering + $isDriverException = ($exception instanceof DriverException || $previousException instanceof DriverException); + + if ($isDriverException && !extension_loaded('sqlite3')) { $event->setException(new \Exception('PHP extension "sqlite3" must be enabled because, by default, the Symfony Demo application uses SQLite to store its information.')); } } From b1ebee4ef5cec1c38e7ed28da449318869f6c808 Mon Sep 17 00:00:00 2001 From: uikolas Date: Mon, 16 Jan 2017 20:30:11 +0200 Subject: [PATCH 6/8] Added to check if SQLite is used as database --- app/config/services.yml | 1 + .../CheckSQLiteEventSubscriber.php | 31 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/app/config/services.yml b/app/config/services.yml index 95e23ab55..88cd5feea 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -37,6 +37,7 @@ services: # See http://symfony.com/doc/current/event_dispatcher.html#creating-an-event-subscriber app.console_subscriber: class: AppBundle\EventListener\CheckSQLiteEventSubscriber + arguments: ['@doctrine.orm.entity_manager'] tags: - { name: kernel.event_subscriber } diff --git a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php index af9d3efbb..7540cddf0 100644 --- a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php +++ b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php @@ -12,6 +12,7 @@ namespace AppBundle\EventListener; use Doctrine\DBAL\Exception\DriverException; +use Doctrine\ORM\EntityManager; use Symfony\Component\Console\ConsoleEvents; use Symfony\Component\Console\Event\ConsoleExceptionEvent; use Symfony\Component\Console\Style\SymfonyStyle; @@ -29,6 +30,21 @@ */ class CheckSQLiteEventSubscriber implements EventSubscriberInterface { + /** + * @var EntityManager + */ + private $entityManager; + + /** + * CheckSQLiteEventSubscriber constructor. + * + * @param EntityManager $entityManager + */ + public function __construct(EntityManager $entityManager) + { + $this->entityManager = $entityManager; + } + // Event Subscribers must define this method to declare the events they // listen to. You can listen to several events, execute more than one method // for each event and set the priority of each event too. @@ -56,7 +72,7 @@ public function handleDatabaseExceptions(ConsoleExceptionEvent $event) $commandNames = ['doctrine:fixtures:load', 'doctrine:database:create', 'doctrine:schema:create', 'doctrine:database:drop']; if (in_array($event->getCommand()->getName(), $commandNames)) { - if (!extension_loaded('sqlite3')) { + if ($this->isSQLitePlatform() && !extension_loaded('sqlite3')) { $io = new SymfonyStyle($event->getInput(), $event->getOutput()); $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.'); } @@ -78,8 +94,19 @@ public function onKernelException(GetResponseForExceptionEvent $event) // Driver exception may happen in controller or in twig template rendering $isDriverException = ($exception instanceof DriverException || $previousException instanceof DriverException); - if ($isDriverException && !extension_loaded('sqlite3')) { + // Check if SQLite is enabled + if ($isDriverException && $this->isSQLitePlatform() && !extension_loaded('sqlite3')) { $event->setException(new \Exception('PHP extension "sqlite3" must be enabled because, by default, the Symfony Demo application uses SQLite to store its information.')); } } + + /** + * Check if demo application is configured to use SQLite as database. + * + * @return bool + */ + private function isSQLitePlatform() + { + return $this->entityManager->getConnection()->getDatabasePlatform()->getName() === 'sqlite'; + } } From 3d20d31f0a11f61e1d369ba7f43dbd36791f78df Mon Sep 17 00:00:00 2001 From: uikolas Date: Mon, 16 Jan 2017 21:08:21 +0200 Subject: [PATCH 7/8] Check if database platform exists --- src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php index 7540cddf0..003e62812 100644 --- a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php +++ b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php @@ -107,6 +107,6 @@ public function onKernelException(GetResponseForExceptionEvent $event) */ private function isSQLitePlatform() { - return $this->entityManager->getConnection()->getDatabasePlatform()->getName() === 'sqlite'; + return $this->entityManager->getConnection()->getDatabasePlatform() ? $this->entityManager->getConnection()->getDatabasePlatform()->getName() === 'sqlite' : false; } } From d90a80ca3da2c0fb3c4c0a0b34369ee344737245 Mon Sep 17 00:00:00 2001 From: uikolas Date: Tue, 17 Jan 2017 19:54:57 +0200 Subject: [PATCH 8/8] code clean --- src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php index 003e62812..6f2a9114e 100644 --- a/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php +++ b/src/AppBundle/EventListener/CheckSQLiteEventSubscriber.php @@ -107,6 +107,8 @@ public function onKernelException(GetResponseForExceptionEvent $event) */ private function isSQLitePlatform() { - return $this->entityManager->getConnection()->getDatabasePlatform() ? $this->entityManager->getConnection()->getDatabasePlatform()->getName() === 'sqlite' : false; + $databasePlatform = $this->entityManager->getConnection()->getDatabasePlatform(); + + return $databasePlatform ? $databasePlatform->getName() === 'sqlite' : false; } }