diff options
author | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
---|---|---|
committer | polo <ordipolo@gmx.fr> | 2024-08-13 23:45:21 +0200 |
commit | bf6655a534a6775d30cafa67bd801276bda1d98d (patch) | |
tree | c6381e3f6c81c33eab72508f410b165ba05f7e9c /vendor/doctrine/orm/src/Tools/Console | |
parent | 94d67a4b51f8e62e7d518cce26a526ae1ec48278 (diff) | |
download | AppliGestionPHP-bf6655a534a6775d30cafa67bd801276bda1d98d.zip |
VERSION 0.2 doctrine ORM et entités
Diffstat (limited to 'vendor/doctrine/orm/src/Tools/Console')
22 files changed, 1839 insertions, 0 deletions
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/AbstractEntityManagerCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/AbstractEntityManagerCommand.php new file mode 100644 index 0000000..370f4fb --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/AbstractEntityManagerCommand.php | |||
@@ -0,0 +1,25 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command; | ||
6 | |||
7 | use Doctrine\ORM\EntityManagerInterface; | ||
8 | use Doctrine\ORM\Tools\Console\EntityManagerProvider; | ||
9 | use Symfony\Component\Console\Command\Command; | ||
10 | use Symfony\Component\Console\Input\InputInterface; | ||
11 | |||
12 | abstract class AbstractEntityManagerCommand extends Command | ||
13 | { | ||
14 | public function __construct(private readonly EntityManagerProvider $entityManagerProvider) | ||
15 | { | ||
16 | parent::__construct(); | ||
17 | } | ||
18 | |||
19 | final protected function getEntityManager(InputInterface $input): EntityManagerInterface | ||
20 | { | ||
21 | return $input->getOption('em') === null | ||
22 | ? $this->entityManagerProvider->getDefaultManager() | ||
23 | : $this->entityManagerProvider->getManager($input->getOption('em')); | ||
24 | } | ||
25 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/CollectionRegionCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/CollectionRegionCommand.php new file mode 100644 index 0000000..b4c6efa --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/CollectionRegionCommand.php | |||
@@ -0,0 +1,119 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\ClearCache; | ||
6 | |||
7 | use Doctrine\ORM\Cache; | ||
8 | use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; | ||
9 | use InvalidArgumentException; | ||
10 | use Symfony\Component\Console\Input\InputArgument; | ||
11 | use Symfony\Component\Console\Input\InputInterface; | ||
12 | use Symfony\Component\Console\Input\InputOption; | ||
13 | use Symfony\Component\Console\Output\OutputInterface; | ||
14 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
15 | |||
16 | use function sprintf; | ||
17 | |||
18 | /** | ||
19 | * Command to clear a collection cache region. | ||
20 | */ | ||
21 | class CollectionRegionCommand extends AbstractEntityManagerCommand | ||
22 | { | ||
23 | protected function configure(): void | ||
24 | { | ||
25 | $this->setName('orm:clear-cache:region:collection') | ||
26 | ->setDescription('Clear a second-level cache collection region') | ||
27 | ->addArgument('owner-class', InputArgument::OPTIONAL, 'The owner entity name.') | ||
28 | ->addArgument('association', InputArgument::OPTIONAL, 'The association collection name.') | ||
29 | ->addArgument('owner-id', InputArgument::OPTIONAL, 'The owner identifier.') | ||
30 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
31 | ->addOption('all', null, InputOption::VALUE_NONE, 'If defined, all entity regions will be deleted/invalidated.') | ||
32 | ->addOption('flush', null, InputOption::VALUE_NONE, 'If defined, all cache entries will be flushed.') | ||
33 | ->setHelp(<<<'EOT' | ||
34 | The <info>%command.name%</info> command is meant to clear a second-level cache collection regions for an associated Entity Manager. | ||
35 | It is possible to delete/invalidate all collection region, a specific collection region or flushes the cache provider. | ||
36 | |||
37 | The execution type differ on how you execute the command. | ||
38 | If you want to invalidate all entries for an collection region this command would do the work: | ||
39 | |||
40 | <info>%command.name% 'Entities\MyEntity' 'collectionName'</info> | ||
41 | |||
42 | To invalidate a specific entry you should use : | ||
43 | |||
44 | <info>%command.name% 'Entities\MyEntity' 'collectionName' 1</info> | ||
45 | |||
46 | If you want to invalidate all entries for the all collection regions: | ||
47 | |||
48 | <info>%command.name% --all</info> | ||
49 | |||
50 | Alternatively, if you want to flush the configured cache provider for an collection region use this command: | ||
51 | |||
52 | <info>%command.name% 'Entities\MyEntity' 'collectionName' --flush</info> | ||
53 | |||
54 | Finally, be aware that if <info>--flush</info> option is passed, | ||
55 | not all cache providers are able to flush entries, because of a limitation of its execution nature. | ||
56 | EOT); | ||
57 | } | ||
58 | |||
59 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
60 | { | ||
61 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
62 | |||
63 | $em = $this->getEntityManager($input); | ||
64 | $ownerClass = $input->getArgument('owner-class'); | ||
65 | $assoc = $input->getArgument('association'); | ||
66 | $ownerId = $input->getArgument('owner-id'); | ||
67 | $cache = $em->getCache(); | ||
68 | |||
69 | if (! $cache instanceof Cache) { | ||
70 | throw new InvalidArgumentException('No second-level cache is configured on the given EntityManager.'); | ||
71 | } | ||
72 | |||
73 | if (( ! $ownerClass || ! $assoc) && ! $input->getOption('all')) { | ||
74 | throw new InvalidArgumentException('Missing arguments "--owner-class" "--association"'); | ||
75 | } | ||
76 | |||
77 | if ($input->getOption('flush')) { | ||
78 | $cache->getCollectionCacheRegion($ownerClass, $assoc) | ||
79 | ->evictAll(); | ||
80 | |||
81 | $ui->comment( | ||
82 | sprintf( | ||
83 | 'Flushing cache provider configured for <info>"%s#%s"</info>', | ||
84 | $ownerClass, | ||
85 | $assoc, | ||
86 | ), | ||
87 | ); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | if ($input->getOption('all')) { | ||
93 | $ui->comment('Clearing <info>all</info> second-level cache collection regions'); | ||
94 | |||
95 | $cache->evictEntityRegions(); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | if ($ownerId) { | ||
101 | $ui->comment( | ||
102 | sprintf( | ||
103 | 'Clearing second-level cache entry for collection <info>"%s#%s"</info> owner entity identified by <info>"%s"</info>', | ||
104 | $ownerClass, | ||
105 | $assoc, | ||
106 | $ownerId, | ||
107 | ), | ||
108 | ); | ||
109 | $cache->evictCollection($ownerClass, $assoc, $ownerId); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | $ui->comment(sprintf('Clearing second-level cache for collection <info>"%s#%s"</info>', $ownerClass, $assoc)); | ||
115 | $cache->evictCollectionRegion($ownerClass, $assoc); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/EntityRegionCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/EntityRegionCommand.php new file mode 100644 index 0000000..c5f2d65 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/EntityRegionCommand.php | |||
@@ -0,0 +1,110 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\ClearCache; | ||
6 | |||
7 | use Doctrine\ORM\Cache; | ||
8 | use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; | ||
9 | use InvalidArgumentException; | ||
10 | use Symfony\Component\Console\Input\InputArgument; | ||
11 | use Symfony\Component\Console\Input\InputInterface; | ||
12 | use Symfony\Component\Console\Input\InputOption; | ||
13 | use Symfony\Component\Console\Output\OutputInterface; | ||
14 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
15 | |||
16 | use function sprintf; | ||
17 | |||
18 | /** | ||
19 | * Command to clear a entity cache region. | ||
20 | */ | ||
21 | class EntityRegionCommand extends AbstractEntityManagerCommand | ||
22 | { | ||
23 | protected function configure(): void | ||
24 | { | ||
25 | $this->setName('orm:clear-cache:region:entity') | ||
26 | ->setDescription('Clear a second-level cache entity region') | ||
27 | ->addArgument('entity-class', InputArgument::OPTIONAL, 'The entity name.') | ||
28 | ->addArgument('entity-id', InputArgument::OPTIONAL, 'The entity identifier.') | ||
29 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
30 | ->addOption('all', null, InputOption::VALUE_NONE, 'If defined, all entity regions will be deleted/invalidated.') | ||
31 | ->addOption('flush', null, InputOption::VALUE_NONE, 'If defined, all cache entries will be flushed.') | ||
32 | ->setHelp(<<<'EOT' | ||
33 | The <info>%command.name%</info> command is meant to clear a second-level cache entity region for an associated Entity Manager. | ||
34 | It is possible to delete/invalidate all entity region, a specific entity region or flushes the cache provider. | ||
35 | |||
36 | The execution type differ on how you execute the command. | ||
37 | If you want to invalidate all entries for an entity region this command would do the work: | ||
38 | |||
39 | <info>%command.name% 'Entities\MyEntity'</info> | ||
40 | |||
41 | To invalidate a specific entry you should use : | ||
42 | |||
43 | <info>%command.name% 'Entities\MyEntity' 1</info> | ||
44 | |||
45 | If you want to invalidate all entries for the all entity regions: | ||
46 | |||
47 | <info>%command.name% --all</info> | ||
48 | |||
49 | Alternatively, if you want to flush the configured cache provider for an entity region use this command: | ||
50 | |||
51 | <info>%command.name% 'Entities\MyEntity' --flush</info> | ||
52 | |||
53 | Finally, be aware that if <info>--flush</info> option is passed, | ||
54 | not all cache providers are able to flush entries, because of a limitation of its execution nature. | ||
55 | EOT); | ||
56 | } | ||
57 | |||
58 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
59 | { | ||
60 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
61 | |||
62 | $em = $this->getEntityManager($input); | ||
63 | $entityClass = $input->getArgument('entity-class'); | ||
64 | $entityId = $input->getArgument('entity-id'); | ||
65 | $cache = $em->getCache(); | ||
66 | |||
67 | if (! $cache instanceof Cache) { | ||
68 | throw new InvalidArgumentException('No second-level cache is configured on the given EntityManager.'); | ||
69 | } | ||
70 | |||
71 | if (! $entityClass && ! $input->getOption('all')) { | ||
72 | throw new InvalidArgumentException('Invalid argument "--entity-class"'); | ||
73 | } | ||
74 | |||
75 | if ($input->getOption('flush')) { | ||
76 | $cache->getEntityCacheRegion($entityClass) | ||
77 | ->evictAll(); | ||
78 | |||
79 | $ui->comment(sprintf('Flushing cache provider configured for entity named <info>"%s"</info>', $entityClass)); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | if ($input->getOption('all')) { | ||
85 | $ui->comment('Clearing <info>all</info> second-level cache entity regions'); | ||
86 | |||
87 | $cache->evictEntityRegions(); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | if ($entityId) { | ||
93 | $ui->comment( | ||
94 | sprintf( | ||
95 | 'Clearing second-level cache entry for entity <info>"%s"</info> identified by <info>"%s"</info>', | ||
96 | $entityClass, | ||
97 | $entityId, | ||
98 | ), | ||
99 | ); | ||
100 | $cache->evictEntity($entityClass, $entityId); | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | $ui->comment(sprintf('Clearing second-level cache for entity <info>"%s"</info>', $entityClass)); | ||
106 | $cache->evictEntityRegion($entityClass); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/MetadataCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/MetadataCommand.php new file mode 100644 index 0000000..147795b --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/MetadataCommand.php | |||
@@ -0,0 +1,52 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\ClearCache; | ||
6 | |||
7 | use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; | ||
8 | use InvalidArgumentException; | ||
9 | use Symfony\Component\Console\Input\InputInterface; | ||
10 | use Symfony\Component\Console\Input\InputOption; | ||
11 | use Symfony\Component\Console\Output\OutputInterface; | ||
12 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
13 | |||
14 | /** | ||
15 | * Command to clear the metadata cache of the various cache drivers. | ||
16 | * | ||
17 | * @link www.doctrine-project.org | ||
18 | */ | ||
19 | class MetadataCommand extends AbstractEntityManagerCommand | ||
20 | { | ||
21 | protected function configure(): void | ||
22 | { | ||
23 | $this->setName('orm:clear-cache:metadata') | ||
24 | ->setDescription('Clear all metadata cache of the various cache drivers') | ||
25 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
26 | ->addOption('flush', null, InputOption::VALUE_NONE, 'If defined, cache entries will be flushed instead of deleted/invalidated.') | ||
27 | ->setHelp(<<<'EOT' | ||
28 | The <info>%command.name%</info> command is meant to clear the metadata cache of associated Entity Manager. | ||
29 | EOT); | ||
30 | } | ||
31 | |||
32 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
33 | { | ||
34 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
35 | |||
36 | $em = $this->getEntityManager($input); | ||
37 | $cacheDriver = $em->getConfiguration()->getMetadataCache(); | ||
38 | |||
39 | if (! $cacheDriver) { | ||
40 | throw new InvalidArgumentException('No Metadata cache driver is configured on given EntityManager.'); | ||
41 | } | ||
42 | |||
43 | $ui->comment('Clearing <info>all</info> Metadata cache entries'); | ||
44 | |||
45 | $result = $cacheDriver->clear(); | ||
46 | $message = $result ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.'; | ||
47 | |||
48 | $ui->success($message); | ||
49 | |||
50 | return 0; | ||
51 | } | ||
52 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/QueryCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/QueryCommand.php new file mode 100644 index 0000000..83edd7a --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/QueryCommand.php | |||
@@ -0,0 +1,54 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\ClearCache; | ||
6 | |||
7 | use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; | ||
8 | use InvalidArgumentException; | ||
9 | use LogicException; | ||
10 | use Symfony\Component\Cache\Adapter\ApcuAdapter; | ||
11 | use Symfony\Component\Console\Input\InputInterface; | ||
12 | use Symfony\Component\Console\Input\InputOption; | ||
13 | use Symfony\Component\Console\Output\OutputInterface; | ||
14 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
15 | |||
16 | /** | ||
17 | * Command to clear the query cache of the various cache drivers. | ||
18 | * | ||
19 | * @link www.doctrine-project.org | ||
20 | */ | ||
21 | class QueryCommand extends AbstractEntityManagerCommand | ||
22 | { | ||
23 | protected function configure(): void | ||
24 | { | ||
25 | $this->setName('orm:clear-cache:query') | ||
26 | ->setDescription('Clear all query cache of the various cache drivers') | ||
27 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
28 | ->setHelp('The <info>%command.name%</info> command is meant to clear the query cache of associated Entity Manager.'); | ||
29 | } | ||
30 | |||
31 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
32 | { | ||
33 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
34 | |||
35 | $em = $this->getEntityManager($input); | ||
36 | $cache = $em->getConfiguration()->getQueryCache(); | ||
37 | |||
38 | if (! $cache) { | ||
39 | throw new InvalidArgumentException('No Query cache driver is configured on given EntityManager.'); | ||
40 | } | ||
41 | |||
42 | if ($cache instanceof ApcuAdapter) { | ||
43 | throw new LogicException('Cannot clear APCu Cache from Console, it\'s shared in the Webserver memory and not accessible from the CLI.'); | ||
44 | } | ||
45 | |||
46 | $ui->comment('Clearing <info>all</info> Query cache entries'); | ||
47 | |||
48 | $message = $cache->clear() ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.'; | ||
49 | |||
50 | $ui->success($message); | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/QueryRegionCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/QueryRegionCommand.php new file mode 100644 index 0000000..e80fb90 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/QueryRegionCommand.php | |||
@@ -0,0 +1,101 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\ClearCache; | ||
6 | |||
7 | use Doctrine\ORM\Cache; | ||
8 | use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; | ||
9 | use InvalidArgumentException; | ||
10 | use Symfony\Component\Console\Input\InputArgument; | ||
11 | use Symfony\Component\Console\Input\InputInterface; | ||
12 | use Symfony\Component\Console\Input\InputOption; | ||
13 | use Symfony\Component\Console\Output\OutputInterface; | ||
14 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
15 | |||
16 | use function sprintf; | ||
17 | |||
18 | /** | ||
19 | * Command to clear a query cache region. | ||
20 | */ | ||
21 | class QueryRegionCommand extends AbstractEntityManagerCommand | ||
22 | { | ||
23 | protected function configure(): void | ||
24 | { | ||
25 | $this->setName('orm:clear-cache:region:query') | ||
26 | ->setDescription('Clear a second-level cache query region') | ||
27 | ->addArgument('region-name', InputArgument::OPTIONAL, 'The query region to clear.') | ||
28 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
29 | ->addOption('all', null, InputOption::VALUE_NONE, 'If defined, all query regions will be deleted/invalidated.') | ||
30 | ->addOption('flush', null, InputOption::VALUE_NONE, 'If defined, all cache entries will be flushed.') | ||
31 | ->setHelp(<<<'EOT' | ||
32 | The <info>%command.name%</info> command is meant to clear a second-level cache query region for an associated Entity Manager. | ||
33 | It is possible to delete/invalidate all query region, a specific query region or flushes the cache provider. | ||
34 | |||
35 | The execution type differ on how you execute the command. | ||
36 | If you want to invalidate all entries for the default query region this command would do the work: | ||
37 | |||
38 | <info>%command.name%</info> | ||
39 | |||
40 | To invalidate entries for a specific query region you should use : | ||
41 | |||
42 | <info>%command.name% my_region_name</info> | ||
43 | |||
44 | If you want to invalidate all entries for the all query region: | ||
45 | |||
46 | <info>%command.name% --all</info> | ||
47 | |||
48 | Alternatively, if you want to flush the configured cache provider use this command: | ||
49 | |||
50 | <info>%command.name% my_region_name --flush</info> | ||
51 | |||
52 | Finally, be aware that if <info>--flush</info> option is passed, | ||
53 | not all cache providers are able to flush entries, because of a limitation of its execution nature. | ||
54 | EOT); | ||
55 | } | ||
56 | |||
57 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
58 | { | ||
59 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
60 | |||
61 | $em = $this->getEntityManager($input); | ||
62 | $name = $input->getArgument('region-name'); | ||
63 | $cache = $em->getCache(); | ||
64 | |||
65 | if ($name === null) { | ||
66 | $name = Cache::DEFAULT_QUERY_REGION_NAME; | ||
67 | } | ||
68 | |||
69 | if (! $cache instanceof Cache) { | ||
70 | throw new InvalidArgumentException('No second-level cache is configured on the given EntityManager.'); | ||
71 | } | ||
72 | |||
73 | if ($input->getOption('flush')) { | ||
74 | $cache->getQueryCache($name) | ||
75 | ->getRegion() | ||
76 | ->evictAll(); | ||
77 | |||
78 | $ui->comment( | ||
79 | sprintf( | ||
80 | 'Flushing cache provider configured for second-level cache query region named <info>"%s"</info>', | ||
81 | $name, | ||
82 | ), | ||
83 | ); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | if ($input->getOption('all')) { | ||
89 | $ui->comment('Clearing <info>all</info> second-level cache query regions'); | ||
90 | |||
91 | $cache->evictQueryRegions(); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | $ui->comment(sprintf('Clearing second-level cache query region named <info>"%s"</info>', $name)); | ||
97 | $cache->evictQueryRegion($name); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/ResultCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/ResultCommand.php new file mode 100644 index 0000000..4f84e0b --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/ClearCache/ResultCommand.php | |||
@@ -0,0 +1,65 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\ClearCache; | ||
6 | |||
7 | use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; | ||
8 | use InvalidArgumentException; | ||
9 | use Symfony\Component\Console\Input\InputInterface; | ||
10 | use Symfony\Component\Console\Input\InputOption; | ||
11 | use Symfony\Component\Console\Output\OutputInterface; | ||
12 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
13 | |||
14 | /** | ||
15 | * Command to clear the result cache of the various cache drivers. | ||
16 | * | ||
17 | * @link www.doctrine-project.org | ||
18 | */ | ||
19 | class ResultCommand extends AbstractEntityManagerCommand | ||
20 | { | ||
21 | protected function configure(): void | ||
22 | { | ||
23 | $this->setName('orm:clear-cache:result') | ||
24 | ->setDescription('Clear all result cache of the various cache drivers') | ||
25 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
26 | ->addOption('flush', null, InputOption::VALUE_NONE, 'If defined, cache entries will be flushed instead of deleted/invalidated.') | ||
27 | ->setHelp(<<<'EOT' | ||
28 | The <info>%command.name%</info> command is meant to clear the result cache of associated Entity Manager. | ||
29 | It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider | ||
30 | instance completely. | ||
31 | |||
32 | The execution type differ on how you execute the command. | ||
33 | If you want to invalidate the entries (and not delete from cache instance), this command would do the work: | ||
34 | |||
35 | <info>%command.name%</info> | ||
36 | |||
37 | Alternatively, if you want to flush the cache provider using this command: | ||
38 | |||
39 | <info>%command.name% --flush</info> | ||
40 | |||
41 | Finally, be aware that if <info>--flush</info> option is passed, not all cache providers are able to flush entries, | ||
42 | because of a limitation of its execution nature. | ||
43 | EOT); | ||
44 | } | ||
45 | |||
46 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
47 | { | ||
48 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
49 | |||
50 | $em = $this->getEntityManager($input); | ||
51 | $cache = $em->getConfiguration()->getResultCache(); | ||
52 | |||
53 | if (! $cache) { | ||
54 | throw new InvalidArgumentException('No Result cache driver is configured on given EntityManager.'); | ||
55 | } | ||
56 | |||
57 | $ui->comment('Clearing <info>all</info> Result cache entries'); | ||
58 | |||
59 | $message = $cache->clear() ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.'; | ||
60 | |||
61 | $ui->success($message); | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/GenerateProxiesCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/GenerateProxiesCommand.php new file mode 100644 index 0000000..5a407de --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/GenerateProxiesCommand.php | |||
@@ -0,0 +1,96 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command; | ||
6 | |||
7 | use Doctrine\ORM\Tools\Console\MetadataFilter; | ||
8 | use InvalidArgumentException; | ||
9 | use Symfony\Component\Console\Input\InputArgument; | ||
10 | use Symfony\Component\Console\Input\InputInterface; | ||
11 | use Symfony\Component\Console\Input\InputOption; | ||
12 | use Symfony\Component\Console\Output\OutputInterface; | ||
13 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
14 | |||
15 | use function file_exists; | ||
16 | use function is_dir; | ||
17 | use function is_writable; | ||
18 | use function mkdir; | ||
19 | use function realpath; | ||
20 | use function sprintf; | ||
21 | |||
22 | /** | ||
23 | * Command to (re)generate the proxy classes used by doctrine. | ||
24 | * | ||
25 | * @link www.doctrine-project.org | ||
26 | */ | ||
27 | class GenerateProxiesCommand extends AbstractEntityManagerCommand | ||
28 | { | ||
29 | protected function configure(): void | ||
30 | { | ||
31 | $this->setName('orm:generate-proxies') | ||
32 | ->setAliases(['orm:generate:proxies']) | ||
33 | ->setDescription('Generates proxy classes for entity classes') | ||
34 | ->addArgument('dest-path', InputArgument::OPTIONAL, 'The path to generate your proxy classes. If none is provided, it will attempt to grab from configuration.') | ||
35 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
36 | ->addOption('filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'A string pattern used to match entities that should be processed.') | ||
37 | ->setHelp('Generates proxy classes for entity classes.'); | ||
38 | } | ||
39 | |||
40 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
41 | { | ||
42 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
43 | |||
44 | $em = $this->getEntityManager($input); | ||
45 | |||
46 | $metadatas = $em->getMetadataFactory()->getAllMetadata(); | ||
47 | $metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter')); | ||
48 | |||
49 | // Process destination directory | ||
50 | $destPath = $input->getArgument('dest-path'); | ||
51 | if ($destPath === null) { | ||
52 | $destPath = $em->getConfiguration()->getProxyDir(); | ||
53 | |||
54 | if ($destPath === null) { | ||
55 | throw new InvalidArgumentException('Proxy directory cannot be null'); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | if (! is_dir($destPath)) { | ||
60 | mkdir($destPath, 0775, true); | ||
61 | } | ||
62 | |||
63 | $destPath = realpath($destPath); | ||
64 | |||
65 | if (! file_exists($destPath)) { | ||
66 | throw new InvalidArgumentException( | ||
67 | sprintf("Proxies destination directory '<info>%s</info>' does not exist.", $em->getConfiguration()->getProxyDir()), | ||
68 | ); | ||
69 | } | ||
70 | |||
71 | if (! is_writable($destPath)) { | ||
72 | throw new InvalidArgumentException( | ||
73 | sprintf("Proxies destination directory '<info>%s</info>' does not have write permissions.", $destPath), | ||
74 | ); | ||
75 | } | ||
76 | |||
77 | if (empty($metadatas)) { | ||
78 | $ui->success('No Metadata Classes to process.'); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | foreach ($metadatas as $metadata) { | ||
84 | $ui->text(sprintf('Processing entity "<info>%s</info>"', $metadata->name)); | ||
85 | } | ||
86 | |||
87 | // Generating Proxies | ||
88 | $em->getProxyFactory()->generateProxyClasses($metadatas, $destPath); | ||
89 | |||
90 | // Outputting information message | ||
91 | $ui->newLine(); | ||
92 | $ui->text(sprintf('Proxy classes generated to "<info>%s</info>"', $destPath)); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/InfoCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/InfoCommand.php new file mode 100644 index 0000000..deebb58 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/InfoCommand.php | |||
@@ -0,0 +1,80 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command; | ||
6 | |||
7 | use Doctrine\ORM\Mapping\MappingException; | ||
8 | use Symfony\Component\Console\Input\InputInterface; | ||
9 | use Symfony\Component\Console\Input\InputOption; | ||
10 | use Symfony\Component\Console\Output\OutputInterface; | ||
11 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
12 | |||
13 | use function count; | ||
14 | use function sprintf; | ||
15 | |||
16 | /** | ||
17 | * Show information about mapped entities. | ||
18 | * | ||
19 | * @link www.doctrine-project.org | ||
20 | */ | ||
21 | class InfoCommand extends AbstractEntityManagerCommand | ||
22 | { | ||
23 | protected function configure(): void | ||
24 | { | ||
25 | $this->setName('orm:info') | ||
26 | ->setDescription('Show basic information about all mapped entities') | ||
27 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
28 | ->setHelp(<<<'EOT' | ||
29 | The <info>%command.name%</info> shows basic information about which | ||
30 | entities exist and possibly if their mapping information contains errors or | ||
31 | not. | ||
32 | EOT); | ||
33 | } | ||
34 | |||
35 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
36 | { | ||
37 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
38 | |||
39 | $entityManager = $this->getEntityManager($input); | ||
40 | |||
41 | $entityClassNames = $entityManager->getConfiguration() | ||
42 | ->getMetadataDriverImpl() | ||
43 | ->getAllClassNames(); | ||
44 | |||
45 | if (! $entityClassNames) { | ||
46 | $ui->caution( | ||
47 | [ | ||
48 | 'You do not have any mapped Doctrine ORM entities according to the current configuration.', | ||
49 | 'If you have entities or mapping files you should check your mapping configuration for errors.', | ||
50 | ], | ||
51 | ); | ||
52 | |||
53 | return 1; | ||
54 | } | ||
55 | |||
56 | $ui->text(sprintf('Found <info>%d</info> mapped entities:', count($entityClassNames))); | ||
57 | $ui->newLine(); | ||
58 | |||
59 | $failure = false; | ||
60 | |||
61 | foreach ($entityClassNames as $entityClassName) { | ||
62 | try { | ||
63 | $entityManager->getClassMetadata($entityClassName); | ||
64 | $ui->text(sprintf('<info>[OK]</info> %s', $entityClassName)); | ||
65 | } catch (MappingException $e) { | ||
66 | $ui->text( | ||
67 | [ | ||
68 | sprintf('<error>[FAIL]</error> %s', $entityClassName), | ||
69 | sprintf('<comment>%s</comment>', $e->getMessage()), | ||
70 | '', | ||
71 | ], | ||
72 | ); | ||
73 | |||
74 | $failure = true; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | return $failure ? 1 : 0; | ||
79 | } | ||
80 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/MappingDescribeCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/MappingDescribeCommand.php new file mode 100644 index 0000000..41a177d --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/MappingDescribeCommand.php | |||
@@ -0,0 +1,279 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command; | ||
6 | |||
7 | use Doctrine\ORM\EntityManagerInterface; | ||
8 | use Doctrine\ORM\Mapping\AssociationMapping; | ||
9 | use Doctrine\ORM\Mapping\ClassMetadata; | ||
10 | use Doctrine\ORM\Mapping\FieldMapping; | ||
11 | use Doctrine\Persistence\Mapping\MappingException; | ||
12 | use InvalidArgumentException; | ||
13 | use Symfony\Component\Console\Input\InputArgument; | ||
14 | use Symfony\Component\Console\Input\InputInterface; | ||
15 | use Symfony\Component\Console\Input\InputOption; | ||
16 | use Symfony\Component\Console\Output\OutputInterface; | ||
17 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
18 | |||
19 | use function array_filter; | ||
20 | use function array_map; | ||
21 | use function array_merge; | ||
22 | use function count; | ||
23 | use function current; | ||
24 | use function get_debug_type; | ||
25 | use function implode; | ||
26 | use function is_array; | ||
27 | use function is_bool; | ||
28 | use function is_object; | ||
29 | use function is_scalar; | ||
30 | use function json_encode; | ||
31 | use function preg_match; | ||
32 | use function preg_quote; | ||
33 | use function print_r; | ||
34 | use function sprintf; | ||
35 | |||
36 | use const JSON_PRETTY_PRINT; | ||
37 | use const JSON_THROW_ON_ERROR; | ||
38 | use const JSON_UNESCAPED_SLASHES; | ||
39 | use const JSON_UNESCAPED_UNICODE; | ||
40 | |||
41 | /** | ||
42 | * Show information about mapped entities. | ||
43 | * | ||
44 | * @link www.doctrine-project.org | ||
45 | */ | ||
46 | final class MappingDescribeCommand extends AbstractEntityManagerCommand | ||
47 | { | ||
48 | protected function configure(): void | ||
49 | { | ||
50 | $this->setName('orm:mapping:describe') | ||
51 | ->addArgument('entityName', InputArgument::REQUIRED, 'Full or partial name of entity') | ||
52 | ->setDescription('Display information about mapped objects') | ||
53 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
54 | ->setHelp(<<<'EOT' | ||
55 | The %command.full_name% command describes the metadata for the given full or partial entity class name. | ||
56 | |||
57 | <info>%command.full_name%</info> My\Namespace\Entity\MyEntity | ||
58 | |||
59 | Or: | ||
60 | |||
61 | <info>%command.full_name%</info> MyEntity | ||
62 | EOT); | ||
63 | } | ||
64 | |||
65 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
66 | { | ||
67 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
68 | |||
69 | $entityManager = $this->getEntityManager($input); | ||
70 | |||
71 | $this->displayEntity($input->getArgument('entityName'), $entityManager, $ui); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * Display all the mapping information for a single Entity. | ||
78 | * | ||
79 | * @param string $entityName Full or partial entity class name | ||
80 | */ | ||
81 | private function displayEntity( | ||
82 | string $entityName, | ||
83 | EntityManagerInterface $entityManager, | ||
84 | SymfonyStyle $ui, | ||
85 | ): void { | ||
86 | $metadata = $this->getClassMetadata($entityName, $entityManager); | ||
87 | |||
88 | $ui->table( | ||
89 | ['Field', 'Value'], | ||
90 | array_merge( | ||
91 | [ | ||
92 | $this->formatField('Name', $metadata->name), | ||
93 | $this->formatField('Root entity name', $metadata->rootEntityName), | ||
94 | $this->formatField('Custom generator definition', $metadata->customGeneratorDefinition), | ||
95 | $this->formatField('Custom repository class', $metadata->customRepositoryClassName), | ||
96 | $this->formatField('Mapped super class?', $metadata->isMappedSuperclass), | ||
97 | $this->formatField('Embedded class?', $metadata->isEmbeddedClass), | ||
98 | $this->formatField('Parent classes', $metadata->parentClasses), | ||
99 | $this->formatField('Sub classes', $metadata->subClasses), | ||
100 | $this->formatField('Embedded classes', $metadata->subClasses), | ||
101 | $this->formatField('Identifier', $metadata->identifier), | ||
102 | $this->formatField('Inheritance type', $metadata->inheritanceType), | ||
103 | $this->formatField('Discriminator column', $metadata->discriminatorColumn), | ||
104 | $this->formatField('Discriminator value', $metadata->discriminatorValue), | ||
105 | $this->formatField('Discriminator map', $metadata->discriminatorMap), | ||
106 | $this->formatField('Generator type', $metadata->generatorType), | ||
107 | $this->formatField('Table', $metadata->table), | ||
108 | $this->formatField('Composite identifier?', $metadata->isIdentifierComposite), | ||
109 | $this->formatField('Foreign identifier?', $metadata->containsForeignIdentifier), | ||
110 | $this->formatField('Enum identifier?', $metadata->containsEnumIdentifier), | ||
111 | $this->formatField('Sequence generator definition', $metadata->sequenceGeneratorDefinition), | ||
112 | $this->formatField('Change tracking policy', $metadata->changeTrackingPolicy), | ||
113 | $this->formatField('Versioned?', $metadata->isVersioned), | ||
114 | $this->formatField('Version field', $metadata->versionField), | ||
115 | $this->formatField('Read only?', $metadata->isReadOnly), | ||
116 | |||
117 | $this->formatEntityListeners($metadata->entityListeners), | ||
118 | ], | ||
119 | [$this->formatField('Association mappings:', '')], | ||
120 | $this->formatMappings($metadata->associationMappings), | ||
121 | [$this->formatField('Field mappings:', '')], | ||
122 | $this->formatMappings($metadata->fieldMappings), | ||
123 | ), | ||
124 | ); | ||
125 | } | ||
126 | |||
127 | /** | ||
128 | * Return all mapped entity class names | ||
129 | * | ||
130 | * @return string[] | ||
131 | * @psalm-return class-string[] | ||
132 | */ | ||
133 | private function getMappedEntities(EntityManagerInterface $entityManager): array | ||
134 | { | ||
135 | $entityClassNames = $entityManager->getConfiguration() | ||
136 | ->getMetadataDriverImpl() | ||
137 | ->getAllClassNames(); | ||
138 | |||
139 | if (! $entityClassNames) { | ||
140 | throw new InvalidArgumentException( | ||
141 | 'You do not have any mapped Doctrine ORM entities according to the current configuration. ' . | ||
142 | 'If you have entities or mapping files you should check your mapping configuration for errors.', | ||
143 | ); | ||
144 | } | ||
145 | |||
146 | return $entityClassNames; | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * Return the class metadata for the given entity | ||
151 | * name | ||
152 | * | ||
153 | * @param string $entityName Full or partial entity name | ||
154 | */ | ||
155 | private function getClassMetadata( | ||
156 | string $entityName, | ||
157 | EntityManagerInterface $entityManager, | ||
158 | ): ClassMetadata { | ||
159 | try { | ||
160 | return $entityManager->getClassMetadata($entityName); | ||
161 | } catch (MappingException) { | ||
162 | } | ||
163 | |||
164 | $matches = array_filter( | ||
165 | $this->getMappedEntities($entityManager), | ||
166 | static fn ($mappedEntity) => preg_match('{' . preg_quote($entityName) . '}', $mappedEntity) | ||
167 | ); | ||
168 | |||
169 | if (! $matches) { | ||
170 | throw new InvalidArgumentException(sprintf( | ||
171 | 'Could not find any mapped Entity classes matching "%s"', | ||
172 | $entityName, | ||
173 | )); | ||
174 | } | ||
175 | |||
176 | if (count($matches) > 1) { | ||
177 | throw new InvalidArgumentException(sprintf( | ||
178 | 'Entity name "%s" is ambiguous, possible matches: "%s"', | ||
179 | $entityName, | ||
180 | implode(', ', $matches), | ||
181 | )); | ||
182 | } | ||
183 | |||
184 | return $entityManager->getClassMetadata(current($matches)); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * Format the given value for console output | ||
189 | */ | ||
190 | private function formatValue(mixed $value): string | ||
191 | { | ||
192 | if ($value === '') { | ||
193 | return ''; | ||
194 | } | ||
195 | |||
196 | if ($value === null) { | ||
197 | return '<comment>Null</comment>'; | ||
198 | } | ||
199 | |||
200 | if (is_bool($value)) { | ||
201 | return '<comment>' . ($value ? 'True' : 'False') . '</comment>'; | ||
202 | } | ||
203 | |||
204 | if (empty($value)) { | ||
205 | return '<comment>Empty</comment>'; | ||
206 | } | ||
207 | |||
208 | if (is_array($value)) { | ||
209 | return json_encode( | ||
210 | $value, | ||
211 | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR, | ||
212 | ); | ||
213 | } | ||
214 | |||
215 | if (is_object($value)) { | ||
216 | return sprintf('<%s>', get_debug_type($value)); | ||
217 | } | ||
218 | |||
219 | if (is_scalar($value)) { | ||
220 | return (string) $value; | ||
221 | } | ||
222 | |||
223 | throw new InvalidArgumentException(sprintf('Do not know how to format value "%s"', print_r($value, true))); | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * Add the given label and value to the two column table output | ||
228 | * | ||
229 | * @param string $label Label for the value | ||
230 | * @param mixed $value A Value to show | ||
231 | * | ||
232 | * @return string[] | ||
233 | * @psalm-return array{0: string, 1: string} | ||
234 | */ | ||
235 | private function formatField(string $label, mixed $value): array | ||
236 | { | ||
237 | if ($value === null) { | ||
238 | $value = '<comment>None</comment>'; | ||
239 | } | ||
240 | |||
241 | return [sprintf('<info>%s</info>', $label), $this->formatValue($value)]; | ||
242 | } | ||
243 | |||
244 | /** | ||
245 | * Format the association mappings | ||
246 | * | ||
247 | * @psalm-param array<string, FieldMapping|AssociationMapping> $propertyMappings | ||
248 | * | ||
249 | * @return string[][] | ||
250 | * @psalm-return list<array{0: string, 1: string}> | ||
251 | */ | ||
252 | private function formatMappings(array $propertyMappings): array | ||
253 | { | ||
254 | $output = []; | ||
255 | |||
256 | foreach ($propertyMappings as $propertyName => $mapping) { | ||
257 | $output[] = $this->formatField(sprintf(' %s', $propertyName), ''); | ||
258 | |||
259 | foreach ((array) $mapping as $field => $value) { | ||
260 | $output[] = $this->formatField(sprintf(' %s', $field), $this->formatValue($value)); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | return $output; | ||
265 | } | ||
266 | |||
267 | /** | ||
268 | * Format the entity listeners | ||
269 | * | ||
270 | * @psalm-param list<object> $entityListeners | ||
271 | * | ||
272 | * @return string[] | ||
273 | * @psalm-return array{0: string, 1: string} | ||
274 | */ | ||
275 | private function formatEntityListeners(array $entityListeners): array | ||
276 | { | ||
277 | return $this->formatField('Entity listeners', array_map('get_class', $entityListeners)); | ||
278 | } | ||
279 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/RunDqlCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/RunDqlCommand.php new file mode 100644 index 0000000..252151e --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/RunDqlCommand.php | |||
@@ -0,0 +1,118 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command; | ||
6 | |||
7 | use Doctrine\ORM\Tools\Debug; | ||
8 | use LogicException; | ||
9 | use RuntimeException; | ||
10 | use Symfony\Component\Console\Input\InputArgument; | ||
11 | use Symfony\Component\Console\Input\InputInterface; | ||
12 | use Symfony\Component\Console\Input\InputOption; | ||
13 | use Symfony\Component\Console\Output\OutputInterface; | ||
14 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
15 | |||
16 | use function constant; | ||
17 | use function defined; | ||
18 | use function is_numeric; | ||
19 | use function sprintf; | ||
20 | use function str_replace; | ||
21 | use function strtoupper; | ||
22 | |||
23 | /** | ||
24 | * Command to execute DQL queries in a given EntityManager. | ||
25 | * | ||
26 | * @link www.doctrine-project.org | ||
27 | */ | ||
28 | class RunDqlCommand extends AbstractEntityManagerCommand | ||
29 | { | ||
30 | protected function configure(): void | ||
31 | { | ||
32 | $this->setName('orm:run-dql') | ||
33 | ->setDescription('Executes arbitrary DQL directly from the command line') | ||
34 | ->addArgument('dql', InputArgument::REQUIRED, 'The DQL to execute.') | ||
35 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
36 | ->addOption('hydrate', null, InputOption::VALUE_REQUIRED, 'Hydration mode of result set. Should be either: object, array, scalar or single-scalar.', 'object') | ||
37 | ->addOption('first-result', null, InputOption::VALUE_REQUIRED, 'The first result in the result set.') | ||
38 | ->addOption('max-result', null, InputOption::VALUE_REQUIRED, 'The maximum number of results in the result set.') | ||
39 | ->addOption('depth', null, InputOption::VALUE_REQUIRED, 'Dumping depth of Entity graph.', 7) | ||
40 | ->addOption('show-sql', null, InputOption::VALUE_NONE, 'Dump generated SQL instead of executing query') | ||
41 | ->setHelp(<<<'EOT' | ||
42 | The <info>%command.name%</info> command executes the given DQL query and | ||
43 | outputs the results: | ||
44 | |||
45 | <info>php %command.full_name% "SELECT u FROM App\Entity\User u"</info> | ||
46 | |||
47 | You can also optionally specify some additional options like what type of | ||
48 | hydration to use when executing the query: | ||
49 | |||
50 | <info>php %command.full_name% "SELECT u FROM App\Entity\User u" --hydrate=array</info> | ||
51 | |||
52 | Additionally you can specify the first result and maximum amount of results to | ||
53 | show: | ||
54 | |||
55 | <info>php %command.full_name% "SELECT u FROM App\Entity\User u" --first-result=0 --max-result=30</info> | ||
56 | EOT); | ||
57 | } | ||
58 | |||
59 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
60 | { | ||
61 | $ui = new SymfonyStyle($input, $output); | ||
62 | |||
63 | $em = $this->getEntityManager($input); | ||
64 | |||
65 | $dql = $input->getArgument('dql'); | ||
66 | if ($dql === null) { | ||
67 | throw new RuntimeException("Argument 'dql' is required in order to execute this command correctly."); | ||
68 | } | ||
69 | |||
70 | $depth = $input->getOption('depth'); | ||
71 | |||
72 | if (! is_numeric($depth)) { | ||
73 | throw new LogicException("Option 'depth' must contain an integer value"); | ||
74 | } | ||
75 | |||
76 | $hydrationModeName = (string) $input->getOption('hydrate'); | ||
77 | $hydrationMode = 'Doctrine\ORM\Query::HYDRATE_' . strtoupper(str_replace('-', '_', $hydrationModeName)); | ||
78 | |||
79 | if (! defined($hydrationMode)) { | ||
80 | throw new RuntimeException(sprintf( | ||
81 | "Hydration mode '%s' does not exist. It should be either: object. array, scalar or single-scalar.", | ||
82 | $hydrationModeName, | ||
83 | )); | ||
84 | } | ||
85 | |||
86 | $query = $em->createQuery($dql); | ||
87 | |||
88 | $firstResult = $input->getOption('first-result'); | ||
89 | if ($firstResult !== null) { | ||
90 | if (! is_numeric($firstResult)) { | ||
91 | throw new LogicException("Option 'first-result' must contain an integer value"); | ||
92 | } | ||
93 | |||
94 | $query->setFirstResult((int) $firstResult); | ||
95 | } | ||
96 | |||
97 | $maxResult = $input->getOption('max-result'); | ||
98 | if ($maxResult !== null) { | ||
99 | if (! is_numeric($maxResult)) { | ||
100 | throw new LogicException("Option 'max-result' must contain an integer value"); | ||
101 | } | ||
102 | |||
103 | $query->setMaxResults((int) $maxResult); | ||
104 | } | ||
105 | |||
106 | if ($input->getOption('show-sql')) { | ||
107 | $ui->text($query->getSQL()); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | $resultSet = $query->execute([], constant($hydrationMode)); | ||
113 | |||
114 | $ui->text(Debug::dump($resultSet, (int) $input->getOption('depth'))); | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/AbstractCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/AbstractCommand.php new file mode 100644 index 0000000..b1e4460 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/AbstractCommand.php | |||
@@ -0,0 +1,39 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\SchemaTool; | ||
6 | |||
7 | use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; | ||
8 | use Doctrine\ORM\Tools\SchemaTool; | ||
9 | use Symfony\Component\Console\Input\InputInterface; | ||
10 | use Symfony\Component\Console\Output\OutputInterface; | ||
11 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
12 | |||
13 | /** | ||
14 | * Base class for CreateCommand, DropCommand and UpdateCommand. | ||
15 | * | ||
16 | * @link www.doctrine-project.org | ||
17 | */ | ||
18 | abstract class AbstractCommand extends AbstractEntityManagerCommand | ||
19 | { | ||
20 | /** @param mixed[] $metadatas */ | ||
21 | abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui): int; | ||
22 | |||
23 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
24 | { | ||
25 | $ui = new SymfonyStyle($input, $output); | ||
26 | |||
27 | $em = $this->getEntityManager($input); | ||
28 | |||
29 | $metadatas = $em->getMetadataFactory()->getAllMetadata(); | ||
30 | |||
31 | if (empty($metadatas)) { | ||
32 | $ui->getErrorStyle()->success('No Metadata Classes to process.'); | ||
33 | |||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | return $this->executeSchemaCommand($input, $output, new SchemaTool($em), $metadatas, $ui); | ||
38 | } | ||
39 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/CreateCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/CreateCommand.php new file mode 100644 index 0000000..69e20c6 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/CreateCommand.php | |||
@@ -0,0 +1,75 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\SchemaTool; | ||
6 | |||
7 | use Doctrine\ORM\Tools\SchemaTool; | ||
8 | use Symfony\Component\Console\Input\InputInterface; | ||
9 | use Symfony\Component\Console\Input\InputOption; | ||
10 | use Symfony\Component\Console\Output\OutputInterface; | ||
11 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
12 | |||
13 | use function sprintf; | ||
14 | |||
15 | /** | ||
16 | * Command to create the database schema for a set of classes based on their mappings. | ||
17 | * | ||
18 | * @link www.doctrine-project.org | ||
19 | */ | ||
20 | class CreateCommand extends AbstractCommand | ||
21 | { | ||
22 | protected function configure(): void | ||
23 | { | ||
24 | $this->setName('orm:schema-tool:create') | ||
25 | ->setDescription('Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output') | ||
26 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
27 | ->addOption('dump-sql', null, InputOption::VALUE_NONE, 'Instead of trying to apply generated SQLs into EntityManager Storage Connection, output them.') | ||
28 | ->setHelp(<<<'EOT' | ||
29 | Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output. | ||
30 | |||
31 | <comment>Hint:</comment> If you have a database with tables that should not be managed | ||
32 | by the ORM, you can use a DBAL functionality to filter the tables and sequences down | ||
33 | on a global level: | ||
34 | |||
35 | $config->setSchemaAssetsFilter(function (string|AbstractAsset $assetName): bool { | ||
36 | if ($assetName instanceof AbstractAsset) { | ||
37 | $assetName = $assetName->getName(); | ||
38 | } | ||
39 | |||
40 | return !str_starts_with($assetName, 'audit_'); | ||
41 | }); | ||
42 | EOT); | ||
43 | } | ||
44 | |||
45 | /** | ||
46 | * {@inheritDoc} | ||
47 | */ | ||
48 | protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui): int | ||
49 | { | ||
50 | $dumpSql = $input->getOption('dump-sql') === true; | ||
51 | |||
52 | if ($dumpSql) { | ||
53 | $sqls = $schemaTool->getCreateSchemaSql($metadatas); | ||
54 | |||
55 | foreach ($sqls as $sql) { | ||
56 | $ui->writeln(sprintf('%s;', $sql)); | ||
57 | } | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | $notificationUi = $ui->getErrorStyle(); | ||
63 | |||
64 | $notificationUi->caution('This operation should not be executed in a production environment!'); | ||
65 | |||
66 | $notificationUi->text('Creating database schema...'); | ||
67 | $notificationUi->newLine(); | ||
68 | |||
69 | $schemaTool->createSchema($metadatas); | ||
70 | |||
71 | $notificationUi->success('Database schema created successfully!'); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/DropCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/DropCommand.php new file mode 100644 index 0000000..5c8253b --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/DropCommand.php | |||
@@ -0,0 +1,116 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\SchemaTool; | ||
6 | |||
7 | use Doctrine\ORM\Tools\SchemaTool; | ||
8 | use Symfony\Component\Console\Input\InputInterface; | ||
9 | use Symfony\Component\Console\Input\InputOption; | ||
10 | use Symfony\Component\Console\Output\OutputInterface; | ||
11 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
12 | |||
13 | use function count; | ||
14 | use function sprintf; | ||
15 | |||
16 | /** | ||
17 | * Command to drop the database schema for a set of classes based on their mappings. | ||
18 | * | ||
19 | * @link www.doctrine-project.org | ||
20 | */ | ||
21 | class DropCommand extends AbstractCommand | ||
22 | { | ||
23 | protected function configure(): void | ||
24 | { | ||
25 | $this->setName('orm:schema-tool:drop') | ||
26 | ->setDescription('Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output') | ||
27 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
28 | ->addOption('dump-sql', null, InputOption::VALUE_NONE, 'Instead of trying to apply generated SQLs into EntityManager Storage Connection, output them.') | ||
29 | ->addOption('force', 'f', InputOption::VALUE_NONE, "Don't ask for the deletion of the database, but force the operation to run.") | ||
30 | ->addOption('full-database', null, InputOption::VALUE_NONE, 'Instead of using the Class Metadata to detect the database table schema, drop ALL assets that the database contains.') | ||
31 | ->setHelp(<<<'EOT' | ||
32 | Processes the schema and either drop the database schema of EntityManager Storage Connection or generate the SQL output. | ||
33 | Beware that the complete database is dropped by this command, even tables that are not relevant to your metadata model. | ||
34 | |||
35 | <comment>Hint:</comment> If you have a database with tables that should not be managed | ||
36 | by the ORM, you can use a DBAL functionality to filter the tables and sequences down | ||
37 | on a global level: | ||
38 | |||
39 | $config->setSchemaAssetsFilter(function (string|AbstractAsset $assetName): bool { | ||
40 | if ($assetName instanceof AbstractAsset) { | ||
41 | $assetName = $assetName->getName(); | ||
42 | } | ||
43 | |||
44 | return !str_starts_with($assetName, 'audit_'); | ||
45 | }); | ||
46 | EOT); | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * {@inheritDoc} | ||
51 | */ | ||
52 | protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui): int | ||
53 | { | ||
54 | $isFullDatabaseDrop = $input->getOption('full-database'); | ||
55 | $dumpSql = $input->getOption('dump-sql') === true; | ||
56 | $force = $input->getOption('force') === true; | ||
57 | |||
58 | if ($dumpSql) { | ||
59 | if ($isFullDatabaseDrop) { | ||
60 | $sqls = $schemaTool->getDropDatabaseSQL(); | ||
61 | } else { | ||
62 | $sqls = $schemaTool->getDropSchemaSQL($metadatas); | ||
63 | } | ||
64 | |||
65 | foreach ($sqls as $sql) { | ||
66 | $ui->writeln(sprintf('%s;', $sql)); | ||
67 | } | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | $notificationUi = $ui->getErrorStyle(); | ||
73 | |||
74 | if ($force) { | ||
75 | $notificationUi->text('Dropping database schema...'); | ||
76 | $notificationUi->newLine(); | ||
77 | |||
78 | if ($isFullDatabaseDrop) { | ||
79 | $schemaTool->dropDatabase(); | ||
80 | } else { | ||
81 | $schemaTool->dropSchema($metadatas); | ||
82 | } | ||
83 | |||
84 | $notificationUi->success('Database schema dropped successfully!'); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | $notificationUi->caution('This operation should not be executed in a production environment!'); | ||
90 | |||
91 | if ($isFullDatabaseDrop) { | ||
92 | $sqls = $schemaTool->getDropDatabaseSQL(); | ||
93 | } else { | ||
94 | $sqls = $schemaTool->getDropSchemaSQL($metadatas); | ||
95 | } | ||
96 | |||
97 | if (empty($sqls)) { | ||
98 | $notificationUi->success('Nothing to drop. The database is empty!'); | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | $notificationUi->text( | ||
104 | [ | ||
105 | sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)), | ||
106 | '', | ||
107 | 'Please run the operation by passing one - or both - of the following options:', | ||
108 | '', | ||
109 | sprintf(' <info>%s --force</info> to execute the command', $this->getName()), | ||
110 | sprintf(' <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()), | ||
111 | ], | ||
112 | ); | ||
113 | |||
114 | return 1; | ||
115 | } | ||
116 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/UpdateCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/UpdateCommand.php new file mode 100644 index 0000000..f35fc38 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/UpdateCommand.php | |||
@@ -0,0 +1,147 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command\SchemaTool; | ||
6 | |||
7 | use Doctrine\Deprecations\Deprecation; | ||
8 | use Doctrine\ORM\Tools\SchemaTool; | ||
9 | use Symfony\Component\Console\Input\InputInterface; | ||
10 | use Symfony\Component\Console\Input\InputOption; | ||
11 | use Symfony\Component\Console\Output\OutputInterface; | ||
12 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
13 | |||
14 | use function count; | ||
15 | use function sprintf; | ||
16 | |||
17 | /** | ||
18 | * Command to generate the SQL needed to update the database schema to match | ||
19 | * the current mapping information. | ||
20 | * | ||
21 | * @link www.doctrine-project.org | ||
22 | */ | ||
23 | class UpdateCommand extends AbstractCommand | ||
24 | { | ||
25 | protected string $name = 'orm:schema-tool:update'; | ||
26 | |||
27 | protected function configure(): void | ||
28 | { | ||
29 | $this->setName($this->name) | ||
30 | ->setDescription('Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata') | ||
31 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
32 | ->addOption('complete', null, InputOption::VALUE_NONE, 'This option is a no-op, is deprecated and will be removed in 4.0') | ||
33 | ->addOption('dump-sql', null, InputOption::VALUE_NONE, 'Dumps the generated SQL statements to the screen (does not execute them).') | ||
34 | ->addOption('force', 'f', InputOption::VALUE_NONE, 'Causes the generated SQL statements to be physically executed against your database.') | ||
35 | ->setHelp(<<<'EOT' | ||
36 | The <info>%command.name%</info> command generates the SQL needed to | ||
37 | synchronize the database schema with the current mapping metadata of the | ||
38 | default entity manager. | ||
39 | |||
40 | For example, if you add metadata for a new column to an entity, this command | ||
41 | would generate and output the SQL needed to add the new column to the database: | ||
42 | |||
43 | <info>%command.name% --dump-sql</info> | ||
44 | |||
45 | Alternatively, you can execute the generated queries: | ||
46 | |||
47 | <info>%command.name% --force</info> | ||
48 | |||
49 | If both options are specified, the queries are output and then executed: | ||
50 | |||
51 | <info>%command.name% --dump-sql --force</info> | ||
52 | |||
53 | Finally, be aware that this task will drop all database assets (e.g. tables, | ||
54 | etc) that are *not* described by the current metadata. In other words, without | ||
55 | this option, this task leaves untouched any "extra" tables that exist in the | ||
56 | database, but which aren't described by any metadata. | ||
57 | |||
58 | <comment>Hint:</comment> If you have a database with tables that should not be managed | ||
59 | by the ORM, you can use a DBAL functionality to filter the tables and sequences down | ||
60 | on a global level: | ||
61 | |||
62 | $config->setSchemaAssetsFilter(function (string|AbstractAsset $assetName): bool { | ||
63 | if ($assetName instanceof AbstractAsset) { | ||
64 | $assetName = $assetName->getName(); | ||
65 | } | ||
66 | |||
67 | return !str_starts_with($assetName, 'audit_'); | ||
68 | }); | ||
69 | EOT); | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * {@inheritDoc} | ||
74 | */ | ||
75 | protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui): int | ||
76 | { | ||
77 | $notificationUi = $ui->getErrorStyle(); | ||
78 | |||
79 | if ($input->getOption('complete') === true) { | ||
80 | Deprecation::trigger( | ||
81 | 'doctrine/orm', | ||
82 | 'https://github.com/doctrine/orm/pull/11354', | ||
83 | 'The --complete option is a no-op, is deprecated and will be removed in Doctrine ORM 4.0.', | ||
84 | ); | ||
85 | $notificationUi->warning('The --complete option is a no-op, is deprecated and will be removed in Doctrine ORM 4.0.'); | ||
86 | } | ||
87 | |||
88 | $sqls = $schemaTool->getUpdateSchemaSql($metadatas); | ||
89 | |||
90 | if (empty($sqls)) { | ||
91 | $notificationUi->success('Nothing to update - your database is already in sync with the current entity metadata.'); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | $dumpSql = $input->getOption('dump-sql') === true; | ||
97 | $force = $input->getOption('force') === true; | ||
98 | |||
99 | if ($dumpSql) { | ||
100 | foreach ($sqls as $sql) { | ||
101 | $ui->writeln(sprintf('%s;', $sql)); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | if ($force) { | ||
106 | if ($dumpSql) { | ||
107 | $notificationUi->newLine(); | ||
108 | } | ||
109 | |||
110 | $notificationUi->text('Updating database schema...'); | ||
111 | $notificationUi->newLine(); | ||
112 | |||
113 | $schemaTool->updateSchema($metadatas); | ||
114 | |||
115 | $pluralization = count($sqls) === 1 ? 'query was' : 'queries were'; | ||
116 | |||
117 | $notificationUi->text(sprintf(' <info>%s</info> %s executed', count($sqls), $pluralization)); | ||
118 | $notificationUi->success('Database schema updated successfully!'); | ||
119 | } | ||
120 | |||
121 | if ($dumpSql || $force) { | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | $notificationUi->caution( | ||
126 | [ | ||
127 | 'This operation should not be executed in a production environment!', | ||
128 | '', | ||
129 | 'Use the incremental update to detect changes during development and use', | ||
130 | 'the SQL DDL provided to manually update your database in production.', | ||
131 | ], | ||
132 | ); | ||
133 | |||
134 | $notificationUi->text( | ||
135 | [ | ||
136 | sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)), | ||
137 | '', | ||
138 | 'Please run the operation by passing one - or both - of the following options:', | ||
139 | '', | ||
140 | sprintf(' <info>%s --force</info> to execute the command', $this->getName()), | ||
141 | sprintf(' <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()), | ||
142 | ], | ||
143 | ); | ||
144 | |||
145 | return 1; | ||
146 | } | ||
147 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/Command/ValidateSchemaCommand.php b/vendor/doctrine/orm/src/Tools/Console/Command/ValidateSchemaCommand.php new file mode 100644 index 0000000..cffb4ce --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/Command/ValidateSchemaCommand.php | |||
@@ -0,0 +1,89 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\Command; | ||
6 | |||
7 | use Doctrine\ORM\Tools\SchemaValidator; | ||
8 | use Symfony\Component\Console\Input\InputInterface; | ||
9 | use Symfony\Component\Console\Input\InputOption; | ||
10 | use Symfony\Component\Console\Output\OutputInterface; | ||
11 | use Symfony\Component\Console\Style\SymfonyStyle; | ||
12 | |||
13 | use function count; | ||
14 | use function sprintf; | ||
15 | |||
16 | /** | ||
17 | * Command to validate that the current mapping is valid. | ||
18 | * | ||
19 | * @link www.doctrine-project.com | ||
20 | */ | ||
21 | class ValidateSchemaCommand extends AbstractEntityManagerCommand | ||
22 | { | ||
23 | protected function configure(): void | ||
24 | { | ||
25 | $this->setName('orm:validate-schema') | ||
26 | ->setDescription('Validate the mapping files') | ||
27 | ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') | ||
28 | ->addOption('skip-mapping', null, InputOption::VALUE_NONE, 'Skip the mapping validation check') | ||
29 | ->addOption('skip-sync', null, InputOption::VALUE_NONE, 'Skip checking if the mapping is in sync with the database') | ||
30 | ->addOption('skip-property-types', null, InputOption::VALUE_NONE, 'Skip checking if property types match the Doctrine types') | ||
31 | ->setHelp('Validate that the mapping files are correct and in sync with the database.'); | ||
32 | } | ||
33 | |||
34 | protected function execute(InputInterface $input, OutputInterface $output): int | ||
35 | { | ||
36 | $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); | ||
37 | |||
38 | $em = $this->getEntityManager($input); | ||
39 | $validator = new SchemaValidator($em, ! $input->getOption('skip-property-types')); | ||
40 | $exit = 0; | ||
41 | |||
42 | $ui->section('Mapping'); | ||
43 | |||
44 | if ($input->getOption('skip-mapping')) { | ||
45 | $ui->text('<comment>[SKIPPED] The mapping was not checked.</comment>'); | ||
46 | } else { | ||
47 | $errors = $validator->validateMapping(); | ||
48 | if ($errors) { | ||
49 | foreach ($errors as $className => $errorMessages) { | ||
50 | $ui->text( | ||
51 | sprintf( | ||
52 | '<error>[FAIL]</error> The entity-class <comment>%s</comment> mapping is invalid:', | ||
53 | $className, | ||
54 | ), | ||
55 | ); | ||
56 | |||
57 | $ui->listing($errorMessages); | ||
58 | $ui->newLine(); | ||
59 | } | ||
60 | |||
61 | ++$exit; | ||
62 | } else { | ||
63 | $ui->success('The mapping files are correct.'); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | $ui->section('Database'); | ||
68 | |||
69 | if ($input->getOption('skip-sync')) { | ||
70 | $ui->text('<comment>[SKIPPED] The database was not checked for synchronicity.</comment>'); | ||
71 | } elseif (! $validator->schemaInSyncWithMetadata()) { | ||
72 | $ui->error('The database schema is not in sync with the current mapping file.'); | ||
73 | |||
74 | if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { | ||
75 | $sqls = $validator->getUpdateSchemaList(); | ||
76 | $ui->comment(sprintf('<info>%d</info> schema diff(s) detected:', count($sqls))); | ||
77 | foreach ($sqls as $sql) { | ||
78 | $ui->text(sprintf(' %s;', $sql)); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | $exit += 2; | ||
83 | } else { | ||
84 | $ui->success('The database schema is in sync with the mapping files.'); | ||
85 | } | ||
86 | |||
87 | return $exit; | ||
88 | } | ||
89 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/ConsoleRunner.php b/vendor/doctrine/orm/src/Tools/Console/ConsoleRunner.php new file mode 100644 index 0000000..0a00483 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/ConsoleRunner.php | |||
@@ -0,0 +1,88 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console; | ||
6 | |||
7 | use Composer\InstalledVersions; | ||
8 | use Doctrine\DBAL\Tools\Console as DBALConsole; | ||
9 | use Doctrine\ORM\Tools\Console\EntityManagerProvider\ConnectionFromManagerProvider; | ||
10 | use OutOfBoundsException; | ||
11 | use Symfony\Component\Console\Application; | ||
12 | use Symfony\Component\Console\Command\Command as SymfonyCommand; | ||
13 | |||
14 | use function assert; | ||
15 | use function class_exists; | ||
16 | |||
17 | /** | ||
18 | * Handles running the Console Tools inside Symfony Console context. | ||
19 | */ | ||
20 | final class ConsoleRunner | ||
21 | { | ||
22 | /** | ||
23 | * Runs console with the given helper set. | ||
24 | * | ||
25 | * @param SymfonyCommand[] $commands | ||
26 | */ | ||
27 | public static function run(EntityManagerProvider $entityManagerProvider, array $commands = []): void | ||
28 | { | ||
29 | $cli = self::createApplication($entityManagerProvider, $commands); | ||
30 | $cli->run(); | ||
31 | } | ||
32 | |||
33 | /** | ||
34 | * Creates a console application with the given helperset and | ||
35 | * optional commands. | ||
36 | * | ||
37 | * @param SymfonyCommand[] $commands | ||
38 | * | ||
39 | * @throws OutOfBoundsException | ||
40 | */ | ||
41 | public static function createApplication( | ||
42 | EntityManagerProvider $entityManagerProvider, | ||
43 | array $commands = [], | ||
44 | ): Application { | ||
45 | $version = InstalledVersions::getVersion('doctrine/orm'); | ||
46 | assert($version !== null); | ||
47 | |||
48 | $cli = new Application('Doctrine Command Line Interface', $version); | ||
49 | $cli->setCatchExceptions(true); | ||
50 | |||
51 | self::addCommands($cli, $entityManagerProvider); | ||
52 | $cli->addCommands($commands); | ||
53 | |||
54 | return $cli; | ||
55 | } | ||
56 | |||
57 | public static function addCommands(Application $cli, EntityManagerProvider $entityManagerProvider): void | ||
58 | { | ||
59 | $connectionProvider = new ConnectionFromManagerProvider($entityManagerProvider); | ||
60 | |||
61 | if (class_exists(DBALConsole\Command\ReservedWordsCommand::class)) { | ||
62 | $cli->add(new DBALConsole\Command\ReservedWordsCommand($connectionProvider)); | ||
63 | } | ||
64 | |||
65 | $cli->addCommands( | ||
66 | [ | ||
67 | // DBAL Commands | ||
68 | new DBALConsole\Command\RunSqlCommand($connectionProvider), | ||
69 | |||
70 | // ORM Commands | ||
71 | new Command\ClearCache\CollectionRegionCommand($entityManagerProvider), | ||
72 | new Command\ClearCache\EntityRegionCommand($entityManagerProvider), | ||
73 | new Command\ClearCache\MetadataCommand($entityManagerProvider), | ||
74 | new Command\ClearCache\QueryCommand($entityManagerProvider), | ||
75 | new Command\ClearCache\QueryRegionCommand($entityManagerProvider), | ||
76 | new Command\ClearCache\ResultCommand($entityManagerProvider), | ||
77 | new Command\SchemaTool\CreateCommand($entityManagerProvider), | ||
78 | new Command\SchemaTool\UpdateCommand($entityManagerProvider), | ||
79 | new Command\SchemaTool\DropCommand($entityManagerProvider), | ||
80 | new Command\GenerateProxiesCommand($entityManagerProvider), | ||
81 | new Command\RunDqlCommand($entityManagerProvider), | ||
82 | new Command\ValidateSchemaCommand($entityManagerProvider), | ||
83 | new Command\InfoCommand($entityManagerProvider), | ||
84 | new Command\MappingDescribeCommand($entityManagerProvider), | ||
85 | ], | ||
86 | ); | ||
87 | } | ||
88 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider.php b/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider.php new file mode 100644 index 0000000..866589b --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider.php | |||
@@ -0,0 +1,14 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console; | ||
6 | |||
7 | use Doctrine\ORM\EntityManagerInterface; | ||
8 | |||
9 | interface EntityManagerProvider | ||
10 | { | ||
11 | public function getDefaultManager(): EntityManagerInterface; | ||
12 | |||
13 | public function getManager(string $name): EntityManagerInterface; | ||
14 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider/ConnectionFromManagerProvider.php b/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider/ConnectionFromManagerProvider.php new file mode 100644 index 0000000..0776601 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider/ConnectionFromManagerProvider.php | |||
@@ -0,0 +1,26 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\EntityManagerProvider; | ||
6 | |||
7 | use Doctrine\DBAL\Connection; | ||
8 | use Doctrine\DBAL\Tools\Console\ConnectionProvider; | ||
9 | use Doctrine\ORM\Tools\Console\EntityManagerProvider; | ||
10 | |||
11 | final class ConnectionFromManagerProvider implements ConnectionProvider | ||
12 | { | ||
13 | public function __construct(private readonly EntityManagerProvider $entityManagerProvider) | ||
14 | { | ||
15 | } | ||
16 | |||
17 | public function getDefaultConnection(): Connection | ||
18 | { | ||
19 | return $this->entityManagerProvider->getDefaultManager()->getConnection(); | ||
20 | } | ||
21 | |||
22 | public function getConnection(string $name): Connection | ||
23 | { | ||
24 | return $this->entityManagerProvider->getManager($name)->getConnection(); | ||
25 | } | ||
26 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider/SingleManagerProvider.php b/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider/SingleManagerProvider.php new file mode 100644 index 0000000..ebe60c9 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider/SingleManagerProvider.php | |||
@@ -0,0 +1,31 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\EntityManagerProvider; | ||
6 | |||
7 | use Doctrine\ORM\EntityManagerInterface; | ||
8 | use Doctrine\ORM\Tools\Console\EntityManagerProvider; | ||
9 | |||
10 | final class SingleManagerProvider implements EntityManagerProvider | ||
11 | { | ||
12 | public function __construct( | ||
13 | private readonly EntityManagerInterface $entityManager, | ||
14 | private readonly string $defaultManagerName = 'default', | ||
15 | ) { | ||
16 | } | ||
17 | |||
18 | public function getDefaultManager(): EntityManagerInterface | ||
19 | { | ||
20 | return $this->entityManager; | ||
21 | } | ||
22 | |||
23 | public function getManager(string $name): EntityManagerInterface | ||
24 | { | ||
25 | if ($name !== $this->defaultManagerName) { | ||
26 | throw UnknownManagerException::unknownManager($name, [$this->defaultManagerName]); | ||
27 | } | ||
28 | |||
29 | return $this->entityManager; | ||
30 | } | ||
31 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider/UnknownManagerException.php b/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider/UnknownManagerException.php new file mode 100644 index 0000000..583d909 --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/EntityManagerProvider/UnknownManagerException.php | |||
@@ -0,0 +1,23 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console\EntityManagerProvider; | ||
6 | |||
7 | use OutOfBoundsException; | ||
8 | |||
9 | use function implode; | ||
10 | use function sprintf; | ||
11 | |||
12 | final class UnknownManagerException extends OutOfBoundsException | ||
13 | { | ||
14 | /** @psalm-param list<string> $knownManagers */ | ||
15 | public static function unknownManager(string $unknownManager, array $knownManagers = []): self | ||
16 | { | ||
17 | return new self(sprintf( | ||
18 | 'Requested unknown entity manager: %s, known managers: %s', | ||
19 | $unknownManager, | ||
20 | implode(', ', $knownManagers), | ||
21 | )); | ||
22 | } | ||
23 | } | ||
diff --git a/vendor/doctrine/orm/src/Tools/Console/MetadataFilter.php b/vendor/doctrine/orm/src/Tools/Console/MetadataFilter.php new file mode 100644 index 0000000..05e248c --- /dev/null +++ b/vendor/doctrine/orm/src/Tools/Console/MetadataFilter.php | |||
@@ -0,0 +1,92 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Doctrine\ORM\Tools\Console; | ||
6 | |||
7 | use ArrayIterator; | ||
8 | use Countable; | ||
9 | use Doctrine\Persistence\Mapping\ClassMetadata; | ||
10 | use FilterIterator; | ||
11 | use RuntimeException; | ||
12 | |||
13 | use function assert; | ||
14 | use function count; | ||
15 | use function iterator_to_array; | ||
16 | use function preg_match; | ||
17 | use function sprintf; | ||
18 | |||
19 | /** | ||
20 | * Used by CLI Tools to restrict entity-based commands to given patterns. | ||
21 | * | ||
22 | * @link www.doctrine-project.com | ||
23 | */ | ||
24 | class MetadataFilter extends FilterIterator implements Countable | ||
25 | { | ||
26 | /** @var mixed[] */ | ||
27 | private array $filter = []; | ||
28 | |||
29 | /** | ||
30 | * Filter Metadatas by one or more filter options. | ||
31 | * | ||
32 | * @param ClassMetadata[] $metadatas | ||
33 | * @param string[]|string $filter | ||
34 | * | ||
35 | * @return ClassMetadata[] | ||
36 | */ | ||
37 | public static function filter(array $metadatas, array|string $filter): array | ||
38 | { | ||
39 | $metadatas = new MetadataFilter(new ArrayIterator($metadatas), $filter); | ||
40 | |||
41 | return iterator_to_array($metadatas); | ||
42 | } | ||
43 | |||
44 | /** @param mixed[]|string $filter */ | ||
45 | public function __construct(ArrayIterator $metadata, array|string $filter) | ||
46 | { | ||
47 | $this->filter = (array) $filter; | ||
48 | |||
49 | parent::__construct($metadata); | ||
50 | } | ||
51 | |||
52 | public function accept(): bool | ||
53 | { | ||
54 | if (count($this->filter) === 0) { | ||
55 | return true; | ||
56 | } | ||
57 | |||
58 | $it = $this->getInnerIterator(); | ||
59 | $metadata = $it->current(); | ||
60 | |||
61 | foreach ($this->filter as $filter) { | ||
62 | $pregResult = preg_match('/' . $filter . '/', $metadata->getName()); | ||
63 | |||
64 | if ($pregResult === false) { | ||
65 | throw new RuntimeException( | ||
66 | sprintf("Error while evaluating regex '/%s/'.", $filter), | ||
67 | ); | ||
68 | } | ||
69 | |||
70 | if ($pregResult) { | ||
71 | return true; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | return false; | ||
76 | } | ||
77 | |||
78 | /** @return ArrayIterator<int, ClassMetadata> */ | ||
79 | public function getInnerIterator(): ArrayIterator | ||
80 | { | ||
81 | $innerIterator = parent::getInnerIterator(); | ||
82 | |||
83 | assert($innerIterator instanceof ArrayIterator); | ||
84 | |||
85 | return $innerIterator; | ||
86 | } | ||
87 | |||
88 | public function count(): int | ||
89 | { | ||
90 | return count($this->getInnerIterator()); | ||
91 | } | ||
92 | } | ||