Skip to content

Commit 2cc8c75

Browse files
committed
[DependencyInjection] Add ContainerBuilder::findTaggedValueClasses
1 parent 04551ad commit 2cc8c75

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Make `#[AsTaggedItem]` repeatable
88
* Support `@>` as a shorthand for `!service_closure` in yaml files
9+
* Add `ContainerBuilder::findTaggedValueClasses()` for auto-discovering value-object classes
910

1011
7.2
1112
---

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,30 @@ public function findTaggedServiceIds(string $name, bool $throwOnAbstract = false
13511351
return $tags;
13521352
}
13531353

1354+
/**
1355+
* Find definitions of value-object classes by tag, and add the "container.excluded" tag to them.
1356+
*
1357+
* @param bool $autoExclude Adds the "container.excluded" tag to the returned definitions
1358+
*
1359+
* @return array<string, array> An array of tags with the tagged classes as key, holding a list of attribute arrays
1360+
*/
1361+
public function findTaggedValueClasses(string $name, bool $autoExclude = true): array
1362+
{
1363+
$this->usedTags[] = $name;
1364+
$tags = [];
1365+
foreach ($this->getDefinitions() as $id => $definition) {
1366+
if ($definition->hasTag($name)) {
1367+
if ($autoExclude) {
1368+
$definition->addTag('container.excluded', ['source' => \sprintf('by tag "%s"', $name)]);
1369+
}
1370+
1371+
$tags[$id] = $definition->getTag($name);
1372+
}
1373+
}
1374+
1375+
return $tags;
1376+
}
1377+
13541378
/**
13551379
* Returns all tags the defined services use.
13561380
*

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,11 +1062,12 @@ public function testMergeLogicException()
10621062
$container->merge(new ContainerBuilder());
10631063
}
10641064

1065-
public function testfindTaggedServiceIds()
1065+
public function testFindTaggedServiceIds()
10661066
{
10671067
$builder = new ContainerBuilder();
10681068
$builder
10691069
->register('foo', 'Bar\FooClass')
1070+
->setAbstract(true)
10701071
->addTag('foo', ['foo' => 'foo'])
10711072
->addTag('bar', ['bar' => 'bar'])
10721073
->addTag('foo', ['foofoo' => 'foofoo'])
@@ -1083,6 +1084,34 @@ public function testfindTaggedServiceIds()
10831084
],
10841085
], $builder->findTaggedServiceIds('foo'), '->findTaggedServiceIds() returns an array of service ids and its tag attributes');
10851086
$this->assertEquals([], $builder->findTaggedServiceIds('foobar'), '->findTaggedServiceIds() returns an empty array if there is annotated services');
1087+
$this->expectException(InvalidArgumentException::class);
1088+
$this->expectExceptionMessage('The service "foo" tagged "foo" must not be abstract.');
1089+
$builder->findTaggedServiceIds('foo', true);
1090+
}
1091+
1092+
public function testFindTaggedValueClasses()
1093+
{
1094+
$builder = new ContainerBuilder();
1095+
$builder
1096+
->register('foo', 'Bar\FooClass')
1097+
->setAbstract(true)
1098+
->addTag('foo', ['foo' => 'foo'])
1099+
->addTag('bar', ['bar' => 'bar'])
1100+
->addTag('foo', ['foofoo' => 'foofoo'])
1101+
;
1102+
1103+
$expected = [
1104+
'foo' => [
1105+
['foo' => 'foo'],
1106+
['foofoo' => 'foofoo'],
1107+
],
1108+
];
1109+
1110+
$this->assertEquals($expected, $builder->findTaggedValueClasses('foo', false));
1111+
$this->assertFalse($builder->getDefinition('foo')->hasTag('container.excluded'));
1112+
1113+
$this->assertEquals($expected, $builder->findTaggedValueClasses('foo'));
1114+
$this->assertTrue($builder->getDefinition('foo')->hasTag('container.excluded'));
10861115
}
10871116

10881117
public function testFindUnusedTags()

0 commit comments

Comments
 (0)