8000 Fix issue #50046 · zerustech/symfony@069c3b2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 069c3b2

Browse files
committed
Fix issue symfony#50046
1 parent 20ee89c commit 069c3b2

File tree

4 files changed

+112
-6
lines changed

4 files changed

+112
-6
lines changed

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,18 @@ private function processAnonymousServices(\DOMDocument $xml, string $file, \DOMN
457457
}
458458
}
459459

460-
private function getArgumentsAsPhp(\DOMElement $node, string $name, string $file, bool $isChildDefinition = false): array
460+
private function getArgumentsAsPhp(\DOMElement $node, string|array $names, string $file, bool $isChildDefinition = false): array
461461
{
462+
$names = !\is_array($names) ? [$names] : $names;
462463
$arguments = [];
463-
foreach ($this->getChildren($node, $name) as $arg) {
464+
$xpath = new \DOMXPath($node->ownerDocument);
465+
$xpath->registerNamespace('container', self::NS);
466+
$expression = [];
467+
foreach ($names as $name) {
468+
$expression[] = "./container:$name";
469+
}
470+
$expression = implode('|', $expression);
471+
foreach ($xpath->query($expression, $node) as $arg) {
464472
if ($arg->hasAttribute('name')) {
465473
$arg->setAttribute('key', $arg->getAttribute('name'));
466474
}
@@ -504,11 +512,11 @@ private function getArgumentsAsPhp(\DOMElement $node, string $name, string $file
504512
$arguments[$key] = new Expression($arg->nodeValue);
505513
break;
506514
case 'collection':
507-
$arguments[$key] = $this->getArgumentsAsPhp($arg, $name, $file);
508-
break;
509515
case 'iterator':
510-
$arg = $this->getArgumentsAsPhp($arg, $name, $file);
511-
$arguments[$key] = new IteratorArgument($arg);
516+
$argumentValues = [];
517+
$argumentNames = 'bind' === $arg->nodeName && 'bind' !== $arg->parentNode->nodeName ? [$name, 'argument'] : ['bind' === $arg->parentNode->nodeName ? 'argument' : $name];
518+
$argumentValues = $this->getArgumentsAsPhp($arg, $argumentNames, $file);
519+
$arguments[$key] = 'collection' === $type ? $argumentValues : new IteratorArgument($argumentValues);
512520
break;
513521
case 'closure':
514522
case 'service_closure':

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@
276276
<xsd:complexType name="bind" mixed="true">
277277
<xsd:choice maxOccurs="unbounded">
278278
<xsd:element name="bind" type="argument" minOccurs="0" maxOccurs="unbounded" />
279+
<xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
279280
<xsd:element name="service" type="service" />
280281
</xsd:choice>
281282
<xsd:attribute name="type" type="argument_type" />
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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 https://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<service id="bar1" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar" autowire="true">
5+
<bind key="$foo" type="collection">
6+
<bind>item.1</bind>
7+
<bind>item.2</bind>
8+
</bind>
9+
</service>
10+
<service id="bar2" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar" autowire="true">
11+
<bind key="$foo" type="collection">
12+
<argument>item.1</argument>
13+
<argument>item.2</argument>
14+
</bind>
15+
</service>
16+
<service id="bar3" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar" autowire="true">
17+
<bind key="$foo" type="collection">
18+
<argument>item.1</argument>
19+
<bind>item.2</bind>
20+
<argument>item.3</argument>
21+
<bind>item.4</bind>
22+
</bind>
23+
</service>
24+
<service id="bar4" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar" autowire="true">
25+
<bind key="$foo" type="collection">
26+
<argument>item.1</argument>
27+
<bind>item.2</bind>
28+
<argument key="1">item.3</argument>
29+
<bind>item.4</bind>
30+
</bind>
31+
</service>
32+
<service id="bar5" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar" autowire="true">
33+
<bind key="$foo" type="collection">
34+
<bind>item.1</bind>
35+
<bind>item.2</bind>
36+
<bind type="collection">
37+
<argument>item.3.1</argument>
38+
<argument>item.3.2</argument>
39+
</bind>
40+
</bind>
41+
</service>
42+
<service id="bar6" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar" autowire="true">
43+
<bind key="$foo" type="collection">
44+
<bind>item.1</bind>
45+
<argument type="collection">
46+
<argument>item.2.1</argument>
47+
<argument>item.2.2</argument>
48+
</argument>
49+
<bind>item.3</bind>
50+
</bind>
51+
</service>
52+
<service id="bar7" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar" autowire="true">
53+
<bind key="$foo" type="iterator">
54+
<bind>item.1</bind>
55+
<bind>item.2</bind>
56+
</bind>
57+
</service>
58+
<service id="bar8" class="Symfony\Component\DependencyInjection\Tests\Fixtures\Bar" autowire="true">
59+
<bind key="$foo" type="iterator">
60+
<bind>item.1</bind>
61+
<bind>item.2</bind>
62+
<bind type="collection">
63+
<argument>item.3.1</argument>
64+
<argument>item.3.2</argument>
65+
</bind>
66+
</bind>
67+
</service>
68+
</services>
69+
</container>

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,4 +1166,32 @@ public function testClosure()
11661166
$definition = $container->getDefinition('closure_property')->getProperties()['foo'];
11671167
$this->assertEquals((new Definition('Closure'))->setFactory(['Closure', 'fromCallable'])->addArgument(new Reference('bar')), $definition);
11681168
}
1169+
1170+
/**
1171+
* @dataProvider dataForBindingsAndInnerCollections
1172+
*/
1173+
public function testBindingsAndInnerCollections($bindName, $expected)
1174+
{
1175+
$container = new ContainerBuilder();
1176+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
1177+
$loader->load('bindings_and_inner_collections.xml');
1178+
(new ResolveBindingsPass())->process($container);
1179+
$definition = $container->getDefinition($bindName);
1180+
$actual = $definition->getBindings()['$foo']->getValues()[0];
1181+
$this->assertEquals($actual, $expected);
1182+
}
1183+
1184+
public function dataForBindingsAndInnerCollections()
1185+
{
1186+
return [
1187+
['bar1', ['item.1', 'item.2']],
1188+
['bar2', ['item.1', 'item.2']],
1189+
['bar3', ['item.1', 'item.2', 'item.3', 'item.4']],
1190+
['bar4', ['item.1', 'item.3', 'item.4']],
1191+
['bar5', ['item.1', 'item.2', ['item.3.1', 'item.3.2']]],
1192+
['bar6', ['item.1', ['item.2.1', 'item.2.2'], 'item.3']],
1193+
['bar7', new IteratorArgument(['item.1', 'item.2'])],
1194+
['bar8', new IteratorArgument(['item.1', 'item.2', ['item.3.1', 'item.3.2']])],
1195+
];
1196+
}
11691197
}

0 commit comments

Comments
 (0)
0