Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add priority support for tagged entity listeners #1135

Merged
merged 1 commit into from Feb 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 7 additions & 7 deletions DependencyInjection/Compiler/EntityListenerPass.php
Expand Up @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -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));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is done from within findAndSortTaggedServices now, so no need for it here anymore

}

$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
Expand Down
16 changes: 8 additions & 8 deletions Tests/DependencyInjection/AbstractDoctrineExtensionTest.php
Expand Up @@ -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']);
Expand Down Expand Up @@ -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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a BC break, merely misleading test case. It DID throw even for non-lazy abstract listeners before.

{
$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);
}
Expand Down
Expand Up @@ -25,7 +25,7 @@
<service id="parent_entity_listener" class="ParentEntityListener" />

<service id="children_entity_listener" parent="parent_entity_listener">
<tag name="doctrine.orm.entity_listener" entity="My/Entity3" event="postLoad" />
<tag name="doctrine.orm.entity_listener" entity="My/Entity3" event="postLoad" priority="1" />
</service>
</services>

Expand Down
Expand Up @@ -8,7 +8,7 @@

<services>
<service id="entity_listener1" class="EntityListener" abstract="true">
<tag name="doctrine.orm.entity_listener" lazy="true" />
<tag name="doctrine.orm.entity_listener" />
</service>
</services>

Expand Down
Expand Up @@ -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:
Expand Down
Expand Up @@ -3,7 +3,7 @@ services:
abstract: true
class: EntityListener
tags:
- { name: doctrine.orm.entity_listener, lazy: true }
- { name: doctrine.orm.entity_listener }

doctrine:
dbal:
Expand Down