From f60ba96374e5c7961dd0065ee9d957abfe179007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Mon, 3 Feb 2020 22:21:33 +0100 Subject: [PATCH] Add priority support for tagged entity listeners --- .../Compiler/EntityListenerPass.php | 14 +++++++------- .../AbstractDoctrineExtensionTest.php | 16 ++++++++-------- .../xml/orm_attach_entity_listener_tag.xml | 2 +- ...ract.xml => orm_entity_listener_abstract.xml} | 2 +- .../yml/orm_attach_entity_listener_tag.yml | 2 +- ...ract.yml => orm_entity_listener_abstract.yml} | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) rename Tests/DependencyInjection/Fixtures/config/xml/{orm_entity_listener_lazy_abstract.xml => orm_entity_listener_abstract.xml} (93%) rename Tests/DependencyInjection/Fixtures/config/yml/{orm_entity_listener_lazy_abstract.yml => orm_entity_listener_abstract.yml} (82%) diff --git a/DependencyInjection/Compiler/EntityListenerPass.php b/DependencyInjection/Compiler/EntityListenerPass.php index 39d7964dc..70ee9db7e 100644 --- a/DependencyInjection/Compiler/EntityListenerPass.php +++ b/DependencyInjection/Compiler/EntityListenerPass.php @@ -6,6 +6,7 @@ use Doctrine\Bundle\DoctrineBundle\Mapping\EntityListenerServiceResolver; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -17,17 +18,20 @@ */ class EntityListenerPass implements CompilerPassInterface { + use PriorityTaggedServiceTrait; + /** * {@inheritDoc} */ public function process(ContainerBuilder $container) { - $resolvers = $container->findTaggedServiceIds('doctrine.orm.entity_listener'); + $resolvers = $this->findAndSortTaggedServices('doctrine.orm.entity_listener', $container); $lazyServiceReferencesByResolver = []; - foreach ($resolvers as $id => $tagAttributes) { - foreach ($tagAttributes as $attributes) { + foreach ($resolvers as $reference) { + $id = $reference->__toString(); + foreach ($container->getDefinition($id)->getTag('doctrine.orm.entity_listener') as $attributes) { $name = isset($attributes['entity_manager']) ? $attributes['entity_manager'] : $container->getParameter('doctrine.default_entity_manager'); $entityManager = sprintf('doctrine.orm.%s_entity_manager', $name); @@ -62,10 +66,6 @@ public function process(ContainerBuilder $container) if (! isset($attributes['lazy']) && $resolverSupportsLazyListeners || $lazyByAttribute) { $listener = $container->findDefinition($id); - if ($listener->isAbstract()) { - throw new InvalidArgumentException(sprintf('The service "%s" must not be abstract as this entity listener is lazy-loaded.', $id)); - } - $resolver->addMethodCall('registerService', [$this->getConcreteDefinitionClass($listener, $container, $id), $id]); // if the resolver uses the default class we will use a service locator for all listeners diff --git a/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php b/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php index 8c0ddf09e..7dae52123 100644 --- a/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php +++ b/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php @@ -881,20 +881,20 @@ public function testAttachEntityListenerTag() : void $listener = $container->getDefinition('doctrine.orm.em1_entity_listener_resolver'); $this->assertDICDefinitionMethodCallCount($listener, 'registerService', [ + ['ParentEntityListener', 'children_entity_listener'], ['EntityListener1', 'entity_listener1'], ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'], ['Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'invokable_entity_listener'], - ['ParentEntityListener', 'children_entity_listener'], ], 4); $listener = $container->getDefinition('doctrine.orm.em2_entity_listener_resolver'); $this->assertDICDefinitionMethodCallOnce($listener, 'registerService', ['EntityListener2', 'entity_listener2']); $attachListener = $container->getDefinition('doctrine.orm.em1_listeners.attach_entity_listeners'); - $this->assertDICDefinitionMethodCallAt(0, $attachListener, 'addEntityListener', ['My/Entity1', 'EntityListener1', 'postLoad']); - $this->assertDICDefinitionMethodCallAt(1, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'loadClassMetadata', '__invoke']); - $this->assertDICDefinitionMethodCallAt(2, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'postPersist']); - $this->assertDICDefinitionMethodCallAt(3, $attachListener, 'addEntityListener', ['My/Entity3', 'ParentEntityListener', 'postLoad']); + $this->assertDICDefinitionMethodCallAt(1, $attachListener, 'addEntityListener', ['My/Entity1', 'EntityListener1', 'postLoad']); + $this->assertDICDefinitionMethodCallAt(2, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'loadClassMetadata', '__invoke']); + $this->assertDICDefinitionMethodCallAt(3, $attachListener, 'addEntityListener', ['My/Entity1', 'Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\InvokableEntityListener', 'postPersist']); + $this->assertDICDefinitionMethodCallAt(0, $attachListener, 'addEntityListener', ['My/Entity3', 'ParentEntityListener', 'postLoad']); $attachListener = $container->getDefinition('doctrine.orm.em2_listeners.attach_entity_listeners'); $this->assertDICDefinitionMethodCallOnce($attachListener, 'addEntityListener', ['My/Entity2', 'EntityListener2', 'preFlush', 'preFlushHandler']); @@ -997,16 +997,16 @@ public function testPrivateLazyEntityListener() : void /** * @expectedException \InvalidArgumentException - * @expectedExceptionMessageRegExp /The service ".*" must not be abstract as this entity listener is lazy-loaded/ + * @expectedExceptionMessageRegExp /The service ".*" must not be abstract\./ */ - public function testAbstractLazyEntityListener() : void + public function testAbstractEntityListener() : void { $container = $this->getContainer([]); $loader = new DoctrineExtension(); $container->registerExtension($loader); $container->addCompilerPass(new EntityListenerPass()); - $this->loadFromFile($container, 'orm_entity_listener_lazy_abstract'); + $this->loadFromFile($container, 'orm_entity_listener_abstract'); $this->compileContainer($container); } diff --git a/Tests/DependencyInjection/Fixtures/config/xml/orm_attach_entity_listener_tag.xml b/Tests/DependencyInjection/Fixtures/config/xml/orm_attach_entity_listener_tag.xml index 16fc5cc5d..0c38446a1 100644 --- a/Tests/DependencyInjection/Fixtures/config/xml/orm_attach_entity_listener_tag.xml +++ b/Tests/DependencyInjection/Fixtures/config/xml/orm_attach_entity_listener_tag.xml @@ -25,7 +25,7 @@ - + diff --git a/Tests/DependencyInjection/Fixtures/config/xml/orm_entity_listener_lazy_abstract.xml b/Tests/DependencyInjection/Fixtures/config/xml/orm_entity_listener_abstract.xml similarity index 93% rename from Tests/DependencyInjection/Fixtures/config/xml/orm_entity_listener_lazy_abstract.xml rename to Tests/DependencyInjection/Fixtures/config/xml/orm_entity_listener_abstract.xml index 661dd5349..823296081 100644 --- a/Tests/DependencyInjection/Fixtures/config/xml/orm_entity_listener_lazy_abstract.xml +++ b/Tests/DependencyInjection/Fixtures/config/xml/orm_entity_listener_abstract.xml @@ -8,7 +8,7 @@ - + diff --git a/Tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listener_tag.yml b/Tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listener_tag.yml index d3d4b5197..480ccca30 100644 --- a/Tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listener_tag.yml +++ b/Tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listener_tag.yml @@ -25,7 +25,7 @@ services: children_entity_listener: parent: parent_entity_listener tags: - - { name: doctrine.orm.entity_listener, entity: My/Entity3, event: postLoad } + - { name: doctrine.orm.entity_listener, entity: My/Entity3, event: postLoad, priority: 1 } doctrine: dbal: diff --git a/Tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_lazy_abstract.yml b/Tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_abstract.yml similarity index 82% rename from Tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_lazy_abstract.yml rename to Tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_abstract.yml index eb46e0359..c9d330e33 100644 --- a/Tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_lazy_abstract.yml +++ b/Tests/DependencyInjection/Fixtures/config/yml/orm_entity_listener_abstract.yml @@ -3,7 +3,7 @@ services: abstract: true class: EntityListener tags: - - { name: doctrine.orm.entity_listener, lazy: true } + - { name: doctrine.orm.entity_listener } doctrine: dbal: