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,80 @@ 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
42- foreach ($ container ->getDefinitions () as $ id => $ definition ) {
43- // yes, we are specifically fetching the definition from the
44- // container to ensure we are not operating on stale data
45- $ definition = $ container ->getDefinition ($ id );
46- if (!$ definition instanceof DefinitionDecorator || $ definition ->isAbstract ()) {
47- continue ;
48- }
42+ $ container ->setDefinitions ($ this ->resolveArguments ($ container , $ container ->getDefinitions (), true ));
43+ }
4944
50- $ this ->resolveDefinition ($ id , $ definition );
45+ /**
46+ * Resolves definition decorator arguments.
47+ *
48+ * @param ContainerBuilder $container The ContainerBuilder
49+ * @param array $arguments An array of arguments
50+ * @param bool $isRoot If we are processing the root definitions or not
51+ *
52+ * @return array
53+ */
54+ private function resolveArguments (ContainerBuilder $ container , array $ arguments , $ isRoot = false )
55+ {
56+ foreach ($ arguments as $ k => $ argument ) {
57+ if ($ isRoot ) {
58+ // yes, we are specifically fetching the definition from the
59+ // container to ensure we are not operating on stale data
60+ $ arguments [$ k ] = $ argument = $ container ->getDefinition ($ k );
61+ $ this ->currentId = $ k ;
62+ }
63+ if (is_array ($ argument )) {
64+ $ arguments [$ k ] = $ this ->resolveArguments ($ container , $ argument );
65+ } elseif ($ argument instanceof Definition) {
66+ if ($ argument instanceof DefinitionDecorator) {
67+ $ arguments [$ k ] = $ argument = $ this ->resolveDefinition ($ container , $ argument );
68+ if ($ isRoot ) {
69+ $ container ->setDefinition ($ k , $ argument );
70+ }
71+ }
72+ $ argument ->setArguments ($ this ->resolveArguments ($ container , $ argument ->getArguments ()));
73+ $ argument ->setMethodCalls ($ this ->resolveArguments ($ container , $ argument ->getMethodCalls ()));
74+ $ argument ->setProperties ($ this ->resolveArguments ($ container , $ argument ->getProperties ()));
75+
76+ $ configurator = $ this ->resolveArguments ($ container , array ($ argument ->getConfigurator ()));
77+ $ argument ->setConfigurator ($ configurator [0 ]);
78+
79+ $ factory = $ this ->resolveArguments ($ container , array ($ argument ->getFactory ()));
80+ $ argument ->setFactory ($ factory [0 ]);
81+ }
5182 }
83+
84+ return $ arguments ;
5285 }
5386
5487 /**
5588 * Resolves the definition.
5689 *
57- * @param string $id The definition identifier
90+ * @param ContainerBuilder $container The ContainerBuilder
5891 * @param DefinitionDecorator $definition
5992 *
6093 * @return Definition
6194 *
6295 * @throws \RuntimeException When the definition is invalid
6396 */
64- private function resolveDefinition ($ id , DefinitionDecorator $ definition )
97+ private function resolveDefinition (ContainerBuilder $ container , DefinitionDecorator $ definition )
6598 {
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 ));
99+ if (!$ container ->hasDefinition ($ parent = $ definition ->getParent ())) {
100+ throw new RuntimeException (sprintf ('The parent definition "%s" defined for definition "%s" does not exist. ' , $ parent , $ this -> currentId ));
68101 }
69102
70- $ parentDef = $ this -> container ->getDefinition ($ parent );
103+ $ parentDef = $ container ->getDefinition ($ parent );
71104 if ($ parentDef instanceof DefinitionDecorator) {
72- $ parentDef = $ this ->resolveDefinition ($ parent , $ parentDef );
105+ $ id = $ this ->currentId ;
106+ $ this ->currentId = $ parent ;
107+ $ parentDef = $ this ->resolveDefinition ($ container , $ parentDef );
108+ $ container ->setDefinition ($ parent , $ parentDef );
109+ $ this ->currentId = $ id ;
73110 }
74111
75- $ this ->compiler ->addLogMessage ($ this ->formatter ->formatResolveInheritance ($ this , $ id , $ parent ));
112+ $ this ->compiler ->addLogMessage ($ this ->formatter ->formatResolveInheritance ($ this , $ this -> currentId , $ parent ));
76113 $ def = new Definition ();
77114
78115 // merge in parent definition
@@ -156,9 +193,6 @@ private function resolveDefinition($id, DefinitionDecorator $definition)
156193 $ def ->setScope ($ definition ->getScope (false ), false );
157194 $ def ->setTags ($ definition ->getTags ());
158195
159- // set new definition on container
160- $ this ->container ->setDefinition ($ id , $ def );
161-
162196 return $ def ;
163197 }
164198}
0 commit comments