5
5
use Symfony \Component \DependencyInjection \Compiler \CompilerPassInterface ;
6
6
use Symfony \Component \DependencyInjection \ContainerAwareInterface ;
7
7
use Symfony \Component \DependencyInjection \ContainerBuilder ;
8
+ use Symfony \Component \DependencyInjection \Definition ;
8
9
use Symfony \Component \DependencyInjection \Reference ;
9
10
10
11
abstract class TaggedServiceMappingPass implements CompilerPassInterface
@@ -18,23 +19,26 @@ private function getTaggedServiceMapping(ContainerBuilder $container, $tagName)
18
19
19
20
foreach ($ taggedServices as $ id => $ tags ) {
20
21
$ className = $ container ->findDefinition ($ id )->getClass ();
21
- foreach ($ tags as $ tag ) {
22
- $ this ->checkRequirements ($ id , $ tag );
23
- $ tag = array_merge ($ tag , ['id ' => $ id ]);
22
+ foreach ($ tags as $ attributes ) {
23
+ $ this ->checkRequirements ($ id , $ attributes );
24
+ $ attributes = array_merge ($ attributes , ['id ' => $ id , 'aliases ' => []]);
25
+
24
26
if (!$ isType ) {
25
- $ tag ['method ' ] = isset ($ tag ['method ' ]) ? $ tag ['method ' ] : '__invoke ' ;
27
+ $ attributes ['method ' ] = isset ($ attributes ['method ' ]) ? $ attributes ['method ' ] : '__invoke ' ;
28
+ }
29
+ if ($ isType || '__invoke ' === $ attributes ['method ' ]) {
30
+ $ solutionID = $ className ;
31
+ } else {
32
+ $ solutionID = sprintf ('%s::%s ' , $ className , $ attributes ['method ' ]);
26
33
}
27
- if (isset ($ tag ['alias ' ])) {
28
- $ serviceMapping [$ tag ['alias ' ]] = $ tag ;
34
+
35
+ if (!isset ($ serviceMapping [$ solutionID ])) {
36
+ $ serviceMapping [$ solutionID ] = $ attributes ;
29
37
}
30
38
31
- // add FQCN alias
32
- $ alias = $ className ;
33
- if (!$ isType && '__invoke ' !== $ tag ['method ' ]) {
34
- $ alias .= ':: ' .$ tag ['method ' ];
39
+ if (isset ($ attributes ['alias ' ]) && $ solutionID !== $ attributes ['alias ' ]) {
40
+ $ serviceMapping [$ solutionID ]['aliases ' ][] = $ attributes ['alias ' ];
35
41
}
36
- $ tag ['alias ' ] = $ alias ;
37
- $ serviceMapping [$ tag ['alias ' ]] = $ tag ;
38
42
}
39
43
}
40
44
@@ -46,35 +50,19 @@ public function process(ContainerBuilder $container)
46
50
$ mapping = $ this ->getTaggedServiceMapping ($ container , $ this ->getTagName ());
47
51
$ resolverDefinition = $ container ->findDefinition ($ this ->getResolverServiceID ());
48
52
49
- foreach ($ mapping as $ name => $ options ) {
50
- $ cleanOptions = $ options ;
51
- $ solutionID = $ options ['id ' ];
53
+ foreach ($ mapping as $ solutionID => $ attributes ) {
54
+ $ attributes ['aliases ' ] = array_unique ($ attributes ['aliases ' ]);
55
+ $ aliases = $ attributes ['aliases ' ];
56
+ $ serviceID = $ attributes ['id ' ];
52
57
53
- $ solutionDefinition = $ container ->findDefinition ($ solutionID );
58
+ $ solutionDefinition = $ container ->findDefinition ($ serviceID );
54
59
// make solution service public to improve lazy loading
55
60
$ solutionDefinition ->setPublic (true );
56
-
57
- $ methods = array_map (
58
- function ($ methodCall ) {
59
- return $ methodCall [0 ];
60
- },
61
- $ solutionDefinition ->getMethodCalls ()
62
- );
63
- if (
64
- empty ($ options ['generated ' ]) // false is consider as empty
65
- && is_subclass_of ($ solutionDefinition ->getClass (), ContainerAwareInterface::class)
66
- && !in_array ('setContainer ' , $ methods )
67
- ) {
68
- @trigger_error (
69
- 'Autowire custom tagged (type, resolver or mutation) services is deprecated as of 0.9 and will be removed in 1.0. Use AutoMapping or set it manually instead. ' ,
70
- E_USER_DEPRECATED
71
- );
72
- $ solutionDefinition ->addMethodCall ('setContainer ' , [new Reference ('service_container ' )]);
73
- }
61
+ $ this ->autowireSolutionImplementingContainerAwareInterface ($ solutionDefinition , empty ($ attributes ['generated ' ]));
74
62
75
63
$ resolverDefinition ->addMethodCall (
76
64
'addSolution ' ,
77
- [$ name , [new Reference ('service_container ' ), 'get ' ], [$ solutionID ] , $ cleanOptions ]
65
+ [$ solutionID , [[ new Reference ('service_container ' ), 'get ' ], [$ serviceID ]] , $ aliases , $ attributes ]
78
66
);
79
67
}
80
68
}
@@ -88,6 +76,30 @@ protected function checkRequirements($id, array $tag)
88
76
}
89
77
}
90
78
79
+ private function autowireSolutionImplementingContainerAwareInterface (Definition $ solutionDefinition , $ isGenerated )
80
+ {
81
+ $ methods = array_map (
82
+ function ($ methodCall ) {
83
+ return $ methodCall [0 ];
84
+ },
85
+ $ solutionDefinition ->getMethodCalls ()
86
+ );
87
+ if (
88
+ $ isGenerated
89
+ && is_subclass_of ($ solutionDefinition ->getClass (), ContainerAwareInterface::class)
90
+ && !in_array ('setContainer ' , $ methods )
91
+ ) {
92
+ @trigger_error (
93
+ sprintf (
94
+ 'Autowire method "%s::setContainer" for custom tagged (type, resolver or mutation) services is deprecated as of 0.9 and will be removed in 1.0. ' ,
95
+ ContainerAwareInterface::class
96
+ ),
97
+ E_USER_DEPRECATED
98
+ );
99
+ $ solutionDefinition ->addMethodCall ('setContainer ' , [new Reference ('service_container ' )]);
100
+ }
101
+ }
102
+
91
103
abstract protected function getTagName ();
92
104
93
105
/**
0 commit comments