diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php index f49e8cf949..e65b7b331e 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php @@ -64,8 +64,18 @@ class DecoratorServicePass implements CompilerPassInterface if (isset($decoratingDefinitions[$inner])) { $decoratingDefinition = $decoratingDefinitions[$inner]; - $definition->setTags(array_merge($decoratingDefinition->getTags(), $definition->getTags())); - $decoratingDefinition->setTags([]); + + $decoratingTags = $decoratingDefinition->getTags(); + $resetTags = []; + + if (isset($decoratingTags['container.service_locator'])) { + // container.service_locator has special logic and it must not be transferred out to decorators + $resetTags = ['container.service_locator' => $decoratingTags['container.service_locator']]; + unset($decoratingTags['container.service_locator']); + } + + $definition->setTags(array_merge($decoratingTags, $definition->getTags())); + $decoratingDefinition->setTags($resetTags); $decoratingDefinitions[$inner] = $definition; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php index d8d7587c8d..721426b024 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/DecoratorServicePassTest.php @@ -167,6 +167,25 @@ class DecoratorServicePassTest extends TestCase $this->assertEquals(['bar' => ['attr' => 'baz']], $container->getDefinition('deco2')->getTags()); } + public function testProcessLeavesServiceLocatorTagOnOriginalDefinition() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setTags(['container.service_locator' => [0 => []], 'bar' => ['attr' => 'baz']]) + ; + $container + ->register('baz') + ->setTags(['foobar' => ['attr' => 'bar']]) + ->setDecoratedService('foo') + ; + + $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()); + } + protected function process(ContainerBuilder $container) { $repeatedPass = new DecoratorServicePass();