From cb2b0717f7163c72996846b41125b4f1a77667b8 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 18 Aug 2022 16:28:13 +0200 Subject: [PATCH] Wire EntityArgumentResolver when available --- DependencyInjection/Configuration.php | 13 ++++++ DependencyInjection/DoctrineExtension.php | 41 +++++++++++++++++++ Resources/config/orm.xml | 8 ++++ .../DoctrineExtensionTest.php | 29 +++++++++++++ psalm.xml.dist | 1 + 5 files changed, 92 insertions(+) diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 5aaa345de..40cdedc9b 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -466,6 +466,19 @@ private function addOrmSection(ArrayNodeDefinition $node): void ->end() ->scalarNode('proxy_dir')->defaultValue('%kernel.cache_dir%/doctrine/orm/Proxies')->end() ->scalarNode('proxy_namespace')->defaultValue('Proxies')->end() + ->arrayNode('controller_resolver') + ->canBeDisabled() + ->children() + ->booleanNode('auto_mapping') + ->defaultTrue() + ->info('Set to false to disable using route placeholders as lookup criteria when the primary key doesn\'t match the argument name') + ->end() + ->booleanNode('evict_cache') + ->info('Set to true to fetch the entity from the database instead of using the cache, if any') + ->defaultFalse() + ->end() + ->end() + ->end() ->end() ->fixXmlConfig('entity_manager') ->append($this->getOrmEntityManagersNode()) diff --git a/DependencyInjection/DoctrineExtension.php b/DependencyInjection/DoctrineExtension.php index e06b6e9f0..a24926e27 100644 --- a/DependencyInjection/DoctrineExtension.php +++ b/DependencyInjection/DoctrineExtension.php @@ -30,6 +30,8 @@ use Doctrine\ORM\UnitOfWork; use LogicException; use ReflectionMethod; +use Symfony\Bridge\Doctrine\ArgumentResolver\EntityValueResolver; +use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension; use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator; use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator; @@ -52,6 +54,7 @@ use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Symfony\Component\Form\AbstractType; use Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransportFactory; use Symfony\Component\Messenger\MessageBusInterface; @@ -527,6 +530,44 @@ protected function ormLoad(array $config, ContainerBuilder $container) $container->removeDefinition('doctrine.uuid_generator'); } + // available in Symfony 6.2 and higher + if (! class_exists(EntityValueResolver::class)) { + $container->removeDefinition('doctrine.orm.entity_value_resolvers'); + $container->removeDefinition('doctrine.orm.entity_value_resolver.expression_language'); + } else { + if (! class_exists(ExpressionLanguage::class)) { + $container->removeDefinition('doctrine.orm.entity_value_resolver.expression_language'); + } + + $controllerResolverDefaults = []; + + if (! $config['controller_resolver']['enabled']) { + $controllerResolverDefaults['disabled'] = true; + } + + if (! $config['controller_resolver']['auto_mapping']) { + $controllerResolverDefaults['mapping'] = []; + } + + if ($config['controller_resolver']['evict_cache']) { + $controllerResolverDefaults['evict_cache'] = true; + } + + if ($controllerResolverDefaults) { + $container->getDefinition('doctrine.orm.entity_value_resolver')->setArgument(2, (new Definition(MapEntity::class))->setArguments([ + null, + null, + null, + $controllerResolverDefaults['mapping'] ?? null, + null, + null, + null, + $controllerResolverDefaults['evict_cache'] ?? null, + $controllerResolverDefaults['disabled'] ?? false, + ])); + } + } + // not available in Doctrine ORM 3.0 and higher if (! class_exists(ConvertMappingCommand::class)) { $container->removeDefinition('doctrine.mapping_convert_command'); diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml index af7572511..417c18959 100644 --- a/Resources/config/orm.xml +++ b/Resources/config/orm.xml @@ -172,6 +172,14 @@ + + + + + + + + diff --git a/Tests/DependencyInjection/DoctrineExtensionTest.php b/Tests/DependencyInjection/DoctrineExtensionTest.php index 31a0ea4f0..921b3ebdc 100644 --- a/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -39,6 +39,7 @@ use PHPUnit\Framework\TestCase; use ReflectionClass; use ReflectionMethod; +use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Bridge\Doctrine\Messenger\DoctrineClearEntityManagerWorkerSubscriber; use Symfony\Bridge\Doctrine\Middleware\Debug\DebugDataHolder; use Symfony\Bridge\Doctrine\Middleware\Debug\Middleware as SfDebugMiddleware; @@ -1564,6 +1565,34 @@ public function testDefinitionsToLogQueriesLoggingFalse(): void $this->assertArrayNotHasKey('doctrine.middleware', $abstractMiddlewareDefTags); } + /** + * @requires function \Symfony\Bridge\Doctrine\ArgumentResolver\EntityValueResolver::__construct + */ + public function testControllerResolver(): void + { + $container = $this->getContainer(); + $extension = new DoctrineExtension(); + $config = BundleConfigurationBuilder::createBuilderWithBaseValues()->build(); + $extension->load([$config], $container); + + $controllerResolver = $container->getDefinition('doctrine.orm.entity_value_resolver'); + + $this->assertEquals([new Reference('doctrine'), new Reference('doctrine.orm.entity_value_resolver.expression_language', $container::IGNORE_ON_INVALID_REFERENCE)], $controllerResolver->getArguments()); + + $container = $this->getContainer(); + + $config['orm']['controller_resolver'] = [ + 'enabled' => false, + 'auto_mapping' => false, + 'evict_cache' => true, + ]; + $extension->load([$config], $container); + + $container->setDefinition('controller_resolver_defaults', $container->getDefinition('doctrine.orm.entity_value_resolver')->getArgument(2))->setPublic(true); + $container->compile(); + $this->assertEquals(new MapEntity(null, null, null, [], null, null, null, true, true), $container->get('controller_resolver_defaults')); + } + // phpcs:enable /** @param list $bundles */ diff --git a/psalm.xml.dist b/psalm.xml.dist index 0bbaae0e7..3d7260911 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -43,6 +43,7 @@ +