8000 autoconfigure behavior describing tags on decorators · lucasaba/symfony@73a3b83 · GitHub
[go: up one dir, main page]

Skip to content

Commit 73a3b83

Browse files
committed
autoconfigure behavior describing tags on decorators
1 parent e5ec204 commit 73a3b83

File tree

4 files changed

+98
-6
lines changed

4 files changed

+98
-6
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,14 @@ public function load(array $configs, ContainerBuilder $container)
470470

471471
$container->registerForAutoconfiguration(RouteLoaderInterface::class)
472472
->addTag('routing.route_loader');
473+
474+
$container->setParameter('container.behavior_describing_tags', [
475+
'container.service_locator',
476+
'container.service_subscriber',
477+
'kernel.event_subscriber',
478+
'kernel.locale_aware',
479+
'kernel.reset',
480+
]);
473481
}
474482

475483
/**

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,20 @@ public function testMailer(string $configFile, array $expectedTransports): void
16561656
$this->assertSame(['redirected@example.org', 'redirected1@example.org'], $l->getArgument(1));
16571657
}
16581658

1659+
public function testRegisterParameterCollectingBehaviorDescribingTags()
1660+
{
1661+
$container = $this->createContainerFromFile('default_config');
1662+
1663+
$this->assertTrue($container->hasParameter('container.behavior_describing_tags'));
1664+
$this->assertEquals([
1665+
'container.service_locator',
1666+
'container.service_subscriber',
1667+
'kernel.event_subscriber',
1668+
'kernel.locale_aware',
1669+
'kernel.reset',
1670+
], $container->getParameter('container.behavior_describing_tags'));
1671+
}
1672+
16591673
protected function createContainer(array $data = [])
16601674
{
16611675
return new ContainerBuilder(new EnvPlaceholderParameterBag(array_merge([

src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,26 @@ public function process(ContainerBuilder $container)
3535
}
3636
}
3737

38+
$tagsToKeep = [];
39+
40+
if ($container->hasParameter('container.behavior_describing_tags')) {
41+
$tagsToKeep = $container->getParameter('container.behavior_describing_tags');
42+
}
43+
3844
foreach ($container->getDefinitions() as $id => $definition) {
3945
if ($definition instanceof ChildDefinition) {
4046
// don't apply "instanceof" to children: it will be applied to their parent
4147
continue;
4248
}
43-
$container->setDefinition($id, $this->processDefinition($container, $id, $definition));
49+
$container->setDefinition($id, $this->processDefinition($container, $id, $definition, $tagsToKeep));
50+
}
51+
52+
if ($container->hasParameter('container.behavior_describing_tags')) {
53+
$container->getParameterBag()->remove('container.behavior_describing_tags');
4454
}
4555
}
4656

47-
private function processDefinition(ContainerBuilder $container, string $id, Definition $definition): Definition
57+
private function processDefinition(ContainerBuilder $container, string $id, Definition $definition, array $tagsToKeep): Definition
4858
{
4959
$instanceofConditionals = $definition->getInstanceofConditionals();
5060
$autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
@@ -115,10 +125,10 @@ private function processDefinition(ContainerBuilder $container, string $id, Defi
115125
}
116126

117127
// Don't add tags to service decorators
118-
if (null === $definition->getDecoratedService()) {
119-
$i = \count($instanceofTags);
120-
while (0 <= --$i) {
121< 629A /code>-
foreach ($instanceofTags[$i] as $k => $v) {
128+
$i = \count($instanceofTags);
129+
while (0 <= --$i) {
130+
foreach ($instanceofTags[$i] as $k => $v) {
131+
if (null === $definition->getDecoratedService() || \in_array($k, $tagsToKeep, true)) {
122132
foreach ($v as $v) {
123133
if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) {
124134
continue;

src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@
1212
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Config\Resource\ResourceInterface;
16+
use Symfony\Component\Config\ResourceCheckerInterface;
1517
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
1618
use Symfony\Component\DependencyInjection\ChildDefinition;
1719
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
1820
use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
1921
use Symfony\Component\DependencyInjection\ContainerBuilder;
2022
use Symfony\Component\DependencyInjection\Reference;
23+
use Symfony\Contracts\Service\ResetInterface;
24+
use Symfony\Contracts\Service\ServiceSubscriberInterface;
2125

2226
class ResolveInstanceofConditionalsPassTest extends TestCase
2327
{
@@ -325,4 +329,60 @@ public function testDecoratorsAreNotAutomaticallyTagged()
325329

326330
$this->assertSame(['manual' => [[]]], $container->getDefinition('decorator')->getTags());
327331
}
332+
333+
public function testDecoratorsKeepBehaviorDescribingTags()
334+
{
335+
$container = new ContainerBuilder();
336+
337+
$container->setParameter('container.behavior_describing_tags', [
338+
'container.service_subscriber',
339+
'kernel.reset',
340+
]);
341+
342+
$container->register('decorator', DecoratorWithBehavior::class)
343+
->setAutoconfigured(true)
344+
->setDecoratedService('decorated')
345+
;
346+
347+
$container->registerForAutoconfiguration(ResourceCheckerInterface::class)
348+
->addTag('config_cache.resource_checker')
349+
;
350+
$container->registerForAutoconfiguration(ServiceSubscriberInterface::class)
351+
->addTag('container.service_subscriber')
352+
;
353+
$container->registerForAutoconfiguration(ResetInterface::class)
354+
->addTag('kernel.reset', ['method' => 'reset'])
355+
;
356+
357+
(new ResolveInstanceofConditionalsPass())->process($container);
358+
359+
$this->assertEquals([
360+
'container.service_subscriber' => [0 => []],
361+
'kernel.reset' => [
362+
[
363+
'method' => 'reset',
364+
],
365+
],
366+
], $container->getDefinition('decorator')->getTags());
367+
$this->assertFalse($container->hasParameter('container.behavior_describing_tags'));
368+
}
369+
}
370+
371+
class DecoratorWithBehavior implements ResetInterface, ResourceCheckerInterface, ServiceSubscriberInterface
372+
{
373+
public function reset()
374+
{
375+
}
376+
377+
public function supports(ResourceInterface $metadata)
378+
{
379+
}
380+
381+
public function isFresh(ResourceInterface $resource, $timestamp)
382+
{
383+
}
384+
385+
publi 42F3 c static function getSubscribedServices()
386+
{
387+
}
328388
}

0 commit comments

Comments
 (0)
0