@@ -118,28 +118,74 @@ private function parseDefinitions(\DOMDocument $xml, $file)
118118 }
119119
120120 foreach ($ services as $ service ) {
121- if (null !== $ definition = $ this ->parseDefinition ($ service , $ file )) {
121+ if (null !== $ definition = $ this ->parseDefinition ($ service , $ file, $ this -> getServiceDefaults ( $ xml , $ file ) )) {
122122 $ this ->container ->setDefinition ((string ) $ service ->getAttribute ('id ' ), $ definition );
123123 }
124124 }
125125 }
126126
127+ /**
128+ * Get service defaults.
129+ *
130+ * @return array
131+ */
132+ private function getServiceDefaults (\DOMDocument $ xml , $ file )
133+ {
134+ $ xpath = new \DOMXPath ($ xml );
135+ $ xpath ->registerNamespace ('container ' , self ::NS );
136+
137+ if (null === $ defaultsNode = $ xpath ->query ('//container:services/container:defaults ' )->item (0 )) {
138+ return array ();
139+ }
140+ $ defaults = array (
141+ 'tags ' => $ this ->getChildren ($ defaultsNode , 'tag ' ),
142+ 'autowire ' => $ this ->getChildren ($ defaultsNode , 'autowire ' ),
143+ );
144+
145+ foreach ($ defaults ['tags ' ] as $ tag ) {
146+ if ('' === $ tag ->getAttribute ('name ' )) {
147+ throw new InvalidArgumentException (sprintf ('The tag name for tag "<defaults>" in %s must be a non-empty string. ' , $ file ));
148+ }
149+ }
150+ if ($ defaultsNode ->hasAttribute ('public ' )) {
151+ $ defaults ['public ' ] = XmlUtils::phpize ($ defaultsNode ->getAttribute ('public ' ));
152+ }
153+ if (!$ defaultsNode ->hasAttribute ('autowire ' )) {
154+ foreach ($ defaults ['autowire ' ] as $ k => $ v ) {
155+ $ defaults ['autowire ' ][$ k ] = $ v ->textContent ;
156+ }
157+
158+ return $ defaults ;
159+ }
160+ if ($ defaults ['autowire ' ]) {
161+ throw new InvalidArgumentException (sprintf ('The "autowire" attribute cannot be used together with "<autowire>" tags for tag "<defaults>" in %s. ' , $ file ));
162+ }
163+ if (XmlUtils::phpize ($ defaultsNode ->getAttribute ('autowire ' ))) {
164+ $ defaults ['autowire ' ][] = '__construct ' ;
165+ }
166+
167+ return $ defaults ;
168+ }
169+
127170 /**
128171 * Parses an individual Definition.
129172 *
130173 * @param \DOMElement $service
131174 * @param string $file
175+ * @param array $defaults
132176 *
133177 * @return Definition|null
134178 */
135- private function parseDefinition (\DOMElement $ service , $ file )
179+ private function parseDefinition (\DOMElement $ service , $ file, array $ defaults = array () )
136180 {
137181 if ($ alias = $ service ->getAttribute ('alias ' )) {
138182 $ this ->validateAlias ($ service , $ file );
139183
140184 $ public = true ;
141185 if ($ publicAttr = $ service ->getAttribute ('public ' )) {
142186 $ public = XmlUtils::phpize ($ publicAttr );
187+ } elseif (isset ($ defaults ['public ' ])) {
188+ $ public = $ defaults ['public ' ];
143189 }
144190 $ this ->container ->setAlias ((string ) $ service ->getAttribute ('id ' ), new Alias ($ alias , $ public ));
145191
@@ -148,11 +194,18 @@ private function parseDefinition(\DOMElement $service, $file)
148194
149195 if ($ parent = $ service ->getAttribute ('parent ' )) {
150196 $ definition = new ChildDefinition ($ parent );
197+ $ defaults = array ();
151198 } else {
152199 $ definition = new Definition ();
153200 }
154201
155- foreach (array ('class ' , 'shared ' , 'public ' , 'synthetic ' , 'lazy ' , 'abstract ' ) as $ key ) {
202+ if ($ publicAttr = $ service ->getAttribute ('public ' )) {
203+ $ definition ->setPublic (XmlUtils::phpize ($ publicAttr ));
204+ } elseif (isset ($ defaults ['public ' ])) {
205+ $ definition ->setPublic ($ defaults ['public ' ]);
206+ }
207+
208+ foreach (array ('class ' , 'shared ' , 'synthetic ' , 'lazy ' , 'abstract ' ) as $ key ) {
156209 if ($ value = $ service ->getAttribute ($ key )) {
157210 $ method = 'set ' .$ key ;
158211 $ definition ->$ method (XmlUtils::phpize ($ value ));
@@ -216,7 +269,12 @@ private function parseDefinition(\DOMElement $service, $file)
216269 $ definition ->addMethodCall ($ call ->getAttribute ('method ' ), $ this ->getArgumentsAsPhp ($ call , 'argument ' ));
217270 }
218271
219- foreach ($ this ->getChildren ($ service , 'tag ' ) as $ tag ) {
272+ $ tags = $ this ->getChildren ($ service , 'tag ' );
273+ if (!$ tags && !empty ($ defaults ['tags ' ])) {
274+ $ tags = $ defaults ['tags ' ];
275+ }
276+
277+ foreach ($ tags as $ tag ) {
220278 $ parameters = array ();
221279 foreach ($ tag ->attributes as $ name => $ node ) {
222280 if ('name ' === $ name ) {
@@ -252,6 +310,8 @@ private function parseDefinition(\DOMElement $service, $file)
252310 }
253311
254312 $ definition ->setAutowiredMethods ($ autowireTags );
313+ } elseif (!$ service ->hasAttribute ('autowire ' ) && !empty ($ defaults ['autowire ' ])) {
314+ $ definition ->setAutowiredMethods ($ defaults ['autowire ' ]);
255315 }
256316
257317 if ($ value = $ service ->getAttribute ('decorates ' )) {
0 commit comments