bug #33436 [DI] fix support for "!tagged_locator foo" (nicolas-grekas)

This PR was merged into the 4.3 branch.

Discussion
----------

[DI] fix support for "!tagged_locator foo"

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Spotted during the workshop at WebSummerCamp

Commits
-------

a9f75692c9 [DI] fix support for "!tagged_locator foo"
This commit is contained in:
Fabien Potencier 2019-09-03 06:48:04 +02:00
commit 4ee3c6bd6a
5 changed files with 17 additions and 12 deletions

View File

@ -124,7 +124,7 @@ function tagged(string $tag, string $indexAttribute = null, string $defaultIndex
/** /**
* Creates a service locator by tag name. * Creates a service locator by tag name.
*/ */
function tagged_locator(string $tag, string $indexAttribute, string $defaultIndexMethod = null): ServiceLocatorArgument function tagged_locator(string $tag, string $indexAttribute = null, string $defaultIndexMethod = null): ServiceLocatorArgument
{ {
return new ServiceLocatorArgument(new TaggedIteratorArgument($tag, $indexAttribute, $defaultIndexMethod, true)); return new ServiceLocatorArgument(new TaggedIteratorArgument($tag, $indexAttribute, $defaultIndexMethod, true));
} }

View File

@ -726,25 +726,23 @@ class YamlFileLoader extends FileLoader
if (\in_array($value->getTag(), ['tagged', 'tagged_locator'], true)) { if (\in_array($value->getTag(), ['tagged', 'tagged_locator'], true)) {
$forLocator = 'tagged_locator' === $value->getTag(); $forLocator = 'tagged_locator' === $value->getTag();
if (\is_string($argument) && $argument) {
return new TaggedIteratorArgument($argument, null, null, $forLocator);
}
if (\is_array($argument) && isset($argument['tag']) && $argument['tag']) { if (\is_array($argument) && isset($argument['tag']) && $argument['tag']) {
if ($diff = array_diff(array_keys($argument), ['tag', 'index_by', 'default_index_method'])) { if ($diff = array_diff(array_keys($argument), ['tag', 'index_by', 'default_index_method'])) {
throw new InvalidArgumentException(sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "tag", "index_by" and "default_index_method".', $value->getTag(), implode('"", "', $diff))); throw new InvalidArgumentException(sprintf('"!%s" tag contains unsupported key "%s"; supported ones are "tag", "index_by" and "default_index_method".', $value->getTag(), implode('"", "', $diff)));
} }
$argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator); $argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator);
} elseif (\is_string($argument) && $argument) {
if ($forLocator) { $argument = new TaggedIteratorArgument($argument, null, null, $forLocator);
$argument = new ServiceLocatorArgument($argument); } else {
} throw new InvalidArgumentException(sprintf('"!%s" tags only accept a non empty string or an array with a key "tag" in "%s".', $value->getTag(), $file));
return $argument;
} }
throw new InvalidArgumentException(sprintf('"!%s" tags only accept a non empty string or an array with a key "tag" in "%s".', $value->getTag(), $file)); if ($forLocator) {
$argument = new ServiceLocatorArgument($argument);
}
return $argument;
} }
if ('service' === $value->getTag()) { if ('service' === $value->getTag()) {
if ($isParameter) { if ($isParameter) {

View File

@ -104,6 +104,7 @@ class YamlDumperTest extends TestCase
$container->register('foo_service', 'Foo')->addTag('foo'); $container->register('foo_service', 'Foo')->addTag('foo');
$container->register('foo_service_tagged_iterator', 'Bar')->addArgument($taggedIterator); $container->register('foo_service_tagged_iterator', 'Bar')->addArgument($taggedIterator);
$container->register('foo_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument($taggedIterator)); $container->register('foo_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument($taggedIterator));
$container->register('bar_service_tagged_locator', 'Bar')->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('foo')));
$dumper = new YamlDumper($container); $dumper = new YamlDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_tagged_argument.yml', $dumper->dump()); $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_tagged_argument.yml', $dumper->dump());

View File

@ -14,6 +14,9 @@ services:
foo_service_tagged_locator: foo_service_tagged_locator:
class: Bar class: Bar
arguments: [!tagged_locator { tag: foo, index_by: barfoo, default_index_method: foobar }] arguments: [!tagged_locator { tag: foo, index_by: barfoo, default_index_method: foobar }]
bar_service_tagged_locator:
class: Bar
arguments: [!tagged_locator foo]
Psr\Container\ContainerInterface: Psr\Container\ContainerInterface:
alias: service_container alias: service_container
public: false public: false

View File

@ -305,6 +305,9 @@ class YamlFileLoaderTest extends TestCase
$taggedIterator = new TaggedIteratorArgument('foo', 'barfoo', 'foobar', true); $taggedIterator = new TaggedIteratorArgument('foo', 'barfoo', 'foobar', true);
$this->assertEquals(new ServiceLocatorArgument($taggedIterator), $container->getDefinition('foo_service_tagged_locator')->getArgument(0)); $this->assertEquals(new ServiceLocatorArgument($taggedIterator), $container->getDefinition('foo_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));
} }
public function testNameOnlyTagsAreAllowedAsString() public function testNameOnlyTagsAreAllowedAsString()