|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare(strict_types=1); |
|
4
|
|
|
|
|
5
|
|
|
/* |
|
6
|
|
|
* This file is part of the Explicit Architecture POC, |
|
7
|
|
|
* which is created on top of the Symfony Demo application. |
|
8
|
|
|
* |
|
9
|
|
|
* (c) Herberto Graça <[email protected]> |
|
10
|
|
|
* |
|
11
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
12
|
|
|
* file that was distributed with this source code. |
|
13
|
|
|
*/ |
|
14
|
|
|
|
|
15
|
|
|
namespace Acme\App\Presentation\Console\EventSubscriber; |
|
16
|
|
|
|
|
17
|
|
|
use Doctrine\DBAL\Exception\DriverException; |
|
18
|
|
|
use Doctrine\ORM\EntityManagerInterface; |
|
19
|
|
|
use Symfony\Component\Console\ConsoleEvents; |
|
20
|
|
|
use Symfony\Component\Console\Event\ConsoleErrorEvent; |
|
21
|
|
|
use Symfony\Component\Console\Style\SymfonyStyle; |
|
22
|
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
|
23
|
|
|
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; |
|
24
|
|
|
use Symfony\Component\HttpKernel\KernelEvents; |
|
25
|
|
|
|
|
26
|
|
|
/** |
|
27
|
|
|
* This application uses by default an SQLite database to store its information. |
|
28
|
|
|
* That's why the 'sqlite3' extension must be enabled in PHP. This event |
|
29
|
|
|
* subscriber listens to console events and in case of an exception caused by |
|
30
|
|
|
* a disabled 'sqlite3' extension, it displays a meaningful error message. |
|
31
|
|
|
* |
|
32
|
|
|
* @author Javier Eguiluz <[email protected]> |
|
33
|
|
|
*/ |
|
34
|
|
|
class CheckRequirementsSubscriber implements EventSubscriberInterface |
|
35
|
|
|
{ |
|
36
|
|
|
/** |
|
37
|
|
|
* @var EntityManagerInterface |
|
38
|
|
|
*/ |
|
39
|
|
|
private $entityManager; |
|
40
|
|
|
|
|
41
|
|
|
public function __construct(EntityManagerInterface $entityManager) |
|
42
|
|
|
{ |
|
43
|
|
|
$this->entityManager = $entityManager; |
|
44
|
|
|
} |
|
45
|
|
|
|
|
46
|
|
|
// Event Subscribers must define this method to declare the events they |
|
47
|
|
|
// listen to. You can listen to several events, execute more than one method |
|
48
|
|
|
// for each event and set the priority of each event too. |
|
49
|
|
|
// See https://symfony.com/doc/current/event_dispatcher.html#creating-an-event-subscriber |
|
50
|
|
|
public static function getSubscribedEvents(): array |
|
51
|
|
|
{ |
|
52
|
|
|
return [ |
|
53
|
|
|
// Errors are one of the events defined by the Console. See the |
|
54
|
|
|
// rest here: https://symfony.com/doc/current/components/console/events.html |
|
55
|
|
|
ConsoleEvents::ERROR => 'handleConsoleError', |
|
56
|
|
|
// See: http://api.symfony.com/master/Symfony/Component/HttpKernel/KernelEvents.html |
|
57
|
|
|
KernelEvents::EXCEPTION => 'handleKernelException', |
|
58
|
|
|
]; |
|
59
|
|
|
} |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* This method checks if there has been an error in a command related to |
|
63
|
|
|
* the database and then, it checks if the 'sqlite3' PHP extension is enabled |
|
64
|
|
|
* or not to display a better error message. |
|
65
|
|
|
* |
|
66
|
|
|
* @throws \Doctrine\DBAL\DBALException |
|
67
|
|
|
*/ |
|
68
|
|
|
public function handleConsoleError(ConsoleErrorEvent $event): void |
|
69
|
|
|
{ |
|
70
|
|
|
$commandNames = ['doctrine:fixtures:load', 'doctrine:database:create', 'doctrine:schema:create', 'doctrine:database:drop']; |
|
71
|
|
|
|
|
72
|
|
|
if ($event->getCommand() && \in_array($event->getCommand()->getName(), $commandNames, true)) { |
|
73
|
|
|
if ($this->isSQLitePlatform() && !\extension_loaded('sqlite3')) { |
|
74
|
|
|
$io = new SymfonyStyle($event->getInput(), $event->getOutput()); |
|
75
|
|
|
$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.'); |
|
76
|
|
|
} |
|
77
|
|
|
} |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
/** |
|
81
|
|
|
* This method checks if the triggered exception is related to the database |
|
82
|
|
|
* and then, it checks if the required 'sqlite3' PHP extension is enabled. |
|
83
|
|
|
* |
|
84
|
|
|
* @throws \Doctrine\DBAL\DBALException |
|
85
|
|
|
*/ |
|
86
|
|
|
public function handleKernelException(GetResponseForExceptionEvent $event): void |
|
87
|
|
|
{ |
|
88
|
|
|
$exception = $event->getException(); |
|
|
|
|
|
|
89
|
|
|
// Since any exception thrown during a Twig template rendering is wrapped |
|
90
|
|
|
// in a Twig_Error_Runtime, we must get the original exception. |
|
91
|
|
|
$previousException = $exception->getPrevious(); |
|
92
|
|
|
|
|
93
|
|
|
// Driver exception may happen in controller or in twig template rendering |
|
94
|
|
|
$isDriverException = ($exception instanceof DriverException || $previousException instanceof DriverException); |
|
95
|
|
|
|
|
96
|
|
|
// Check if SQLite is enabled |
|
97
|
|
|
if ($isDriverException && $this->isSQLitePlatform() && !extension_loaded('sqlite3')) { |
|
98
|
|
|
$event->setException(new \Exception('PHP extension "sqlite3" must be enabled because, by default, the Symfony Demo application uses SQLite to store its information.')); |
|
|
|
|
|
|
99
|
|
|
} |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
/** |
|
103
|
|
|
* Checks if the application is using SQLite as its database. |
|
104
|
|
|
* |
|
105
|
|
|
* @throws \Doctrine\DBAL\DBALException |
|
106
|
|
|
*/ |
|
107
|
|
|
private function isSQLitePlatform(): bool |
|
108
|
|
|
{ |
|
109
|
|
|
$databasePlatform = $this->entityManager->getConnection()->getDatabasePlatform(); |
|
110
|
|
|
|
|
111
|
|
|
return $databasePlatform ? $databasePlatform->getName() === 'sqlite' : false; |
|
112
|
|
|
} |
|
113
|
|
|
} |
|
114
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.