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

Skip to content

[DependencyInjection] Add support for tagged iterators/locators exclude option to xml and yaml #47902

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Symfony/Component/DependencyInjection/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CHANGELOG
* Change the signature of `ContainerAwareInterface::setContainer()` to `setContainer(?ContainerInterface)`
* Deprecate calling `ContainerAwareTrait::setContainer()` without arguments
* Deprecate using numeric parameter names
* Add support for tagged iterators/locators `exclude` option to the xml and yaml loaders/dumpers

6.1
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,15 @@ private function convertParameters(array $parameters, string $type, \DOMElement
$element->setAttribute('default-priority-method', $tag->getDefaultPriorityMethod());
}
}
if ($excludes = $tag->getExclude()) {
if (1 === \count($excludes)) {
$element->setAttribute('exclude', $excludes[0]);
} else {
foreach ($excludes as $exclude) {
$element->appendChild($this->document->createElement('exclude', $exclude));
}
}
}
} elseif ($value instanceof IteratorArgument) {
$element->setAttribute('type', 'iterator');
$this->convertParameters($value->getValues(), $type, $element, 'key');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@ private function dumpValue(mixed $value): mixed
$content['default_priority_method'] = $tag->getDefaultPriorityMethod();
}
}
if ($excludes = $tag->getExclude()) {
if (!\is_array($content)) {
$content = ['tag' => $content];
}
$content['exclude'] = 1 === \count($excludes) ? $excludes[0] : $excludes;
}

return new TaggedValue($value instanceof TaggedIteratorArgument ? 'tagged_iterator' : 'tagged_locator', $content);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,15 @@ private function getArgumentsAsPhp(\DOMElement $node, string $name, string $file
throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="%s" has no or empty "tag" attribute in "%s".', $name, $type, $file));
}

$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 = array_column($this->getChildren($arg, 'exclude'), 'nodeValue');
if ($arg->hasAttribute('exclude')) {
if (\count($excludes) > 0) {
throw new InvalidArgumentException('You cannot use both the attribute "exclude" and <exclude> tags at the same time.');
}
$excludes = [$arg->getAttribute('exclude')];
}

$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);

if ($forLocator) {
$arguments[$key] = new ServiceLocatorArgument($arguments[$key]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -832,11 +832,11 @@ private function resolveServices(mixed $value, string $file, bool $isParameter =
$forLocator = 'tagged_locator' === $value->getTag();

if (\is_array($argument) && isset($argument['tag']) && $argument['tag']) {
if ($diff = array_diff(array_keys($argument), ['tag', 'index_by', 'default_index_method', 'default_priority_method'])) {
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)));
if ($diff = array_diff(array_keys($argument), $supportedKeys = ['tag', 'index_by', 'default_index_method', 'default_priority_method', 'exclude'])) {
throw new InvalidArgumentException(sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "%s".', $value->getTag(), implode('", "', $diff), implode('", "', $supportedKeys)));
}

$argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator, $argument['default_priority_method'] ?? null);
$argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator, $argument['default_priority_method'] ?? null, (array) ($argument['exclude'] ?? null));
} elseif (\is_string($argument) && $argument) {
$argument = new TaggedIteratorArgument($argument, null, null, $forLocator);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
<xsd:choice minOccurs="0">
<xsd:element name="argument" type="argument" maxOccurs="unbounded" />
<xsd:element name="service" type="service" />
<xsd:element name="exclude" type="xsd:string" maxOccurs="unbounded" />
</xsd:choice>
<xsd:attribute name="type" type="argument_type" />
<xsd:attribute name="id" type="xsd:string" />
Expand All @@ -294,6 +295,7 @@
<xsd:attribute name="index-by" type="xsd:string" />
<xsd:attribute name="default-index-method" type="xsd:string" />
<xsd:attribute name="default-priority-method" type="xsd:string" />
<xsd:attribute name="exclude" type="xsd:string" />
</xsd:complexType>

<xsd:complexType name="call">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,16 +203,40 @@ public function testDumpLoad()
public function testTaggedArguments()
{
$taggedIterator = new TaggedIteratorArgument('foo_tag', 'barfoo', 'foobar', false, 'getPriority');
$taggedIterator2 = new TaggedIteratorArgument('foo_tag', null, null, false, null, ['baz']);
$taggedIterator3 = new TaggedIteratorArgument('foo_tag', null, null, false, null, ['baz', 'qux']);

$container = new ContainerBuilder();

$container->register('foo', 'Foo')->addTag('foo_tag');
$container->register('baz', 'Baz')->addTag('foo_tag');
$container->register('qux', 'Qux')->addTag('foo_tag');

$container->register('foo_tagged_iterator', 'Bar')
->setPublic(true)
->addArgument($taggedIterator)
;
$container->register('foo2_tagged_iterator', 'Bar')
->setPublic(true)
->addArgument($taggedIterator2)
;
$container->register('foo3_tagged_iterator', 'Bar')
->setPublic(true)
->addArgument($taggedIterator3)
;

$container->register('foo_tagged_locator', 'Bar')
->setPublic(true)
->addArgument(new ServiceLocatorArgument($taggedIterator))
;
$container->register('foo2_tagged_locator', 'Bar')
->setPublic(true)
->addArgument(new ServiceLocatorArgument($taggedIterator2))
;
$container->register('foo3_tagged_locator', 'Bar')
->setPublic(true)
->addArgument(new ServiceLocatorArgument($taggedIterator3))
;

$dumper = new XmlDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/xml/services_with_tagged_arguments.xml', $dumper->dump());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,22 @@ public function testInlineServices()
public function testTaggedArguments()
{
$taggedIterator = new TaggedIteratorArgument('foo', 'barfoo', 'foobar', false, 'getPriority');
$taggedIterator2 = new TaggedIteratorArgument('foo', null, null, false, null, ['baz']);
$taggedIterator3 = new TaggedIteratorArgument('foo', null, null, false, null, ['baz', 'qux']);

$container = new ContainerBuilder();

$container->register('foo_service', 'Foo')->addTag('foo');
$container->register('baz_service', 'Baz')->addTag('foo');
$container->register('qux_service', 'Qux')->addTag('foo');

$container->register('foo_service_tagged_iterator', 'Bar')->addArgument($taggedIterator);
$container->register('foo2_service_tagged_iterator', 'Bar')->addArgument($taggedIterator2);
$container->register('foo3_service_tagged_iterator', 'Bar')->addArgument($taggedIterator3);

$container->register('foo_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument($taggedIterator));
$container->register('foo2_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument($taggedIterator2));
$container->register('foo3_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument($taggedIterator3));
$container->register('bar_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('foo')));

$dumper = new YamlDumper($container);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,35 @@
<service id="foo" class="Foo">
<tag name="foo_tag"/>
</service>
<service id="baz" class="Baz">
<tag name="foo_tag"/>
</service>
<service id="qux" class="Qux">
<tag name="foo_tag"/>
</service>
<service id="foo_tagged_iterator" class="Bar" public="true">
<argument type="tagged_iterator" tag="foo_tag" index-by="barfoo" default-index-method="foobar" default-priority-method="getPriority"/>
</service>
<service id="foo2_tagged_iterator" class="Bar" public="true">
<argument type="tagged_iterator" tag="foo_tag" exclude="baz"/>
</service>
<service id="foo3_tagged_iterator" class="Bar" public="true">
<argument type="tagged_iterator" tag="foo_tag">
<exclude>baz</exclude>
<exclude>qux</exclude>
</argument>
</service>
<service id="foo_tagged_locator" class="Bar" public="true">
<argument type="tagged_locator" tag="foo_tag" index-by="barfoo" default-index-method="foobar" default-priority-method="getPriority"/>
</service>
<service id="foo2_tagged_locator" class="Bar" public="true">
<argument type="tagged_locator" tag="foo_tag" exclude="baz"/>
</service>
<service id="foo3_tagged_locator" class="Bar" public="true">
<argument type="tagged_locator" tag="foo_tag">
<exclude>baz</exclude>
<exclude>qux</exclude>
</argument>
</service>
</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,32 @@ services:
class: Foo
tags:
- foo
baz_service:
class: Baz
tags:
- foo
qux_service:
class: Qux
tags:
- foo
foo_service_tagged_iterator:
class: Bar
arguments: [!tagged_iterator { tag: foo, index_by: barfoo, default_index_method: foobar, default_priority_method: getPriority }]
foo2_service_tagged_iterator:
class: Bar
arguments: [!tagged_iterator { tag: foo, exclude: baz }]
foo3_service_tagged_iterator:
class: Bar
arguments: [!tagged_iterator { tag: foo, exclude: [baz, qux] }]
foo_service_tagged_locator:
class: Bar
arguments: [!tagged_locator { tag: foo, index_by: barfoo, default_index_method: foobar, default_priority_method: getPriority }]
foo2_service_tagged_locator:
class: Bar
arguments: [!tagged_locator { tag: foo, exclude: baz }]
foo3_service_tagged_locator:
class: Bar
arguments: [!tagged_locator { tag: foo, exclude: [baz, qux] }]
bar_service_tagged_locator:
class: Bar
arguments: [!tagged_locator foo]
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,17 @@ public function testParseTaggedArgumentsWithIndexBy()

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

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

public function testParseServiceClosure()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,17 @@ public function testTaggedArgumentsWithIndex()

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

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

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