Skip to content

Commit e22f299

Browse files
committed
[Routing] support for array values in defaults
As pointed out in symfony/symfony-docs#4017, the XmlFileLoader was not capable of defining array default values.
1 parent 890cd39 commit e22f299

File tree

4 files changed

+68
-6
lines changed

4 files changed

+68
-6
lines changed

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

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,9 @@ private function parseConfigs(\DOMElement $node, $path)
219219
foreach ($node->getElementsByTagNameNS(self::NAMESPACE_URI, '*') as $n) {
220220
switch ($n->localName) {
221221
case 'default':
222-
if ($n->hasAttribute('xsi:nil') && 'true' == $n->getAttribute('xsi:nil')) {
223-
$defaults[$n->getAttribute('key')] = null;
224-
} else {
225-
$defaults[$n->getAttribute('key')] = trim($n->textContent);
222+
if ($node === $n->parentNode) {
223+
$defaults[$n->getAttribute('key')] = $this->parseDefaultsConfig($n);
226224
}
227-
228225
break;
229226
case 'requirement':
230227
$requirements[$n->getAttribute('key')] = trim($n->textContent);
@@ -242,4 +239,27 @@ private function parseConfigs(\DOMElement $node, $path)
242239

243240
return array($defaults, $requirements, $options, $condition);
244241
}
242+
243+
private function parseDefaultsConfig(\DOMElement $element)
244+
{
245+
if ($element->hasAttribute('xsi:nil') && 'true' == $element->getAttribute('xsi:nil')) {
246+
return null;
247+
}
248+
249+
if (1 === $element->childNodes->length && $element->firstChild instanceof \DOMText) {
250+
return trim($element->firstChild->textContent);
251+
}
252+
253+
$defaults = array();
254+
255+
foreach ($element->childNodes as $childNode) {
256+
if ($childNode instanceof \DOMText) {
257+
continue;
258+
}
259+
260+
$defaults[$childNode->getAttribute('key')] = $this->parseDefaultsConfig($childNode);
261+
}
262+
263+
return $defaults;
264+
}
245265
}

src/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
<xsd:group name="configs">
2828
<xsd:choice>
29-
<xsd:element name="default" nillable="true" type="element" />
29+
<xsd:element name="default" nillable="true" type="default" />
3030
<xsd:element name="requirement" type="element" />
3131
<xsd:element name="option" type="element" />
3232
<xsd:element name="condition" type="condition" />
@@ -55,6 +55,13 @@
5555
<xsd:attribute name="methods" type="xsd:string" />
5656
</xsd:complexType>
5757

58+
<xsd:complexType name="default" mixed="true">
59+
<xsd:choice minOccurs="0" maxOccurs="unbounded">
60+
<xsd:element name="default" type="default" />
61+
</xsd:choice>
62+
<xsd:attribute name="key" type="xsd:string" use="required" />
63+
</xsd:complexType>
64+
5865
<xsd:complexType name="element">
5966
<xsd:simpleContent>
6067
<xsd:extension base="xsd:string">
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<routes xmlns="http://symfony.com/schema/routing"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
5+
6+
<route id="blog" path="/blog">
7+
<default key="_controller">AcmeBlogBundle:Blog:index</default>
8+
<default key="page">1</default>
9+
<default key="foo">
10+
<default key="bar">1</default>
11+
<default key="baz">2</default>
12+
</default>
13+
<default key="foobar" xsi:nil="true" />
14+
</route>
15+
</routes>

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,24 @@ public function testDocTypeIsNotAllowed()
121121
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
122122
$loader->load('withdoctype.xml');
123123
}
124+
125+
public function testArrayDefaultsAreSupported()
126+
{
127+
$loader = new XmlFileLoader(new FileLocator(array(__DIR__.'/../Fixtures')));
128+
$routeCollection = $loader->load('array_defaults.xml');
129+
$route = $routeCollection->get('blog');
130+
131+
$this->assertEquals(
132+
array(
133+
'_controller' => 'AcmeBlogBundle:Blog:index',
134+
'page' => '1',
135+
'foo' => array(
136+
'bar' => '1',
137+
'baz' => '2',
138+
),
139+
'foobar' => null,
140+
),
141+
$route->getDefaults()
142+
);
143+
}
124144
}

0 commit comments

Comments
 (0)