Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b2783a7

Browse filesBrowse files
Okhoshinicolas-grekas
authored andcommitted
[DependencyInjection] Fix autowiring tagged arguments from attributes
1 parent 67f43b0 commit b2783a7
Copy full SHA for b2783a7

File tree

7 files changed

+46
-13
lines changed
Filter options

7 files changed

+46
-13
lines changed

‎src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
+2-4Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,8 @@ private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot,
159159
$this->decoratedClass = null;
160160
$this->getPreviousValue = null;
161161

162-
if ($isRoot && ($definition = $this->container->getDefinition($this->currentId)) && ($decoratedDefinition = $definition->getDecoratedService()) && null !== ($innerId = $decoratedDefinition[0]) && $this->container->has($innerId)) {
163-
// If the class references to itself and is decorated, provide the inner service id and class to not get a circular reference
164-
$this->decoratedClass = $this->container->findDefinition($innerId)->getClass();
165-
$this->decoratedId = $decoratedDefinition[1] ?? $this->currentId.'.inner';
162+
if ($isRoot && ($definition = $this->container->getDefinition($this->currentId)) && null !== ($this->decoratedId = $definition->innerServiceId) && $this->container->has($this->decoratedId)) {
163+
$this->decoratedClass = $this->container->findDefinition($this->decoratedId)->getClass();
166164
}
167165

168166
$patchedIndexes = [];

‎src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ public function __construct()
6262
new AutowireRequiredMethodsPass(),
6363
new AutowireRequiredPropertiesPass(),
6464
new ResolveBindingsPass(),
65-
new CheckDefinitionValidityPass(),
66-
new AutowirePass(false),
6765
new ServiceLocatorTagPass(),
6866
new DecoratorServicePass(),
67+
new CheckDefinitionValidityPass(),
68+
new AutowirePass(false),
6969
new ResolveTaggedIteratorArgumentPass(),
7070
new ResolveServiceSubscribersPass(),
7171
new ResolveReferencesToAliasesPass(),

‎src/Symfony/Component/DependencyInjection/Compiler/ResolveTaggedIteratorArgumentPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/ResolveTaggedIteratorArgumentPass.php
+10-1Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
namespace Symfony\Component\DependencyInjection\Compiler;
1313

1414
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
15+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1516

1617
/**
17-
* Resolves all TaggedIteratorArgument arguments.
18+
* Resolves TaggedIteratorArgument and ServiceLocatorArgument.
1819
*
1920
* @author Roland Franssen <franssen.roland@gmail.com>
2021
*/
@@ -27,6 +28,14 @@ class ResolveTaggedIteratorArgumentPass extends AbstractRecursivePass
2728
*/
2829
protected function processValue($value, bool $isRoot = false)
2930
{
31+
if ($value instanceof ServiceLocatorArgument) {
32+
if ($value->getTaggedIteratorArgument()) {
33+
$value->setValues($this->findAndSortTaggedServices($value->getTaggedIteratorArgument(), $this->container));
34+
}
35+
36+
return ServiceLocatorTagPass::register($this->container, $value->getValues());
37+
}
38+
3039
if (!$value instanceof TaggedIteratorArgument) {
3140
return parent::processValue($value, $isRoot);
3241
}

‎src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php
+5-4Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -985,8 +985,8 @@ public function testAutowireDecorator()
985985
->setAutowired(true)
986986
;
987987

988-
(new AutowirePass())->process($container);
989988
(new DecoratorServicePass())->process($container);
989+
(new AutowirePass())->process($container);
990990

991991
$definition = $container->getDefinition(Decorator::class);
992992
$this->assertSame(Decorator::class.'.inner', (string) $definition->getArgument(1));
@@ -1008,8 +1008,8 @@ public function testAutowireDecoratorChain()
10081008
->setAutowired(true)
10091009
;
10101010

1011-
(new AutowirePass())->process($container);
10121011
(new DecoratorServicePass())->process($container);
1012+
(new AutowirePass())->process($container);
10131013

10141014
$definition = $container->getDefinition(DecoratedDecorator::class);
10151015
$this->assertSame(DecoratedDecorator::class.'.inner', (string) $definition->getArgument(0));
@@ -1026,8 +1026,8 @@ public function testAutowireDecoratorRenamedId()
10261026
->setAutowired(true)
10271027
;
10281028

1029-
(new AutowirePass())->process($container);
10301029
(new DecoratorServicePass())->process($container);
1030+
(new AutowirePass())->process($container);
10311031

10321032
$definition = $container->getDefinition(Decorator::class);
10331033
$this->assertSame('renamed', (string) $definition->getArgument(1));
@@ -1044,11 +1044,12 @@ public function testDoNotAutowireDecoratorWhenSeveralArgumentOfTheType()
10441044
->setAutowired(true)
10451045
;
10461046

1047+
(new DecoratorServicePass())->process($container);
10471048
try {
10481049
(new AutowirePass())->process($container);
10491050
$this->fail('AutowirePass should have thrown an exception');
10501051
} catch (AutowiringFailedException $e) {
1051-
$this->assertSame('Cannot autowire service "Symfony\Component\DependencyInjection\Tests\Compiler\NonAutowirableDecorator": argument "$decorated1" of method "__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\DecoratorInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "Symfony\Component\DependencyInjection\Tests\Compiler\Decorated", "Symfony\Component\DependencyInjection\Tests\Compiler\NonAutowirableDecorator".', (string) $e->getMessage());
1052+
$this->assertSame('Cannot autowire service "Symfony\Component\DependencyInjection\Tests\Compiler\NonAutowirableDecorator": argument "$decorated1" of method "__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\DecoratorInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "Symfony\Component\DependencyInjection\Tests\Compiler\NonAutowirableDecorator", "Symfony\Component\DependencyInjection\Tests\Compiler\NonAutowirableDecorator.inner".', (string) $e->getMessage());
10521053
}
10531054
}
10541055

‎src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,33 @@ public function testCanDecorateServiceLocator()
175175
$this->assertSame($container->get('foo'), $container->get(DecoratedServiceLocator::class)->get('foo'));
176176
}
177177

178+
public function testAliasDecoratedService()
179+
{
180+
$container = new ContainerBuilder();
181+
182+
$container->register('service', ServiceLocator::class)
183+
->setPublic(true)
184+
->setArguments([[]])
185+
;
186+
$container->register('decorator', DecoratedServiceLocator::class)
187+
->setDecoratedService('service')
188+
->setAutowired(true)
189+
->setPublic(true)
190+
;
191+
$container->setAlias(ServiceLocator::class, 'decorator.inner')
192+
->setPublic(true)
193+
;
194+
$container->register('user_service', DecoratedServiceLocator::class)
195+
->setAutowired(true)
196+
;
197+
198+
$container->compile();
199+
200+
$this->assertInstanceOf(DecoratedServiceLocator::class, $container->get('service'));
201+
$this->assertInstanceOf(ServiceLocator::class, $container->get(ServiceLocator::class));
202+
$this->assertSame($container->get('service'), $container->get('decorator'));
203+
}
204+
178205
/**
179206
* @dataProvider getYamlCompileTests
180207
*/

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public function getRemovedIds(): array
4646
return [
4747
'.service_locator.DlIAmAe' => true,
4848
'.service_locator.DlIAmAe.foo_service' => true,
49-
'.service_locator.t5IGRMW' => true,
5049
'Psr\\Container\\ContainerInterface' => true,
5150
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
5251
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true,

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public function getRemovedIds(): array
4646
return [
4747
'.service_locator.JmEob1b' => true,
4848
'.service_locator.JmEob1b.foo_service' => true,
49-
'.service_locator.KIgkoLM' => true,
5049
'Psr\\Container\\ContainerInterface' => true,
5150
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
5251
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true,

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.