Skip to content

Commit 264cf5d

Browse files
committed
Fix for multiple tags
1 parent 6f6130a commit 264cf5d

File tree

2 files changed

+70
-36
lines changed

2 files changed

+70
-36
lines changed

DependencyInjection/Compiler/AddProcessorsPass.php

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\MonologBundle\DependencyInjection\Compiler;
1313

14+
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
1415
use Symfony\Component\DependencyInjection\ChildDefinition;
1516
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1617
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
@@ -33,43 +34,54 @@ public function process(ContainerBuilder $container)
3334
return;
3435
}
3536

37+
$indexedTags = [];
38+
$i = 1;
39+
40+
foreach ($container->findTaggedServiceIds('monolog.processor') as $id => $tags) {
41+
foreach ($tags as &$tag) {
42+
$indexedTags[$tag['index'] = $i++] = $tag;
43+
}
44+
unset($tag);
45+
$definition = $container->getDefinition($id);
46+
$definition->setTags(array_merge($definition->getTags(), ['monolog.processor' => $tags]));
47+
}
48+
49+
$taggedIteratorArgument = new TaggedIteratorArgument('monolog.processor', 'index', null, true);
3650
// array_reverse is used because ProcessableHandlerTrait::pushProcessor prepends processors to the beginning of the stack
37-
foreach (array_reverse($this->findAndSortTaggedServices('monolog.processor', $container)) as $reference) {
38-
$tags = $container->getDefinition((string) $reference)->getTag('monolog.processor');
51+
foreach (array_reverse($this->findAndSortTaggedServices($taggedIteratorArgument, $container), true) as $index => $reference) {
52+
$tag = $indexedTags[$index];
3953

40-
foreach ($tags as $tag) {
41-
if (!empty($tag['channel']) && !empty($tag['handler'])) {
42-
throw new \InvalidArgumentException(\sprintf('you cannot specify both the "handler" and "channel" attributes for the "monolog.processor" tag on service "%s"', $reference));
43-
}
54+
if (!empty($tag['channel']) && !empty($tag['handler'])) {
55+
throw new \InvalidArgumentException(\sprintf('you cannot specify both the "handler" and "channel" attributes for the "monolog.processor" tag on service "%s"', $reference));
56+
}
4457

45-
if (!empty($tag['handler'])) {
46-
$definition = $container->findDefinition(\sprintf('monolog.handler.%s', $tag['handler']));
47-
$parentDef = $definition;
48-
while (!$parentDef->getClass() && $parentDef instanceof ChildDefinition) {
49-
$parentDef = $container->findDefinition($parentDef->getParent());
50-
}
51-
$class = $container->getParameterBag()->resolveValue($parentDef->getClass());
52-
if (!method_exists($class, 'pushProcessor')) {
53-
throw new \InvalidArgumentException(\sprintf('The "%s" handler does not accept processors', $tag['handler']));
54-
}
55-
} elseif (!empty($tag['channel'])) {
56-
if ('app' === $tag['channel']) {
57-
$definition = $container->getDefinition('monolog.logger');
58-
} else {
59-
$definition = $container->getDefinition(\sprintf('monolog.logger.%s', $tag['channel']));
60-
}
61-
} else {
62-
$definition = $container->getDefinition('monolog.logger_prototype');
58+
if (!empty($tag['handler'])) {
59+
$definition = $container->findDefinition(\sprintf('monolog.handler.%s', $tag['handler']));
60+
$parentDef = $definition;
61+
while (!$parentDef->getClass() && $parentDef instanceof ChildDefinition) {
62+
$parentDef = $container->findDefinition($parentDef->getParent());
6363
}
64-
65-
if (!empty($tag['method'])) {
66-
$processor = [$reference, $tag['method']];
64+
$class = $container->getParameterBag()->resolveValue($parentDef->getClass());
65+
if (!method_exists($class, 'pushProcessor')) {
66+
throw new \InvalidArgumentException(\sprintf('The "%s" handler does not accept processors', $tag['handler']));
67+
}
68+
} elseif (!empty($tag['channel'])) {
69+
if ('app' === $tag['channel']) {
70+
$definition = $container->getDefinition('monolog.logger');
6771
} else {
68-
// If no method is defined, fallback to use __invoke
69-
$processor = $reference;
72+
$definition = $container->getDefinition(\sprintf('monolog.logger.%s', $tag['channel']));
7073
}
71-
$definition->addMethodCall('pushProcessor', [$processor]);
74+
} else {
75+
$definition = $container->getDefinition('monolog.logger_prototype');
76+
}
77+
78+
if (!empty($tag['method'])) {
79+
$processor = [$reference, $tag['method']];
80+
} else {
81+
// If no method is defined, fallback to use __invoke
82+
$processor = $reference;
7283
}
84+
$definition->addMethodCall('pushProcessor', [$processor]);
7385
}
7486
}
7587
}

Tests/DependencyInjection/Compiler/AddProcessorsPassTest.php

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\DependencyInjection\Definition;
2222
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
2323
use Symfony\Component\DependencyInjection\Reference;
24+
use Symfony\Component\DependencyInjection\TypedReference;
2425

2526
class AddProcessorsPassTest extends TestCase
2627
{
@@ -31,19 +32,28 @@ public function testHandlerProcessors()
3132
$service = $container->getDefinition('monolog.handler.test');
3233
$calls = $service->getMethodCalls();
3334
$this->assertCount(1, $calls);
34-
$this->assertEquals(['pushProcessor', [new Reference('test')]], $calls[0]);
35+
$this->assertEquals(['pushProcessor', [new TypedReference('test', 'TestClass')]], $calls[0]);
3536

3637
$service = $container->getDefinition('handler_test');
3738
$calls = $service->getMethodCalls();
3839
$this->assertCount(1, $calls);
39-
$this->assertEquals(['pushProcessor', [new Reference('test2')]], $calls[0]);
40+
$this->assertEquals(['pushProcessor', [new TypedReference('test2', 'TestClass')]], $calls[0]);
4041

4142
$service = $container->getDefinition('monolog.handler.priority_test');
4243
$calls = $service->getMethodCalls();
43-
$this->assertCount(3, $calls);
44-
$this->assertEquals(['pushProcessor', [new Reference('processor-10')]], $calls[0]);
45-
$this->assertEquals(['pushProcessor', [new Reference('processor+10')]], $calls[1]);
46-
$this->assertEquals(['pushProcessor', [new Reference('processor+20')]], $calls[2]);
44+
$this->assertCount(5, $calls);
45+
$this->assertEquals(['pushProcessor', [new TypedReference('processor-10', 'TestClass')]], $calls[0]);
46+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+10', 'TestClass')]], $calls[1]);
47+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+20', 'TestClass')]], $calls[2]);
48+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+20', 'TestClass')]], $calls[2]);
49+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+25+35', 'TestClass')]], $calls[3]);
50+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+35+25', 'TestClass')]], $calls[4]);
51+
52+
$service = $container->getDefinition('monolog.handler.priority_test_2');
53+
$calls = $service->getMethodCalls();
54+
$this->assertCount(2, $calls);
55+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+35+25', 'TestClass')]], $calls[0]);
56+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+25+35', 'TestClass')]], $calls[1]);
4757
}
4858

4959
public function testFailureOnHandlerWithoutPushProcessor()
@@ -83,10 +93,12 @@ protected function getContainer()
8393
$container->setDefinition('monolog.handler.test', new Definition('%monolog.handler.console.class%', [100, false]));
8494
$container->setDefinition('handler_test', new Definition('%monolog.handler.console.class%', [100, false]));
8595
$container->setDefinition('monolog.handler.priority_test', new Definition('%monolog.handler.console.class%', [100, false]));
96+
$container->setDefinition('monolog.handler.priority_test_2', new Definition('%monolog.handler.console.class%', [100, false]));
8697
$container->setAlias('monolog.handler.test2', 'handler_test');
8798
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.test')]);
8899
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.test2')]);
89100
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.priority_test')]);
101+
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.priority_test_2')]);
90102

91103
$service = new Definition('TestClass', ['false', new Reference('logger')]);
92104
$service->addTag('monolog.processor', ['handler' => 'test']);
@@ -108,6 +120,16 @@ protected function getContainer()
108120
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => 20]);
109121
$container->setDefinition('processor+20', $service);
110122

123+
$service = new Definition('TestClass', ['false', new Reference('logger')]);
124+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => 35]);
125+
$service->addTag('monolog.processor', ['handler' => 'priority_test_2', 'priority' => 25]);
126+
$container->setDefinition('processor+35+25', $service);
127+
128+
$service = new Definition('TestClass', ['false', new Reference('logger')]);
129+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => 25]);
130+
$service->addTag('monolog.processor', ['handler' => 'priority_test_2', 'priority' => 35]);
131+
$container->setDefinition('processor+25+35', $service);
132+
111133
$container->getCompilerPassConfig()->setOptimizationPasses([]);
112134
$container->getCompilerPassConfig()->setRemovingPasses([]);
113135
$container->addCompilerPass(new AddProcessorsPass());

0 commit comments

Comments
 (0)