From b2e839926496d63d0e682f953acc2ba88eaec501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Tue, 13 Aug 2024 16:40:05 +0200 Subject: [PATCH] [DependencyInjection] Fix issue between decorator and service locator index --- .../Compiler/DecoratorServicePass.php | 4 ++++ .../Compiler/PriorityTaggedServiceTrait.php | 3 ++- .../Tests/Compiler/DecoratorServicePassTest.php | 10 +++++----- .../Tests/Compiler/PriorityTaggedServiceTraitTest.php | 4 ++++ .../Tests/Fixtures/config/anonymous.expected.yml | 2 ++ .../Tests/Fixtures/config/child.expected.yml | 2 ++ 6 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index 8ca86c1110fbf..08002d4070cf6 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -120,6 +120,10 @@ public function process(ContainerBuilder $container) $container->setAlias($inner, $id)->setPublic($public); } + + foreach ($decoratingDefinitions as $inner => $definition) { + $definition->addTag('container.decorator', ['id' => $inner]); + } } protected function processValue($value, bool $isRoot = false) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php index 8d27303ee0cc6..21ea304db6bac 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/PriorityTaggedServiceTrait.php @@ -82,7 +82,8 @@ private function findAndSortTaggedServices($tagName, ContainerBuilder $container } elseif (null === $defaultIndex && $defaultPriorityMethod && $class) { $defaultIndex = PriorityTaggedServiceUtil::getDefault($container, $serviceId, $class, $defaultIndexMethod ?? 'getDefaultName', $tagName, $indexAttribute, $checkTaggedItem); } - $index = $index ?? $defaultIndex ?? $defaultIndex = $serviceId; + $decorated = $definition->getTag('container.decorator')[0]['id'] ?? null; + $index = $index ?? $defaultIndex ?? $defaultIndex = $decorated ?? $serviceId; $services[] = [$priority, ++$i, $index, $serviceId, $class]; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php index cac0460841105..8c8a158a76327 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php @@ -198,7 +198,7 @@ public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitio $this->process($container); $this->assertEmpty($container->getDefinition('baz.inner')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('baz')->getTags()); } public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitionMultipleTimes() @@ -221,7 +221,7 @@ public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitio $this->process($container); $this->assertEmpty($container->getDefinition('deco1')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz']], $container->getDefinition('deco2')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('deco2')->getTags()); } public function testProcessLeavesServiceLocatorTagOnOriginalDefinition() @@ -240,7 +240,7 @@ public function testProcessLeavesServiceLocatorTagOnOriginalDefinition() $this->process($container); $this->assertEquals(['container.service_locator' => [0 => []]], $container->getDefinition('baz.inner')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('baz')->getTags()); } public function testProcessLeavesServiceSubscriberTagOnOriginalDefinition() @@ -259,7 +259,7 @@ public function testProcessLeavesServiceSubscriberTagOnOriginalDefinition() $this->process($container); $this->assertEquals(['container.service_subscriber' => [], 'container.service_subscriber.locator' => []], $container->getDefinition('baz.inner')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('baz')->getTags()); } public function testProcessLeavesProxyTagOnOriginalDefinition() @@ -278,7 +278,7 @@ public function testProcessLeavesProxyTagOnOriginalDefinition() $this->process($container); $this->assertEquals(['proxy' => 'foo'], $container->getDefinition('baz.inner')->getTags()); - $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar'], 'container.decorator' => [['id' => 'foo']]], $container->getDefinition('baz')->getTags()); } public function testCannotDecorateSyntheticService() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php index c39d79f9e8772..e65735d4133ed 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/PriorityTaggedServiceTraitTest.php @@ -153,6 +153,9 @@ public function testTheIndexedTagsByDefaultIndexMethod() $container->register('service4', HelloInterface::class)->addTag('my_custom_tag'); + $definition = $container->register('debug.service5', \stdClass::class)->addTag('my_custom_tag'); + $definition->addTag('container.decorator', ['id' => 'service5']); + $priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation(); $tag = new TaggedIteratorArgument('my_custom_tag', 'foo', 'getFooBar'); @@ -161,6 +164,7 @@ public function testTheIndexedTagsByDefaultIndexMethod() 'service1' => new TypedReference('service1', FooTagClass::class), '10' => new TypedReference('service3', IntTagClass::class), 'service4' => new TypedReference('service4', HelloInterface::class), + 'service5' => new TypedReference('debug.service5', \stdClass::class), ]; $services = $priorityTaggedServiceTraitImplementation->test($tag, $container); $this->assertSame(array_keys($expected), array_keys($services)); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/anonymous.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/anonymous.expected.yml index 3dd00ab6f8fe8..9b1213fbcab8e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/anonymous.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/anonymous.expected.yml @@ -15,4 +15,6 @@ services: decorated: class: Symfony\Component\DependencyInjection\Tests\Fixtures\StdClassDecorator public: true + tags: + - container.decorator: { id: decorated } arguments: [!service { class: stdClass }] diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml index d9537a05e4c34..a4e4eb995c4be 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/child.expected.yml @@ -7,6 +7,8 @@ services: foo: class: Class2 public: true + tags: + - container.decorator: { id: bar } file: file.php lazy: true arguments: [!service { class: Class1 }]