diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index ce71235bea2b9..bc610bedd86ff 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -148,10 +148,15 @@ protected function getMappingDriverBundleConfigDefaults(array $bundleConfig, \Re $bundleDir = func_get_arg(3); } - $bundleDir ?? $bundleDir = \dirname($bundle->getFileName()); + $bundleClassDir = \dirname($bundle->getFileName()); + $bundleDir ?? $bundleDir = $bundleClassDir; if (!$bundleConfig['type']) { $bundleConfig['type'] = $this->detectMetadataDriver($bundleDir, $container); + + if (!$bundleConfig['type'] && $bundleDir !== $bundleClassDir) { + $bundleConfig['type'] = $this->detectMetadataDriver($bundleClassDir, $container); + } } if (!$bundleConfig['type']) { @@ -161,7 +166,7 @@ protected function getMappingDriverBundleConfigDefaults(array $bundleConfig, \Re if (!$bundleConfig['dir']) { if (\in_array($bundleConfig['type'], ['annotation', 'staticphp', 'attribute'])) { - $bundleConfig['dir'] = $bundleDir.'/'.$this->getMappingObjectDefaultName(); + $bundleConfig['dir'] = $bundleClassDir.'/'.$this->getMappingObjectDefaultName(); } else { $bundleConfig['dir'] = $bundleDir.'/'.$this->getMappingResourceConfigDirectory($bundleDir); } diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php index b665b242cc496..468a03667f1da 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -16,6 +16,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\HttpKernel\Bundle\BundleInterface; /** * @author Fabio B. Silva @@ -53,6 +54,10 @@ protected function setUp(): void $this->extension ->method('getMappingObjectDefaultName') ->willReturn('Entity'); + + $this->extension + ->method('getMappingResourceExtension') + ->willReturn('orm'); } public function testFixManagersAutoMappingsWithTwoAutomappings() @@ -271,6 +276,75 @@ public function testUnrecognizedCacheDriverException() $this->invokeLoadCacheDriver($objectManager, $container, $cacheName); } + public function providerBundles() + { + yield ['AnnotationsBundle', 'annotation', '/Entity']; + if (\PHP_VERSION_ID >= 80000) { + yield ['AttributesBundle', 'attribute', '/Entity']; + } + yield ['XmlBundle', 'xml', '/Resources/config/doctrine']; + yield ['PhpBundle', 'php', '/Resources/config/doctrine']; + yield ['YamlBundle', 'yml', '/Resources/config/doctrine']; + + yield ['SrcXmlBundle', 'xml', '/Resources/config/doctrine']; + + yield ['NewAnnotationsBundle', 'annotation', '/src/Entity']; + yield ['NewXmlBundle', 'xml', '/config/doctrine']; + } + + /** + * @dataProvider providerBundles + */ + public function testBundleAutoMapping(string $bundle, string $expectedType, string $dirSuffix) + { + $bundleDir = __DIR__.'/../Fixtures/Bundles/'.$bundle; + $bundleClassName = 'Fixtures\\Bundles\\'.$bundle.'\\'.$bundle; + + if (is_dir($bundleDir.'/src')) { + require_once $bundleDir.'/src/'.$bundle.'.php'; + } else { + require_once $bundleDir.'/'.$bundle.'.php'; + } + + /** @var BundleInterface $bundleClass */ + $bundleClass = new $bundleClassName(); + + $mappingConfig = [ + 'dir' => false, + 'type' => false, + 'prefix' => false, + 'mapping' => true, + 'is_bundle' => true, + ]; + + $this->extension + ->method('getMappingResourceConfigDirectory') + ->willReturnCallback(function ($bundleDir) { + if (null !== $bundleDir && is_dir($bundleDir.'/config/doctrine')) { + return 'config/doctrine'; + } + + return 'Resources/config/doctrine'; + }); + + $container = $this->createContainer([], [$bundle => $bundleClassName]); + + $reflection = new \ReflectionClass(\get_class($this->extension)); + $method = $reflection->getMethod('getMappingDriverBundleConfigDefaults'); + $method->setAccessible(true); + + $this->assertSame( + [ + 'dir' => $bundleClass->getPath().$dirSuffix, + 'type' => $expectedType, + 'prefix' => $bundleClass->getNamespace().'\\Entity', + 'mapping' => true, + 'is_bundle' => true, + ], + $method->invoke($this->extension, $mappingConfig, new \ReflectionClass($bundleClass), $container, $bundleClass->getPath()) + ); + } + protected function invokeLoadCacheDriver(array $objectManager, ContainerBuilder $container, $cacheName) { $method = new \ReflectionMethod($this->extension, 'loadObjectManagerCacheDriver'); @@ -280,10 +354,10 @@ protected function invokeLoadCacheDriver(array $objectManager, ContainerBuilder $method->invokeArgs($this->extension, [$objectManager, $container, $cacheName]); } - protected function createContainer(array $data = []): ContainerBuilder + protected function createContainer(array $data = [], array $extraBundles = []): ContainerBuilder { return new ContainerBuilder(new ParameterBag(array_merge([ - 'kernel.bundles' => ['FrameworkBundle' => 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'], + 'kernel.bundles' => array_merge(['FrameworkBundle' => 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'], $extraBundles), 'kernel.cache_dir' => __DIR__, 'kernel.build_dir' => __DIR__, 'kernel.container_class' => 'kernel', diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php new file mode 100644 index 0000000000000..e4dfd3e07cc88 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsBundle/AnnotationsBundle.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\AnnotationsBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class AnnotationsBundle extends Bundle +{ +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsBundle/Entity/Person.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsBundle/Entity/Person.php new file mode 100644 index 0000000000000..0d7cc91362da3 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AnnotationsBundle/Entity/Person.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\AnnotationsBundle\Entity; + +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; + +/** + * @Entity + */ +class Person +{ + /** @Id @Column(type="integer") */ + protected $id; + + /** @Column(type="string") */ + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString(): string + { + return (string) $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AttributesBundle/AttributesBundle.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AttributesBundle/AttributesBundle.php new file mode 100644 index 0000000000000..686dbe4e8f3b2 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AttributesBundle/AttributesBundle.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\AttributesBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class AttributesBundle extends Bundle +{ +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AttributesBundle/Entity/Person.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AttributesBundle/Entity/Person.php new file mode 100644 index 0000000000000..6b445b198457f --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/AttributesBundle/Entity/Person.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\AttributesBundle\Entity; + +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; + +#[Entity] +class Person +{ + #[Id, Column(type: 'integer')] + protected $id; + + #[Column(type: 'string')] + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString(): string + { + return (string) $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewAnnotationsBundle/src/Entity/Person.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewAnnotationsBundle/src/Entity/Person.php new file mode 100644 index 0000000000000..e94a24e1a95c7 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewAnnotationsBundle/src/Entity/Person.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\NewAnnotationsBundle\Entity; + +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; + +/** + * @Entity + */ +class Person +{ + /** @Id @Column(type="integer") */ + protected $id; + + /** @Column(type="string") */ + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString(): string + { + return (string) $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewAnnotationsBundle/src/NewAnnotationsBundle.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewAnnotationsBundle/src/NewAnnotationsBundle.php new file mode 100644 index 0000000000000..962b6d025ebc8 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewAnnotationsBundle/src/NewAnnotationsBundle.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\NewAnnotationsBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class NewAnnotationsBundle extends Bundle +{ + public function getPath(): string + { + return \dirname(__DIR__); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewXmlBundle/config/doctrine/Person.orm.xml b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewXmlBundle/config/doctrine/Person.orm.xml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewXmlBundle/src/Entity/Person.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewXmlBundle/src/Entity/Person.php new file mode 100644 index 0000000000000..3adfa62aa90fe --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewXmlBundle/src/Entity/Person.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\NewXmlBundle\Entity; + +class Person +{ + protected $id; + + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString(): string + { + return (string) $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewXmlBundle/src/NewXmlBundle.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewXmlBundle/src/NewXmlBundle.php new file mode 100644 index 0000000000000..b5abbdb38d45d --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/NewXmlBundle/src/NewXmlBundle.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\NewXmlBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class NewXmlBundle extends Bundle +{ + public function getPath(): string + { + return \dirname(__DIR__); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/PhpBundle/Entity/Person.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/PhpBundle/Entity/Person.php new file mode 100644 index 0000000000000..67937cd3b8bd4 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/PhpBundle/Entity/Person.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\PhpBundle\Entity; + +class Person +{ + protected $id; + + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString(): string + { + return (string) $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/PhpBundle/PhpBundle.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/PhpBundle/PhpBundle.php new file mode 100644 index 0000000000000..0fbd8f34dd644 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/PhpBundle/PhpBundle.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\PhpBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class PhpBundle extends Bundle +{ +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/PhpBundle/Resources/config/doctrine/Person.orm.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/PhpBundle/Resources/config/doctrine/Person.orm.php new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/SrcXmlBundle/src/Entity/Person.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/SrcXmlBundle/src/Entity/Person.php new file mode 100644 index 0000000000000..445d0d4bd01ab --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/SrcXmlBundle/src/Entity/Person.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\SrcXmlBundle\Entity; + +class Person +{ + protected $id; + + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString(): string + { + return (string) $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/SrcXmlBundle/src/Resources/config/doctrine/Person.orm.xml b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/SrcXmlBundle/src/Resources/config/doctrine/Person.orm.xml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/SrcXmlBundle/src/SrcXmlBundle.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/SrcXmlBundle/src/SrcXmlBundle.php new file mode 100644 index 0000000000000..456983db04120 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/SrcXmlBundle/src/SrcXmlBundle.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\SrcXmlBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class SrcXmlBundle extends Bundle +{ +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/XmlBundle/Entity/Person.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/XmlBundle/Entity/Person.php new file mode 100644 index 0000000000000..83c89773e4911 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/XmlBundle/Entity/Person.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\XmlBundle\Entity; + +class Person +{ + protected $id; + + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString(): string + { + return (string) $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/Person.orm.xml b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/XmlBundle/Resources/config/doctrine/Person.orm.xml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/XmlBundle/XmlBundle.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/XmlBundle/XmlBundle.php new file mode 100644 index 0000000000000..6a69bd7583dd2 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/XmlBundle/XmlBundle.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\XmlBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class XmlBundle extends Bundle +{ +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/YamlBundle/Entity/Person.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/YamlBundle/Entity/Person.php new file mode 100644 index 0000000000000..861cf5b652ab2 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/YamlBundle/Entity/Person.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\YamlBundle\Entity; + +class Person +{ + protected $id; + + public $name; + + public function __construct($id, $name) + { + $this->id = $id; + $this->name = $name; + } + + public function __toString(): string + { + return (string) $this->name; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Person.orm.yml b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/YamlBundle/Resources/config/doctrine/Person.orm.yml new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/YamlBundle/YamlBundle.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/YamlBundle/YamlBundle.php new file mode 100644 index 0000000000000..415db47843d9d --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/Bundles/YamlBundle/YamlBundle.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fixtures\Bundles\YamlBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class YamlBundle extends Bundle +{ +}