Skip to content

Commit

Permalink
bug #50224 [DoctrineBridge] skip subscriber if listener already defin…
Browse files Browse the repository at this point in the history
…ed (alli83)

This PR was merged into the 6.3 branch.

Discussion
----------

[DoctrineBridge] skip subscriber if listener already defined

| Q             | A
| ------------- | ---
| Branch?       | 6.3
| Bug fix?      | no
| New feature?  | no
| Deprecations? |
| Tickets       |
| License       | MIT
| Doc PR        |

Following #49918 and doctrine/DoctrineBundle#1650 skip doctrine event subscriber if a doctrine event listener is already defined for the same definition.

Commits
-------

5a867c5 [DoctrineBridge] skip subscriber if listener already defined
  • Loading branch information
fabpot committed May 5, 2023
2 parents 32dc97a + 5a867c5 commit 218dfaa
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ private function addTaggedServices(ContainerBuilder $container): array
$listenerTag = $this->tagPrefix.'.event_listener';
$subscriberTag = $this->tagPrefix.'.event_subscriber';
$listenerRefs = [];
$taggedServices = $this->findAndSortTags([$subscriberTag, $listenerTag], $container);
$taggedServices = $this->findAndSortTags($subscriberTag, $listenerTag, $container);

$managerDefs = [];
foreach ($taggedServices as $taggedSubscriber) {
Expand Down Expand Up @@ -144,24 +144,26 @@ private function getEventManagerDef(ContainerBuilder $container, string $name):
* @see https://bugs.php.net/53710
* @see https://bugs.php.net/60926
*/
private function findAndSortTags(array $tagNames, ContainerBuilder $container): array
private function findAndSortTags(string $subscriberTag, string $listenerTag, ContainerBuilder $container): array
{
$sortedTags = [];

foreach ($tagNames as $tagName) {
foreach ($container->findTaggedServiceIds($tagName, true) as $serviceId => $tags) {
$taggedIds = [
$subscriberTag => $container->findTaggedServiceIds($subscriberTag, true),
$listenerTag => $container->findTaggedServiceIds($listenerTag, true),
];
$taggedIds[$subscriberTag] = array_diff_key($taggedIds[$subscriberTag], $taggedIds[$listenerTag]);

foreach ($taggedIds as $tagName => $serviceIds) {
foreach ($serviceIds as $serviceId => $tags) {
foreach ($tags as $attributes) {
$priority = $attributes['priority'] ?? 0;
$sortedTags[$priority][] = [$tagName, $serviceId, $attributes];
}
}
}

if ($sortedTags) {
krsort($sortedTags);
$sortedTags = array_merge(...$sortedTags);
}
krsort($sortedTags);

return $sortedTags;
return array_merge(...$sortedTags);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,44 @@ public function testProcessEventSubscribersAndListenersWithPriorities()
);
}

public function testSubscribersAreSkippedIfListenerDefinedForSameDefinition()
{
$container = $this->createBuilder();

$container
->register('a', 'stdClass')
->setPublic(false)
->addTag('doctrine.event_listener', [
'event' => 'bar',
'priority' => 3,
])
;
$container
->register('b', 'stdClass')
->setPublic(false)
->addTag('doctrine.event_listener', [
'event' => 'bar',
])
->addTag('doctrine.event_listener', [
'event' => 'foo',
'priority' => -5,
])
->addTag('doctrine.event_subscriber')
;
$this->process($container);

$eventManagerDef = $container->getDefinition('doctrine.dbal.default_connection.event_manager');

$this->assertEquals(
[
[['bar'], 'a'],
[['bar'], 'b'],
[['foo'], 'b'],
],
$eventManagerDef->getArgument(1)
);
}

public function testProcessNoTaggedServices()
{
$container = $this->createBuilder(true);
Expand Down

0 comments on commit 218dfaa

Please sign in to comment.