2121 * merged Definition instance.
2222 *
2323 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
24+ * @author Nicolas Grekas <p@tchwork.com>
2425 */
2526class ResolveDefinitionTemplatesPass implements CompilerPassInterface
2627{
27- private $ container ;
2828 private $ compiler ;
2929 private $ formatter ;
30+ private $ currentId ;
3031
3132 /**
3233 * Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
@@ -35,44 +36,78 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
3536 */
3637 public function process (ContainerBuilder $ container )
3738 {
38- $ this ->container = $ container ;
3939 $ this ->compiler = $ container ->getCompiler ();
4040 $ this ->formatter = $ this ->compiler ->getLoggingFormatter ();
4141
4242 foreach ($ container ->getDefinitions () as $ id => $ definition ) {
43+ $ this ->currentId = $ id ;
44+
4345 // yes, we are specifically fetching the definition from the
4446 // container to ensure we are not operating on stale data
4547 $ definition = $ container ->getDefinition ($ id );
46- if (!$ definition instanceof DefinitionDecorator || $ definition ->isAbstract ()) {
47- continue ;
48+ if ($ definition instanceof DefinitionDecorator) {
49+ $ definition = $ this ->resolveDefinition ($ container , $ definition );
50+ $ container ->setDefinition ($ id , $ definition );
4851 }
4952
50- $ this ->resolveDefinition ($ id , $ definition );
53+ $ definition ->setArguments ($ this ->resolveArguments ($ container , $ definition ->getArguments ()));
54+ $ definition ->setMethodCalls ($ this ->resolveArguments ($ container , $ definition ->getMethodCalls ()));
55+ $ definition ->setProperties ($ this ->resolveArguments ($ container , $ definition ->getProperties ()));
5156 }
5257 }
5358
59+ /**
60+ * Resolves definition decorator arguments.
61+ *
62+ * @param ContainerBuilder $container The ContainerBuilder
63+ * @param array $arguments An array of arguments
64+ *
65+ * @return array
66+ */
67+ private function resolveArguments (ContainerBuilder $ container , array $ arguments )
68+ {
69+ foreach ($ arguments as $ k => $ argument ) {
70+ if (is_array ($ argument )) {
71+ $ arguments [$ k ] = $ this ->resolveArguments ($ container , $ argument );
72+ } elseif ($ argument instanceof Definition) {
73+ if ($ argument instanceof DefinitionDecorator) {
74+ $ arguments [$ k ] = $ argument = $ this ->resolveDefinition ($ container , $ argument );
75+ }
76+ $ argument ->setArguments ($ this ->resolveArguments ($ container , $ argument ->getArguments ()));
77+ $ argument ->setMethodCalls ($ this ->resolveArguments ($ container , $ argument ->getMethodCalls ()));
78+ $ argument ->setProperties ($ this ->resolveArguments ($ container , $ argument ->getProperties ()));
79+ }
80+ }
81+
82+ return $ arguments ;
83+ }
84+
5485 /**
5586 * Resolves the definition.
5687 *
57- * @param string $id The definition identifier
88+ * @param ContainerBuilder $container The ContainerBuilder
5889 * @param DefinitionDecorator $definition
5990 *
6091 * @return Definition
6192 *
6293 * @throws \RuntimeException When the definition is invalid
6394 */
64- private function resolveDefinition ($ id , DefinitionDecorator $ definition )
95+ private function resolveDefinition (ContainerBuilder $ container , DefinitionDecorator $ definition )
6596 {
66- if (!$ this -> container ->hasDefinition ($ parent = $ definition ->getParent ())) {
67- throw new RuntimeException (sprintf ('The parent definition "%s" defined for definition "%s" does not exist. ' , $ parent , $ id ));
97+ if (!$ container ->hasDefinition ($ parent = $ definition ->getParent ())) {
98+ throw new RuntimeException (sprintf ('The parent definition "%s" defined for definition "%s" does not exist. ' , $ parent , $ this -> currentId ));
6899 }
69100
70- $ parentDef = $ this -> container ->getDefinition ($ parent );
101+ $ parentDef = $ container ->getDefinition ($ parent );
71102 if ($ parentDef instanceof DefinitionDecorator) {
72- $ parentDef = $ this ->resolveDefinition ($ parent , $ parentDef );
103+ $ id = $ this ->currentId ;
104+ $ this ->currentId = $ parent ;
105+ $ parentDef = $ this ->resolveDefinition ($ container , $ parentDef );
106+ $ container ->setDefinition ($ parent , $ parentDef );
107+ $ this ->currentId = $ id ;
73108 }
74109
75- $ this ->compiler ->addLogMessage ($ this ->formatter ->formatResolveInheritance ($ this , $ id , $ parent ));
110+ $ this ->compiler ->addLogMessage ($ this ->formatter ->formatResolveInheritance ($ this , $ this -> currentId , $ parent ));
76111 $ def = new Definition ();
77112
78113 // merge in parent definition
@@ -156,9 +191,6 @@ private function resolveDefinition($id, DefinitionDecorator $definition)
156191 $ def ->setScope ($ definition ->getScope (false ), false );
157192 $ def ->setTags ($ definition ->getTags ());
158193
159- // set new definition on container
160- $ this ->container ->setDefinition ($ id , $ def );
161-
162194 return $ def ;
163195 }
164196}
0 commit comments