From 98454f8b44f5a2fdd1dc5b73b935435fe636b30e Mon Sep 17 00:00:00 2001 From: Gert Wijnalda Date: Tue, 26 Oct 2021 17:22:59 +0200 Subject: [PATCH] Determine attribute or annotation type for directories --- .../AbstractDoctrineExtension.php | 58 ++++++++++++------- .../DoctrineExtensionTest.php | 17 ++++++ .../Tests/Fixtures/Attribute/UuidIdEntity.php | 29 ++++++++++ 3 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/Attribute/UuidIdEntity.php diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index b729dfe8f134e..2714e27d754a3 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -89,25 +89,8 @@ protected function loadMappingInformation(array $objectManager, ContainerBuilder if (!$mappingConfig) { continue; } - } elseif (!$mappingConfig['type'] && \PHP_VERSION_ID < 80000) { - $mappingConfig['type'] = 'annotation'; } elseif (!$mappingConfig['type']) { - $mappingConfig['type'] = 'attribute'; - - $glob = new GlobResource($mappingConfig['dir'], '*', true); - $container->addResource($glob); - - foreach ($glob as $file) { - $content = file_get_contents($file); - - if (preg_match('/^#\[.*Entity\b/m', $content)) { - break; - } - if (preg_match('/^ \* @.*Entity\b/m', $content)) { - $mappingConfig['type'] = 'annotation'; - break; - } - } + $mappingConfig['type'] = $this->detectMappingType($mappingConfig['dir'], $container); } $this->assertValidMappingConfiguration($mappingConfig, $objectManager['name']); @@ -259,7 +242,7 @@ protected function assertValidMappingConfiguration(array $mappingConfig, string /** * Detects what metadata driver to use for the supplied directory. * - * @return string|null + * @return string|null A metadata driver short name, if one can be detected */ protected function detectMetadataDriver(string $dir, ContainerBuilder $container) { @@ -280,13 +263,48 @@ protected function detectMetadataDriver(string $dir, ContainerBuilder $container } $container->fileExists($resource, false); - return $container->fileExists($dir.'/'.$this->getMappingObjectDefaultName(), false) ? 'annotation' : null; + if ($container->fileExists($dir.'/'.$this->getMappingObjectDefaultName(), false)) { + return $this->detectMappingType($dir, $container); + } + + return null; } $container->fileExists($dir.'/'.$configPath, false); return $driver; } + /** + * Detects what mapping type to use for the supplied directory. + * + * @return string A mapping type 'attribute' or 'annotation' + */ + private function detectMappingType(string $directory, ContainerBuilder $container): string + { + if (\PHP_VERSION_ID < 80000) { + return 'annotation'; + } + + $type = 'attribute'; + + $glob = new GlobResource($directory, '*', true); + $container->addResource($glob); + + foreach ($glob as $file) { + $content = file_get_contents($file); + + if (preg_match('/^#\[.*Entity\b/m', $content)) { + break; + } + if (preg_match('/^ \* @.*Entity\b/m', $content)) { + $type = 'annotation'; + break; + } + } + + return $type; + } + /** * Loads a configured object manager metadata, query or result cache driver. * diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php index 085a37fbff73f..dc86ee22b640e 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -171,6 +171,23 @@ public function testFixManagersAutoMappings(array $originalEm1, array $originalE ], $expectedEm2)); } + public function testMappingTypeDetection() + { + $container = $this->createContainer(); + + $reflection = new \ReflectionClass(\get_class($this->extension)); + $method = $reflection->getMethod('detectMappingType'); + $method->setAccessible(true); + + // The ordinary fixtures contain annotation + $mappingType = $method->invoke($this->extension, __DIR__.'/../Fixtures', $container); + $this->assertSame($mappingType, 'annotation'); + + // In the attribute folder, attributes are used + $mappingType = $method->invoke($this->extension, __DIR__.'/../Fixtures/Attribute', $container); + $this->assertSame($mappingType, \PHP_VERSION_ID < 80000 ? 'annotation' : 'attribute'); + } + public function providerBasicDrivers() { return [ diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Attribute/UuidIdEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Attribute/UuidIdEntity.php new file mode 100644 index 0000000000000..3d28d4469c1fb --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Attribute/UuidIdEntity.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Fixtures\Attribute; + +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; + +#[Entity] +class UuidIdEntity +{ + #[Id] + #[Column("uuid")] + protected $id; + + public function __construct($id) + { + $this->id = $id; + } +}