From cda7d7fdd05bf29b6bdf5d58457b1bcf22b1d195 Mon Sep 17 00:00:00 2001 From: Soha Jin Date: Sat, 3 Sep 2022 02:05:50 +0800 Subject: [PATCH] [DependencyInjection] Fix PriorityTaggedServiceTrait for `AsTaggedItem` If `$tagName` is string, `$defaultPriorityMethod` will be null, and `PriorityTaggedServiceUtil::getDefault` won't work for tagged services. This will cause `AsTaggedItem` not working for these tag names. --- .../Compiler/PriorityTaggedServiceTrait.php | 15 ++++++++------- .../Compiler/PriorityTaggedServiceTraitTest.php | 16 ++++++++++++++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php index 8c4d841f5a1f8..c9cc5be2eb3c2 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php @@ -62,25 +62,26 @@ private function findAndSortTaggedServices($tagName, ContainerBuilder $container $class = $container->getParameterBag()->resolveValue($class) ?: null; $checkTaggedItem = !$definition->hasTag(80000 <= \PHP_VERSION_ID && $definition->isAutoconfigured() ? 'container.ignore_attributes' : $tagName); + if ($class) { + $defaultPriority = PriorityTaggedServiceUtil::getDefault($container, $serviceId, $class, $defaultPriorityMethod, $tagName, 'priority', $checkTaggedItem); + $defaultIndex = PriorityTaggedServiceUtil::getDefault($container, $serviceId, $class, $defaultIndexMethod ?? 'getDefaultName', $tagName, $indexAttribute, $checkTaggedItem); + } + foreach ($attributes as $attribute) { $index = $priority = null; if (isset($attribute['priority'])) { $priority = $attribute['priority']; - } elseif (null === $defaultPriority && $defaultPriorityMethod && $class) { - $defaultPriority = PriorityTaggedServiceUtil::getDefault($container, $serviceId, $class, $defaultPriorityMethod, $tagName, 'priority', $checkTaggedItem); } $priority = $priority ?? $defaultPriority ?? $defaultPriority = 0; - if (null === $indexAttribute && !$defaultIndexMethod && !$needsIndexes) { + if (null === $indexAttribute && null === $defaultIndex && !$needsIndexes) { $services[] = [$priority, ++$i, null, $serviceId, null]; continue 2; } if (null !== $indexAttribute && isset($attribute[$indexAttribute])) { $index = $attribute[$indexAttribute]; - } elseif (null === $defaultIndex && $defaultPriorityMethod && $class) { - $defaultIndex = PriorityTaggedServiceUtil::getDefault($container, $serviceId, $class, $defaultIndexMethod ?? 'getDefaultName', $tagName, $indexAttribute, $checkTaggedItem); } $index = $index ?? $defaultIndex ?? $defaultIndex = $serviceId; @@ -119,13 +120,13 @@ class PriorityTaggedServiceUtil /** * @return string|int|null */ - public static function getDefault(ContainerBuilder $container, string $serviceId, string $class, string $defaultMethod, string $tagName, ?string $indexAttribute, bool $checkTaggedItem) + public static function getDefault(ContainerBuilder $container, string $serviceId, string $class, ?string $defaultMethod, string $tagName, ?string $indexAttribute, bool $checkTaggedItem) { if (!($r = $container->getReflectionClass($class)) || (!$checkTaggedItem && !$r->hasMethod($defaultMethod))) { return null; } - if ($checkTaggedItem && !$r->hasMethod($defaultMethod)) { + if ($checkTaggedItem && (!$defaultMethod || !$r->hasMethod($defaultMethod))) { foreach ($r->getAttributes(AsTaggedItem::class) as $attribute) { return 'priority' === $indexAttribute ? $attribute->newInstance()->priority : $attribute->newInstance()->index; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php index 4f4b2a69468af..6ea0892774d0e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php @@ -214,14 +214,26 @@ public function testTaggedItemAttributes() $priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation(); $tag = new TaggedIteratorArgument('my_custom_tag', 'foo', 'getFooBar'); + + // Test TaggedIteratorArgument + $services = $priorityTaggedServiceTraitImplementation->test($tag, $container); $expected = [ 'service3' => new TypedReference('service3', HelloNamedService2::class), 'hello' => new TypedReference('service2', HelloNamedService::class), 'service1' => new TypedReference('service1', FooTagClass::class), ]; - $services = $priorityTaggedServiceTraitImplementation->test($tag, $container); $this->assertSame(array_keys($expected), array_keys($services)); - $this->assertEquals($expected, $priorityTaggedServiceTraitImplementation->test($tag, $container)); + $this->assertEquals($expected, $services); + + // Test string + $services = $priorityTaggedServiceTraitImplementation->test($tag->getTag(), $container); + $expected = [ + 0 => new Reference('service3'), + 'hello' => new TypedReference('service2', HelloNamedService::class), + 1 => new Reference('service1'), + ]; + $this->assertSame(array_keys($expected), array_keys($services)); + $this->assertEquals($expected, $services); } }