Skip to content

Commit

Permalink
Fix wiring of PHP metadata drivers on doctrine/orm 3.x (#1832)
Browse files Browse the repository at this point in the history
  • Loading branch information
MatTheCat authored Nov 6, 2024
1 parent 7bfb8e8 commit eda148b
Show file tree
Hide file tree
Showing 11 changed files with 53 additions and 94 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"symfony/console": "^5.4 || ^6.0 || ^7.0",
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
"symfony/deprecation-contracts": "^2.1 || ^3",
"symfony/doctrine-bridge": "^5.4.19 || ^6.0.7 || ^7.0",
"symfony/doctrine-bridge": "^5.4.46 || ^6.4.3 || ^7.0.3",
"symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0",
"symfony/polyfill-php80": "^1.15",
"symfony/service-contracts": "^1.1.1 || ^2.0 || ^3"
Expand Down
2 changes: 2 additions & 0 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
<referencedClass name="Doctrine\ORM\Mapping\Driver\YamlDriver"/>
<referencedClass name="Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver"/>
<referencedClass name="Doctrine\ORM\Mapping\Driver\AnnotationDriver"/>
<referencedClass name="Doctrine\ORM\Mapping\Driver\PHPDriver"/>
<referencedClass name="Doctrine\ORM\Mapping\Driver\StaticPHPDriver"/>
<referencedClass name="Doctrine\ORM\ORMException"/>
<!-- Dropped in DBAL 4 -->
<referencedClass name="Doctrine\DBAL\Exception"/>
Expand Down
38 changes: 37 additions & 1 deletion src/DependencyInjection/DoctrineExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,21 @@
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Events;
use Doctrine\ORM\Id\AbstractIdGenerator;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\ORM\Mapping\Driver\PHPDriver as LegacyPHPDriver;
use Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver;
use Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver;
use Doctrine\ORM\Mapping\Driver\StaticPHPDriver as LegacyStaticPHPDriver;
use Doctrine\ORM\Proxy\Autoloader;
use Doctrine\ORM\Proxy\ProxyFactory;
use Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand;
use Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand;
use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\Persistence\Mapping\Driver\PHPDriver;
use Doctrine\Persistence\Mapping\Driver\StaticPHPDriver;
use Doctrine\Persistence\Reflection\RuntimeReflectionProperty;
use InvalidArgumentException;
use LogicException;
Expand Down Expand Up @@ -1163,7 +1171,35 @@ public function getConfiguration(array $config, ContainerBuilder $container): Co

protected function getMetadataDriverClass(string $driverType): string
{
return '%' . $this->getObjectManagerElementName('metadata.' . $driverType . '.class') . '%';
switch ($driverType) {
case 'driver_chain':
return MappingDriverChain::class;

case 'annotation':
if (! class_exists(AnnotationDriver::class)) {
throw new LogicException('The annotation driver is only available in doctrine/orm v2.');
}

return AnnotationDriver::class;

case 'xml':
return SimplifiedXmlDriver::class;

case 'yml':
return SimplifiedYamlDriver::class;

case 'php':
return class_exists(PHPDriver::class) ? PHPDriver::class : LegacyPHPDriver::class;

case 'staticphp':
return class_exists(StaticPHPDriver::class) ? StaticPHPDriver::class : LegacyStaticPHPDriver::class;

case 'attribute':
return AttributeDriver::class;

default:
throw new LogicException(sprintf('Unknown "%s" metadata driver type.', $driverType));
}
}

private function loadMessengerServices(ContainerBuilder $container): void
Expand Down
50 changes: 10 additions & 40 deletions tests/DependencyInjection/AbstractDoctrineExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,11 @@
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Security\Core\User\UserInterface;

use function array_filter;
use function array_intersect_key;
use function array_keys;
use function array_merge;
use function array_values;
use function assert;
use function class_exists;
Expand All @@ -57,7 +55,6 @@
use function sprintf;
use function sys_get_temp_dir;
use function uniqid;
use function version_compare;

use const DIRECTORY_SEPARATOR;

Expand Down Expand Up @@ -543,40 +540,30 @@ public function testSingleEntityManagerMultipleMappingBundleDefinitions(): void
self::markTestSkipped('This test requires ORM');
}

$container = $this->loadContainer('orm_single_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle', 'AttributesBundle']);
$container = $this->loadContainer('orm_single_em_bundle_mappings', ['YamlBundle', 'XmlBundle', 'AttributesBundle']);

$definition = $container->getDefinition('doctrine.orm.default_metadata_driver');

$this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
new Reference(version_compare(Kernel::VERSION, '7.0.0', '<') ? 'doctrine.orm.default_annotation_metadata_driver' : 'doctrine.orm.default_attribute_metadata_driver'),
'Fixtures\Bundles\AnnotationsBundle\Entity',
]);

$this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
new Reference('doctrine.orm.default_attribute_metadata_driver'),
'Fixtures\Bundles\AttributesBundle\Entity',
]);

$this->assertDICDefinitionMethodCallAt(2, $definition, 'addDriver', [
$this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
new Reference('doctrine.orm.default_yml_metadata_driver'),
'Fixtures\Bundles\YamlBundle\Entity',
]);

$this->assertDICDefinitionMethodCallAt(3, $definition, 'addDriver', [
$this->assertDICDefinitionMethodCallAt(2, $definition, 'addDriver', [
new Reference('doctrine.orm.default_xml_metadata_driver'),
'Fixtures\Bundles\XmlBundle',
]);

$attrDef = $container->getDefinition('doctrine.orm.default_attribute_metadata_driver');
$this->assertDICConstructorArguments($attrDef, [
array_merge(
! version_compare(Kernel::VERSION, '7.0.0', '<') ? [
__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity',
] : [],
[
__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AttributesBundle' . DIRECTORY_SEPARATOR . 'Entity',
],
),
[
__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AttributesBundle' . DIRECTORY_SEPARATOR . 'Entity',
],
! class_exists(AnnotationDriver::class),
]);

Expand All @@ -600,21 +587,15 @@ public function testMultipleEntityManagersMappingBundleDefinitions(): void
self::markTestSkipped('This test requires ORM');
}

$container = $this->loadContainer('orm_multiple_em_bundle_mappings', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle', 'AttributesBundle']);
$container = $this->loadContainer('orm_multiple_em_bundle_mappings', ['YamlBundle', 'XmlBundle', 'AttributesBundle']);

$this->assertEquals(['em1' => 'doctrine.orm.em1_entity_manager', 'em2' => 'doctrine.orm.em2_entity_manager'], $container->getParameter('doctrine.entity_managers'), 'Set of the existing EntityManagers names is incorrect.');
$this->assertEquals('%doctrine.entity_managers%', $container->getDefinition('doctrine')->getArgument(2), 'Set of the existing EntityManagers names is incorrect.');

$def1 = $container->getDefinition('doctrine.orm.em1_metadata_driver');
$def2 = $container->getDefinition('doctrine.orm.em2_metadata_driver');
$def1Id = version_compare(Kernel::VERSION, '7.0.0', '<') ? 'doctrine.orm.em1_annotation_metadata_driver' : 'doctrine.orm.em1_attribute_metadata_driver';
$def1 = $container->getDefinition('doctrine.orm.em1_metadata_driver');
$def2 = $container->getDefinition('doctrine.orm.em2_metadata_driver');

$this->assertDICDefinitionMethodCallAt(0, $def1, 'addDriver', [
new Reference($def1Id),
'Fixtures\Bundles\AnnotationsBundle\Entity',
]);

$this->assertDICDefinitionMethodCallAt(1, $def1, 'addDriver', [
new Reference('doctrine.orm.em1_attribute_metadata_driver'),
'Fixtures\Bundles\AttributesBundle\Entity',
]);
Expand All @@ -629,17 +610,6 @@ public function testMultipleEntityManagersMappingBundleDefinitions(): void
'Fixtures\Bundles\XmlBundle',
]);

if (version_compare(Kernel::VERSION, '7.0.0', '<')) {
$annDef = $container->getDefinition($def1Id);
$this->assertDICConstructorArguments($annDef, [
new Reference('doctrine.orm.metadata.annotation_reader'),
[
__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'AnnotationsBundle' . DIRECTORY_SEPARATOR . 'Entity',
],
! class_exists(AnnotationDriver::class),
]);
}

$ymlDef = $container->getDefinition('doctrine.orm.em2_yml_metadata_driver');
$this->assertDICConstructorArguments($ymlDef, [
[__DIR__ . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR . 'Bundles' . DIRECTORY_SEPARATOR . 'YamlBundle' . DIRECTORY_SEPARATOR . 'Resources' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'doctrine' => 'Fixtures\Bundles\YamlBundle\Entity'],
Expand All @@ -659,7 +629,7 @@ public function testSingleEntityManagerDefaultTableOptions(): void
self::markTestSkipped('This test requires ORM');
}

$container = $this->loadContainer('orm_single_em_default_table_options', ['YamlBundle', 'AnnotationsBundle', 'XmlBundle', 'AttributesBundle']);
$container = $this->loadContainer('orm_single_em_default_table_options', ['YamlBundle', 'XmlBundle', 'AttributesBundle']);

$param = $container->getDefinition('doctrine.dbal.default_connection')->getArgument(0);

Expand Down
49 changes: 3 additions & 46 deletions tests/DependencyInjection/DoctrineExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransportFactory;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;

use function array_values;
use function class_exists;
Expand Down Expand Up @@ -823,39 +822,6 @@ public function testXmlBundleMappingDetection(): void
]);
}

public function testAnnotationsBundleMappingDetection(): void
{
if (! interface_exists(EntityManagerInterface::class)) {
self::markTestSkipped('This test requires ORM');
}

$container = $this->getContainer(['AnnotationsBundle']);
$extension = new DoctrineExtension();

$config = BundleConfigurationBuilder::createBuilder()
->addBaseConnection()
->addEntityManager([
'default_entity_manager' => 'default',
'entity_managers' => [
'default' => [
'mappings' => [
'AnnotationsBundle' => [],
],
],
],
])
->build();
$extension->load([$config], $container);

$definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
$this->assertDICDefinitionMethodCallOnce($definition, 'addDriver', [
new Reference(class_exists(AnnotationLoader::class)
? 'doctrine.orm.default_annotation_metadata_driver'
: 'doctrine.orm.default_attribute_metadata_driver'),
'Fixtures\Bundles\AnnotationsBundle\Entity',
]);
}

/** @requires PHP 8 */
public function testAttributesBundleMappingDetection(): void
{
Expand Down Expand Up @@ -898,7 +864,7 @@ public function testOrmMergeConfigs(): void
self::markTestSkipped('This test requires ORM');
}

$container = $this->getContainer(['XmlBundle', 'AnnotationsBundle', 'AttributesBundle']);
$container = $this->getContainer(['XmlBundle', 'AttributesBundle']);
$extension = new DoctrineExtension();

$config1 = BundleConfigurationBuilder::createBuilder()
Expand All @@ -908,10 +874,7 @@ public function testOrmMergeConfigs(): void
'default_entity_manager' => 'default',
'entity_managers' => [
'default' => [
'mappings' => [
'AnnotationsBundle' => [],
'AttributesBundle' => ['type' => 'attribute'],
],
'mappings' => ['AttributesBundle' => ['type' => 'attribute']],
],
],
])
Expand All @@ -934,16 +897,10 @@ public function testOrmMergeConfigs(): void

$definition = $container->getDefinition('doctrine.orm.default_metadata_driver');
$this->assertDICDefinitionMethodCallAt(0, $definition, 'addDriver', [
new Reference(class_exists(AnnotationLoader::class)
? 'doctrine.orm.default_annotation_metadata_driver'
: 'doctrine.orm.default_attribute_metadata_driver'),
'Fixtures\Bundles\AnnotationsBundle\Entity',
]);
$this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
new Reference('doctrine.orm.default_attribute_metadata_driver'),
'Fixtures\Bundles\AttributesBundle\Entity',
]);
$this->assertDICDefinitionMethodCallAt(2, $definition, 'addDriver', [
$this->assertDICDefinitionMethodCallAt(1, $definition, 'addDriver', [
new Reference('doctrine.orm.default_xml_metadata_driver'),
'Fixtures\Bundles\XmlBundle\Entity',
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

<orm default-entity-manager="em2">
<entity-manager name="em1">
<mapping name="AnnotationsBundle" />
<mapping name="AttributesBundle" type="attribute" />
</entity-manager>
<entity-manager name="em2" validate-xml-mapping="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
</dbal>

<orm validate-xml-mapping="true">
<mapping name="AnnotationsBundle" />
<mapping name="AttributesBundle" type="attribute" />
<mapping name="YamlBundle" dir="Resources/config/doctrine" alias="yml" />
<mapping name="manual" type="xml" prefix="Fixtures\Bundles\XmlBundle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
</dbal>

<orm>
<mapping name="AnnotationsBundle" />
<mapping name="AttributesBundle" type="attribute" />
<mapping name="YamlBundle" dir="Resources/config/doctrine" alias="yml" />
<mapping name="manual" type="xml" prefix="Fixtures\Bundles\XmlBundle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ doctrine:
entity_managers:
em1:
mappings:
AnnotationsBundle: ~
AttributesBundle:
type: attribute
em2:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ doctrine:
orm:
validate_xml_mapping: true
mappings:
AnnotationsBundle: ~
AttributesBundle:
type: attribute
YamlBundle:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ doctrine:

orm:
mappings:
AnnotationsBundle: ~
AttributesBundle: ~
YamlBundle:
dir: Resources/config/doctrine
Expand Down

0 comments on commit eda148b

Please sign in to comment.