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

Skip to content

Commit 572db9f

Browse files
ogizanaginicolas-grekas
authored andcommitted
[DI] Add "defaults" tag to XML services configuration
1 parent 346a180 commit 572db9f

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
@@ -116,28 +116,74 @@ private function parseDefinitions(\DOMDocument $xml, $file)
116116
}
117117

118118
foreach ($services as $service) {
119-
if (null !== $definition = $this->parseDefinition($service, $file)) {
119+
if (null !== $definition = $this->parseDefinition($service, $file, $this->getServiceDefaults($xml, $file))) {
120120
$this->container->setDefinition((string) $service->getAttribute('id'), $definition);
121121
}
122122
}
123123
}
124124

125+
/**
126+
* Get service defaults.
127+
*
128+
* @return array
129+
*/
130+
private function getServiceDefaults(\DOMDocument $xml, $file)
131+
{
132+
$xpath = new \DOMXPath($xml);
133+
$xpath->registerNamespace('container', self::NS);
134+
135+
if (null === $defaultsNode = $xpath->query('//container:services/container:defaults')->item(0)) {
136+
return array();
137+
}
138+
$defaults = array(
139+
'tags' => $this->getChildren($defaultsNode, 'tag'),
140+
'autowire' => $this->getChildren($defaultsNode, 'autowire'),
141+
);
142+
143+
foreach ($defaults['tags'] as $tag) {
144+
if ('' === $tag->getAttribute('name')) {
145+
throw new InvalidArgumentException(sprintf('The tag name for tag "<defaults>" in %s must be a non-empty string.', $file));
146+
}
147+
}
148+
if ($defaultsNode->hasAttribute('public')) {
149+
$defaults['public'] = XmlUtils::phpize($defaultsNode->getAttribute('public'));
150+
}
151+
if (!$defaultsNode->hasAttribute('autowire')) {
152+
foreach ($defaults['autowire'] as $k => $v) {
153+
$defaults['autowire'][$k] = $v->textContent;
154+
}
155+
156+
return $defaults;
157+
}
158+
if ($defaults['autowire']) {
159+
throw new InvalidArgumentException(sprintf('The "autowire" attribute cannot be used together with "<autowire>" tags for tag "<defaults>" in %s.', $file));
160+
}
161+
if (XmlUtils::phpize($defaultsNode->getAttribute('autowire'))) {
162+
$defaults['autowire'][] = '__construct';
163+
}
164+
165+
return $defaults;
166+
}
167+
125168
/**
126169
* Parses an individual Definition.
127170
*
128171
* @param \DOMElement $service
129172
* @param string $file
173+
* @param array $defaults
130174
*
131175
* @return Definition|null
132176
*/
133-
private function parseDefinition(\DOMElement $service, $file)
177+
private function parseDefinition(\DOMElement $service, $file, array $defaults = array())
134178
{
135179
if ($alias = $service->getAttribute('alias')) {
136180
$this->validateAlias($service, $file);
137181

138182
$public = true;
139183
if ($publicAttr = $service->getAttribute('public')) {
140184
$public = XmlUtils::phpize($publicAttr);
185+
} elseif (isset($defaults['public'])) {
186+
$public = $defaults['public'];
141187
}
142188
$this->container->setAlias((string) $service->getAttribute('id'), new Alias($alias, $public));
143189

@@ -146,11 +192,18 @@ private function parseDefinition(\DOMElement $service, $file)
146192

147193
if ($parent = $service->getAttribute('parent')) {
148194
$definition = new ChildDefinition($parent);
195+
$defaults = array();
149196
} else {
150197
$definition = new Definition();
151198
}
152199

153-
foreach (array('class', 'shared', 'public', 'synthetic', 'lazy', 'abstract') as $key) {
200+
if ($publicAttr = $service->getAttribute('public')) {
201+
$definition->setPublic(XmlUtils::phpize($publicAttr));
202+
} elseif (isset($defaults['public'])) {
203+
$definition->setPublic($defaults['public']);
204+
}
205+
206+
foreach (array('class', 'shared', 'synthetic', 'lazy', 'abstract') as $key) {
154207
if ($value = $service->getAttribute($key)) {
155208
$method = 'set'.$key;
156209
$definition->$method(XmlUtils::phpize($value));
@@ -214,7 +267,12 @@ private function parseDefinition(\DOMElement $service, $file)
214267
$definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument'));
215268
}
216269

217-
foreach ($this->getChildren($service, 'tag') as $tag) {
270+
$tags = $this->getChildren($service, 'tag');
271+
if (!$tags && !empty($defaults['tags'])) {
272+
$tags = $defaults['tags'];
273+
}
274+
275+
foreach ($tags as $tag) {
218276
$parameters = array();
219277
foreach ($tag->attributes as $name => $node) {
220278
if ('name' === $name) {
@@ -250,6 +308,8 @@ private function parseDefinition(\DOMElement $service, $file)
250308
}
251309

252310
$definition->setAutowiredMethods($autowireTags);
311+
} elseif (!$service->hasAttribute('autowire') && !empty($defaults['autowire'])) {
312+
$definition->setAutowiredMethods($defaults['autowire']);
253313
}
254314

255315
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
@@ -594,4 +594,38 @@ public function testArgumentWithKeyOutsideCollection()
594594

595595
$this->assertSame(array('type' => 'foo', 'bar'), $container->getDefinition('foo')->getArguments());
596596
}
597+
598+
public function testDefaults()
599+
{
600+
$container = new ContainerBuilder();
601+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
602+
$loader->load('services29.xml');
603+
604+
$this->assertFalse($container->getDefinition('with_defaults')->isPublic());
605+
$this->assertTrue($container->getDefinition('no_defaults')->isPublic());
606+
$this->assertTrue($container->getDefinition('no_defaults_child')->isPublic());
607+
$this->assertArrayNotHasKey('public', $container->getDefinition('no_defaults_child')->getChanges());
608+
609+
$this->assertSame(array('foo' => array(array())), $container->getDefinition('with_defaults')->getTags());
610+
$this->assertSame(array('bar' => array(array())), $container->getDefinition('no_defaults')->getTags());
611+
$this->assertSame(array('bar' => array(array())), $container->getDefinition('no_defaults_child')->getTags());
612+
$this->assertSame(array(), $container->getDefinition('with_defaults_child')->getTags());
613+
614+
$this->assertTrue($container->getDefinition('with_defaults')->isAutowired());
615+
$this->assertFalse($container->getDefinition('no_defaults')->isAutowired());
616+
$this->assertFalse($container->getDefinition('no_defaults_child')->isAutowired());
617+
$this->assertArrayNotHasKey('autowire', $container->getDefinition('no_defaults_child')->getChanges());
618+
}
619+
620+
public function testDefaultsWithAutowiredMethods()
621+
{
622+
$container = new ContainerBuilder();
623+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
624+
$loader->load('services30.xml');
625+
626+
$this->assertSame(array('__construct'), $container->getDefinition('with_defaults')->getAutowiredMethods());
627+
$this->assertSame(array('setFoo'), $container->getDefinition('no_defaults')->getAutowiredMethods());
628+
$this->assertSame(array('setFoo'), $container->getDefinition('no_defaults_child')->getAutowiredMethods());
629+
$this->assertSame(array(), $container->getDefinition('with_defaults_child')->getAutowiredMethods());
630+
}
597631
}

0 commit comments

Comments
 (0)