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

Skip to content

Commit 9c628d0

Browse files
feature #47902 [DependencyInjection] Add support for tagged iterators/locators exclude option to xml and yaml (HypeMC)
This PR was merged into the 6.2 branch. Discussion ---------- [DependencyInjection] Add support for tagged iterators/locators exclude option to xml and yaml | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - Followup to #44774 . The previous PR added support for the `exclude` option to php attributes & php config files, but not xml or yaml, making it impossible to use this feature with those config types. Also, since the support for this feature was never added to the yaml & xml dumpers, the generated `App_KernelDevDebugContainer.xml` is actually incorrect (possibly should be considered a bug), eg the following php configuration: ```php $services->set(TestExclude::class) ->public() ->args([ tagged_iterator('app.test', exclude: TestExclude::class), ]); ``` produces this xml file: ```xml <service id="App\Service\TestExclude" class="App\Service\TestExclude" public="true"> <tag name="app.test"/> <argument type="tagged_iterator" tag="app.test"/> </service> ``` With this PR, the dumpers are now aware of the `exclude` option: ```diff <service id="App\Service\TestExclude" class="App\Service\TestExclude" public="true"> <tag name="app.test"/> - <argument type="tagged_iterator" tag="app.test"/> + <argument type="tagged_iterator" tag="app.test" exclude="App\Service\TestExclude"/> </service> ``` Commits ------- 9afa5c9 [DI] Add support for tagged iterators/locators `exclude` option to xml and yaml
2 parents 5b4236a + 9afa5c9 commit 9c628d0

File tree

12 files changed

+126
-4
lines changed

12 files changed

+126
-4
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ CHANGELOG
1212
* Change the signature of `ContainerAwareInterface::setContainer()` to `setContainer(?ContainerInterface)`
1313
* Deprecate calling `ContainerAwareTrait::setContainer()` without arguments
1414
* Deprecate using numeric parameter names
15+
* Add support for tagged iterators/locators `exclude` option to the xml and yaml loaders/dumpers
1516

1617
6.1
1718
---

src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,15 @@ private function convertParameters(array $parameters, string $type, \DOMElement
287287
$element->setAttribute('default-priority-method', $tag->getDefaultPriorityMethod());
288288
}
289289
}
290+
if ($excludes = $tag->getExclude()) {
291+
if (1 === \count($excludes)) {
292+
$element->setAttribute('exclude', $excludes[0]);
293+
} else {
294+
foreach ($excludes as $exclude) {
295+
$element->appendChild($this->document->createElement('exclude', $exclude));
296+
}
297+
}
298+
}
290299
} elseif ($value instanceof IteratorArgument) {
291300
$element->setAttribute('type', 'iterator');
292301
$this->convertParameters($value->getValues(), $type, $element, 'key');

src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,12 @@ private function dumpValue(mixed $value): mixed
266266
$content['default_priority_method'] = $tag->getDefaultPriorityMethod();
267267
}
268268
}
269+
if ($excludes = $tag->getExclude()) {
270+
if (!\is_array($content)) {
271+
$content = ['tag' => $content];
272+
}
273+
$content['exclude'] = 1 === \count($excludes) ? $excludes[0] : $excludes;
274+
}
269275

270276
return new TaggedValue($value instanceof TaggedIteratorArgument ? 'tagged_iterator' : 'tagged_locator', $content);
271277
}

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,15 @@ private function getArgumentsAsPhp(\DOMElement $node, string $name, string $file
538538
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="%s" has no or empty "tag" attribute in "%s".', $name, $type, $file));
539539
}
540540

541-
$arguments[$key] = new TaggedIteratorArgument($arg->getAttribute('tag'), $arg->getAttribute('index-by') ?: null, $arg->getAttribute('default-index-method') ?: null, $forLocator, $arg->getAttribute('default-priority-method') ?: null);
541+
$excludes = array_column($this->getChildren($arg, 'exclude'), 'nodeValue');
542+
if ($arg->hasAttribute('exclude')) {
543+
if (\count($excludes) > 0) {
544+
throw new InvalidArgumentException('You cannot use both the attribute "exclude" and <exclude> tags at the same time.');
545+
}
546+
$excludes = [$arg->getAttribute('exclude')];
547+
}
548+
549+
$arguments[$key] = new TaggedIteratorArgument($arg->getAttribute('tag'), $arg->getAttribute('index-by') ?: null, $arg->getAttribute('default-index-method') ?: null, $forLocator, $arg->getAttribute('default-priority-method') ?: null, $excludes);
542550

543551
if ($forLocator) {
544552
$arguments[$key] = new ServiceLocatorArgument($arguments[$key]);

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -832,11 +832,11 @@ private function resolveServices(mixed $value, string $file, bool $isParameter =
832832
$forLocator = 'tagged_locator' === $value->getTag();
833833

834834
if (\is_array($argument) && isset($argument['tag']) && $argument['tag']) {
835-
if ($diff = array_diff(array_keys($argument), ['tag', 'index_by', 'default_index_method', 'default_priority_method'])) {
836-
throw new InvalidArgumentException(sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "tag", "index_by", "default_index_method", and "default_priority_method".', $value->getTag(), implode('", "', $diff)));
835+
if ($diff = array_diff(array_keys($argument), $supportedKeys = ['tag', 'index_by', 'default_index_method', 'default_priority_method', 'exclude'])) {
836+
throw new InvalidArgumentException(sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "%s".', $value->getTag(), implode('", "', $diff), implode('", "', $supportedKeys)));
837837
}
838838

839-
$argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator, $argument['default_priority_method'] ?? null);
839+
$argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator, $argument['default_priority_method'] ?? null, (array) ($argument['exclude'] ?? null));
840840
} elseif (\is_string($argument) && $argument) {
841841
$argument = new TaggedIteratorArgument($argument, null, null, $forLocator);
842842
} else {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@
284284
<xsd:choice minOccurs="0">
285285
<xsd:element name="argument" type="argument" maxOccurs="unbounded" />
286286
<xsd:element name="service" type="service" />
287+
<xsd:element name="exclude" type="xsd:string" maxOccurs="unbounded" />
287288
</xsd:choice>
288289
<xsd:attribute name="type" type="argument_type" />
289290
<xsd:attribute name="id" type="xsd:string" />
@@ -294,6 +295,7 @@
294295
<xsd:attribute name="index-by" type="xsd:string" />
295296
<xsd:attribute name="default-index-method" type="xsd:string" />
296297
<xsd:attribute name="default-priority-method" type="xsd:string" />
298+
<xsd:attribute name="exclude" type="xsd:string" />
297299
</xsd:complexType>
298300

299301
<xsd:complexType name="call">

src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,16 +203,40 @@ public function testDumpLoad()
203203
public function testTaggedArguments()
204204
{
205205
$taggedIterator = new TaggedIteratorArgument('foo_tag', 'barfoo', 'foobar', false, 'getPriority');
206+
$taggedIterator2 = new TaggedIteratorArgument('foo_tag', null, null, false, null, ['baz']);
207+
$taggedIterator3 = new TaggedIteratorArgument('foo_tag', null, null, false, null, ['baz', 'qux']);
208+
206209
$container = new ContainerBuilder();
210+
207211
$container->register('foo', 'Foo')->addTag('foo_tag');
212+
$container->register('baz', 'Baz')->addTag('foo_tag');
213+
$container->register('qux', 'Qux')->addTag('foo_tag');
214+
208215
$container->register('foo_tagged_iterator', 'Bar')
209216
->setPublic(true)
210217
->addArgument($taggedIterator)
211218
;
219+
$container->register('foo2_tagged_iterator', 'Bar')
220+
->setPublic(true)
221+
->addArgument($taggedIterator2)
222+
;
223+
$container->register('foo3_tagged_iterator', 'Bar')
224+
->setPublic(true)
225+
->addArgument($taggedIterator3)
226+
;
227+
212228
$container->register('foo_tagged_locator', 'Bar')
213229
->setPublic(true)
214230
->addArgument(new ServiceLocatorArgument($taggedIterator))
215231
;
232+
$container->register('foo2_tagged_locator', 'Bar')
233+
->setPublic(true)
234+
->addArgument(new ServiceLocatorArgument($taggedIterator2))
235+
;
236+
$container->register('foo3_tagged_locator', 'Bar')
237+
->setPublic(true)
238+
->addArgument(new ServiceLocatorArgument($taggedIterator3))
239+
;
216240

217241
$dumper = new XmlDumper($container);
218242
$this->assertStringEqualsFile(self::$fixturesPath.'/xml/services_with_tagged_arguments.xml', $dumper->dump());

src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,22 @@ public function testInlineServices()
112112
public function testTaggedArguments()
113113
{
114114
$taggedIterator = new TaggedIteratorArgument('foo', 'barfoo', 'foobar', false, 'getPriority');
115+
$taggedIterator2 = new TaggedIteratorArgument('foo', null, null, false, null, ['baz']);
116+
$taggedIterator3 = new TaggedIteratorArgument('foo', null, null, false, null, ['baz', 'qux']);
117+
115118
$container = new ContainerBuilder();
119+
116120
$container->register('foo_service', 'Foo')->addTag('foo');
121+
$container->register('baz_service', 'Baz')->addTag('foo');
122+
$container->register('qux_service', 'Qux')->addTag('foo');
123+
117124
$container->register('foo_service_tagged_iterator', 'Bar')->addArgument($taggedIterator);
125+
$container->register('foo2_service_tagged_iterator', 'Bar')->addArgument($taggedIterator2);
126+
$container->register('foo3_service_tagged_iterator', 'Bar')->addArgument($taggedIterator3);
127+
118128
$container->register('foo_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument($taggedIterator));
129+
$container->register('foo2_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument($taggedIterator2));
130+
$container->register('foo3_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument($taggedIterator3));
119131
$container->register('bar_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('foo')));
120132

121133
$dumper = new YamlDumper($container);

src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_with_tagged_arguments.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,35 @@
55
<service id="foo" class="Foo">
66
<tag name="foo_tag"/>
77
</service>
8+
<service id="baz" class="Baz">
9+
<tag name="foo_tag"/>
10+
</service>
11+
<service id="qux" class="Qux">
12+
<tag name="foo_tag"/>
13+
</service>
814
<service id="foo_tagged_iterator" class="Bar" public="true">
915
<argument type="tagged_iterator" tag="foo_tag" index-by="barfoo" default-index-method="foobar" default-priority-method="getPriority"/>
1016
</service>
17+
<service id="foo2_tagged_iterator" class="Bar" public="true">
18+
<argument type="tagged_iterator" tag="foo_tag" exclude="baz"/>
19+
</service>
20+
<service id="foo3_tagged_iterator" class="Bar" public="true">
21+
<argument type="tagged_iterator" tag="foo_tag">
22+
<exclude>baz</exclude>
23+
<exclude>qux</exclude>
24+
</argument>
25+
</service>
1126
<service id="foo_tagged_locator" class="Bar" public="true">
1227
<argument type="tagged_locator" tag="foo_tag" index-by="barfoo" default-index-method="foobar" default-priority-method="getPriority"/>
1328
</service>
29+
<service id="foo2_tagged_locator" class="Bar" public="true">
30+
<argument type="tagged_locator" tag="foo_tag" exclude="baz"/>
31+
</service>
32+
<service id="foo3_tagged_locator" class="Bar" public="true">
33+
<argument type="tagged_locator" tag="foo_tag">
34+
<exclude>baz</exclude>
35+
<exclude>qux</exclude>
36+
</argument>
37+
</service>
1438
</services>
1539
</container>

src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_with_tagged_argument.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,32 @@ services:
88
class: Foo
99
tags:
1010
- foo
11+
baz_service:
12+
class: Baz
13+
tags:
14+
- foo
15+
qux_service:
16+
class: Qux
17+
tags:
18+
- foo
1119
foo_service_tagged_iterator:
1220
class: Bar
1321
arguments: [!tagged_iterator { tag: foo, index_by: barfoo, default_index_method: foobar, default_priority_method: getPriority }]
22+
foo2_service_tagged_iterator:
23+
class: Bar
24+
arguments: [!tagged_iterator { tag: foo, exclude: baz }]
25+
foo3_service_tagged_iterator:
26+
class: Bar
27+
arguments: [!tagged_iterator { tag: foo, exclude: [baz, qux] }]
1428
foo_service_tagged_locator:
1529
class: Bar
1630
arguments: [!tagged_locator { tag: foo, index_by: barfoo, default_index_method: foobar, default_priority_method: getPriority }]
31+
foo2_service_tagged_locator:
32+
class: Bar
33+
arguments: [!tagged_locator { tag: foo, exclude: baz }]
34+
foo3_service_tagged_locator:
35+
class: Bar
36+
arguments: [!tagged_locator { tag: foo, exclude: [baz, qux] }]
1737
bar_service_tagged_locator:
1838
class: Bar
1939
arguments: [!tagged_locator foo]

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,17 @@ public function testParseTaggedArgumentsWithIndexBy()
404404

405405
$taggedIterator = new TaggedIteratorArgument('foo_tag', 'barfoo', 'foobar', false, 'getPriority');
406406
$this->assertEquals($taggedIterator, $container->getDefinition('foo_tagged_iterator')->getArgument(0));
407+
$taggedIterator2 = new TaggedIteratorArgument('foo_tag', null, null, false, null, ['baz']);
408+
$this->assertEquals($taggedIterator2, $container->getDefinition('foo2_tagged_iterator')->getArgument(0));
409+
$taggedIterator3 = new TaggedIteratorArgument('foo_tag', null, null, false, null, ['baz', 'qux']);
410+
$this->assertEquals($taggedIterator3, $container->getDefinition('foo3_tagged_iterator')->getArgument(0));
407411

408412
$taggedIterator = new TaggedIteratorArgument('foo_tag', 'barfoo', 'foobar', true, 'getPriority');
409413
$this->assertEquals(new ServiceLocatorArgument($taggedIterator), $container->getDefinition('foo_tagged_locator')->getArgument(0));
414+
$taggedIterator2 = new TaggedIteratorArgument('foo_tag', 'foo_tag', 'getDefaultFooTagName', true, 'getDefaultFooTagPriority', ['baz']);
415+
$this->assertEquals(new ServiceLocatorArgument($taggedIterator2), $container->getDefinition('foo2_tagged_locator')->getArgument(0));
416+
$taggedIterator3 = new TaggedIteratorArgument('foo_tag', 'foo_tag', 'getDefaultFooTagName', true, 'getDefaultFooTagPriority', ['baz', 'qux']);
417+
$this->assertEquals(new ServiceLocatorArgument($taggedIterator3), $container->getDefinition('foo3_tagged_locator')->getArgument(0));
410418
}
411419

412420
public function testParseServiceClosure()

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,9 +392,17 @@ public function testTaggedArgumentsWithIndex()
392392

393393
$taggedIterator = new TaggedIteratorArgument('foo', 'barfoo', 'foobar', false, 'getPriority');
394394
$this->assertEquals($taggedIterator, $container->getDefinition('foo_service_tagged_iterator')->getArgument(0));
395+
$taggedIterator2 = new TaggedIteratorArgument('foo', null, null, false, null, ['baz']);
396+
$this->assertEquals($taggedIterator2, $container->getDefinition('foo2_service_tagged_iterator')->getArgument(0));
397+
$taggedIterator3 = new TaggedIteratorArgument('foo', null, null, false, null, ['baz', 'qux']);
398+
$this->assertEquals($taggedIterator3, $container->getDefinition('foo3_service_tagged_iterator')->getArgument(0));
395399

396400
$taggedIterator = new TaggedIteratorArgument('foo', 'barfoo', 'foobar', true, 'getPriority');
397401
$this->assertEquals(new ServiceLocatorArgument($taggedIterator), $container->getDefinition('foo_service_tagged_locator')->getArgument(0));
402+
$taggedIterator2 = new TaggedIteratorArgument('foo', 'foo', 'getDefaultFooName', true, 'getDefaultFooPriority', ['baz']);
403+
$this->assertEquals(new ServiceLocatorArgument($taggedIterator2), $container->getDefinition('foo2_service_tagged_locator')->getArgument(0));
404+
$taggedIterator3 = new TaggedIteratorArgument('foo', 'foo', 'getDefaultFooName', true, 'getDefaultFooPriority', ['baz', 'qux']);
405+
$this->assertEquals(new ServiceLocatorArgument($taggedIterator3), $container->getDefinition('foo3_service_tagged_locator')->getArgument(0));
398406

399407
$taggedIterator = new TaggedIteratorArgument('foo', null, null, true);
400408
$this->assertEquals(new ServiceLocatorArgument($taggedIterator), $container->getDefinition('bar_service_tagged_locator')->getArgument(0));

0 commit comments

Comments
 (0)