Skip to content

Commit

Permalink
bug #33436 [DI] fix support for "!tagged_locator foo" (nicolas-grekas)
Browse files Browse the repository at this point in the history
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
-------

a9f7569 [DI] fix support for "!tagged_locator foo"
  • Loading branch information
fabpot committed Sep 3, 2019
2 parents d26a656 + a9f7569 commit 4ee3c6b
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 11 deletions.
Expand Up @@ -124,7 +124,7 @@ function tagged(string $tag, string $indexAttribute = null, string $defaultIndex
/**
* 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));
}
Expand Down
Expand Up @@ -726,25 +726,23 @@ private function resolveServices($value, $file, $isParameter = false)
if (\in_array($value->getTag(), ['tagged', 'tagged_locator'], true)) {
$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 ($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)));
}

$argument = new TaggedIteratorArgument($argument['tag'], $argument['index_by'] ?? null, $argument['default_index_method'] ?? null, $forLocator);
} elseif (\is_string($argument) && $argument) {
$argument = new TaggedIteratorArgument($argument, null, null, $forLocator);
} 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));
}

if ($forLocator) {
$argument = new ServiceLocatorArgument($argument);
}

return $argument;
if ($forLocator) {
$argument = new ServiceLocatorArgument($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));
return $argument;
}
if ('service' === $value->getTag()) {
if ($isParameter) {
Expand Down
Expand Up @@ -104,6 +104,7 @@ public function testTaggedArguments()
$container->register('foo_service', 'Foo')->addTag('foo');
$container->register('foo_service_tagged_iterator', 'Bar')->addArgument($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);
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_tagged_argument.yml', $dumper->dump());
Expand Down
Expand Up @@ -14,6 +14,9 @@ services:
foo_service_tagged_locator:
class: Bar
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:
alias: service_container
public: false
Expand Down
Expand Up @@ -305,6 +305,9 @@ public function testTaggedArgumentsWithIndex()

$taggedIterator = new TaggedIteratorArgument('foo', 'barfoo', 'foobar', true);
$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()
Expand Down

0 comments on commit 4ee3c6b

Please sign in to comment.