Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 05f24d5

Browse files
ogizanaginicolas-grekas
authored andcommitted
[DI] Add "defaults" tag to XML services configuration
1 parent 7b4a18b commit 05f24d5

File tree

5 files changed

+149
-6
lines changed

5 files changed

+149
-6
lines changed

src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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')) {

src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@
5252
Enclosing element for the definition of all services
5353
]]></xsd:documentation>
5454
</xsd:annotation>
55-
<xsd:choice minOccurs="1" maxOccurs="unbounded">
56-
<xsd:element name="service" type="service" />
55+
<xsd:choice maxOccurs="unbounded">
56+
<xsd:element name="service" type="service" minOccurs="1" />
57+
<xsd:element name="defaults" type="defaults" minOccurs="0" maxOccurs="1" />
5758
</xsd:choice>
5859
</xsd:complexType>
5960

@@ -89,6 +90,20 @@
8990
<xsd:attribute name="function" type="xsd:string" />
9091
</xsd:complexType>
9192

93+
<xsd:complexType name="defaults">
94+
<xsd:annotation>
95+
<xsd:documentation><![CDATA[
96+
Enclosing element for the service definitions' defaults for the current file
97+
]]></xsd:documentation>
98+
</xsd:annotation>
99+
<xsd:choice maxOccurs="unbounded">
100+
<xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" />
101+
<xsd:element name="autowire" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
102+
</xsd:choice>
103+
<xsd:attribute name="public" type="boolean" />
104+
<xsd:attribute name="autowire" type="boolean" />
105+
</xsd:complexType>
106+
92107
<xsd:complexType name="service">
93108
<xsd:choice maxOccurs="unbounded">
94109
<xsd:element name="file" type="xsd:string" minOccurs="0" maxOccurs="1" />
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<defaults public="false" autowire="true">
5+
<tag name="foo" />
6+
</defaults>
7+
8+
<service id="with_defaults" class="Foo" />
9+
<service id="no_defaults" class="Foo" public="true" autowire="false">
10+
<tag name="bar" />
11+
</service>
12+
<service id="no_defaults_child" class="Foo" parent="no_defaults">
13+
<tag name="bar" />
14+
</service>
15+
<service id="with_defaults_child" class="Foo" parent="with_defaults" />
16+
</services>
17+
</container>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<defaults public="false">
5+
<autowire>__construct</autowire>
6+
</defaults>
7+
8+
<service id="with_defaults" class="Foo" />
9+
<service id="no_defaults" class="Foo" public="true">
10+
<autowire>setFoo</autowire>
11+
</service>
12+
<service id="no_defaults_child" class="Foo" parent="no_defaults">
13+
<autowire>setFoo</autowire>
14+
</service>
15+
<service id="with_defaults_child" class="Foo" parent="with_defaults" />
16+
</services>
17+
</container>

src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,4 +617,38 @@ public function testArgumentWithKeyOutsideCollection()
617617

618618
$this->assertSame(array('type' => 'foo', 'bar'), $container->getDefinition('foo')->getArguments());
619619
}
620+
621+
public function testDefaults()
622+
{
623+
$container = new ContainerBuilder();
624+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
625+
$loader->load('services29.xml');
626+
627+
$this->assertFalse($container->getDefinition('with_defaults')->isPublic());
628+
$this->assertTrue($container->getDefinition('no_defaults')->isPublic());
629+
$this->assertTrue($container->getDefinition('no_defaults_child')->isPublic());
630+
$this->assertArrayNotHasKey('public', $container->getDefinition('no_defaults_child')->getChanges());
631+
632+
$this->assertSame(array('foo' => array(array())), $container->getDefinition('with_defaults')->getTags());
633+
$this->assertSame(array('bar' => array(array())), $container->getDefinition('no_defaults')->getTags());
634+
$this->assertSame(array('bar' => array(array())), $container->getDefinition('no_defaults_child')->getTags());
635+
$this->assertSame(array(), $container->getDefinition('with_defaults_child')->getTags());
636+
637+
$this->assertTrue($container->getDefinition('with_defaults')->isAutowired());
638+
$this->assertFalse($container->getDefinition('no_defaults')->isAutowired());
639+
$this->assertFalse($container->getDefinition('no_defaults_child')->isAutowired());
640+
$this->assertArrayNotHasKey('autowire', $container->getDefinition('no_defaults_child')->getChanges());
641+
}
642+
643+
public function testDefaultsWithAutowiredMethods()
644+
{
645+
$container = new ContainerBuilder();
646+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
647+
$loader->load('services30.xml');
648+
649+
$this->assertSame(array('__construct'), $container->getDefinition('with_defaults')->getAutowiredMethods());
650+
$this->assertSame(array('setFoo'), $container->getDefinition('no_defaults')->getAutowiredMethods());
651+
$this->assertSame(array('setFoo'), $container->getDefinition('no_defaults_child')->getAutowiredMethods());
652+
$this->assertSame(array(), $container->getDefinition('with_defaults_child')->getAutowiredMethods());
653+
}
620654
}

0 commit comments

Comments
 (0)