Skip to content

Commit f432f7c

Browse files
committed
bug #254 Make channel selection work with autowired arguments (stof)
This PR was merged into the 3.x-dev branch. Discussion ---------- Make channel selection work with autowired arguments This only works on Symfony 3.4+, not on Symfony 3.3, but 3.3 is EOL already so this is fine. Closes #218 Closes #228 Replaces #251 Commits ------- 457032a Make channel selection work with autowired arguments
2 parents 01e1313 + 457032a commit f432f7c

File tree

2 files changed

+91
-2
lines changed

2 files changed

+91
-2
lines changed

DependencyInjection/Compiler/LoggerChannelPass.php

Lines changed: 15 additions & 0 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\BoundArgument;
1415
use Symfony\Component\DependencyInjection\Reference;
1516
use Symfony\Component\DependencyInjection\ChildDefinition;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -61,6 +62,20 @@ public function process(ContainerBuilder $container)
6162
}
6263
}
6364
$definition->setMethodCalls($calls);
65+
66+
if (!$definition instanceof ChildDefinition && \method_exists($definition, 'getBindings')) {
67+
$binding = new BoundArgument(new Reference($loggerId));
68+
69+
// Mark the binding as used already, to avoid reporting it as unused if the service does not use a
70+
// logger injected through the LoggerInterface alias.
71+
$values = $binding->getValues();
72+
$values[2] = true;
73+
$binding->setValues($values);
74+
75+
$bindings = $definition->getBindings();
76+
$bindings['Psr\Log\LoggerInterface'] = $binding;
77+
$definition->setBindings($bindings);
78+
}
6479
}
6580
}
6681

Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Psr\Log\LoggerInterface;
1516
use Symfony\Component\DependencyInjection\Reference;
1617
use Symfony\Component\DependencyInjection\Definition;
1718
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -63,7 +64,55 @@ public function testProcessSetters()
6364
$this->assertEquals('monolog.logger.test', (string) $calls[0][1][0], '->process replaces the logger by the new one in setters');
6465
}
6566

66-
protected function getContainer()
67+
public function testAutowiredLoggerArgumentsAreReplacedWithChannelLogger()
68+
{
69+
if (!\method_exists('Symfony\Component\DependencyInjection\Definition', 'getBindings')) {
70+
$this->markTestSkipped('Need DependencyInjection 3.4+ to autowire channel logger.');
71+
}
72+
73+
$container = $this->getFunctionalContainer();
74+
75+
$dummyService = $container->register('dummy_service', 'Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler\DummyService')
76+
->setAutowired(true)
77+
->setPublic(true)
78+
->addTag('monolog.logger', array('channel' => 'test'));
79+
80+
$container->compile();
81+
82+
$this->assertEquals('monolog.logger.test', (string) $dummyService->getArgument(0));
83+
}
84+
85+
public function testAutowiredLoggerArgumentsAreNotReplacedWithChannelLoggerIfLoggerArgumentIsConfiguredExplicitly()
86+
{
87+
if (!\method_exists('Symfony\Component\DependencyInjection\Definition', 'getBindings')) {
88+
$this->markTestSkipped('Need DependencyInjection 3.4+ to autowire channel logger.');
89+
}
90+
91+
$container = $this->getFunctionalContainer();
92+
93+
$dummyService = $container->register('dummy_service', 'Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler\DummyService')
94+
->setAutowired(true)
95+
->addArgument(new Reference('monolog.logger'))
96+
->addTag('monolog.logger', array('channel' => 'test'));
97+
98+
$container->compile();
99+
100+
$this->assertEquals('monolog.logger', (string) $dummyService->getArgument(0));
101+
}
102+
103+
public function testTagNotBreakingIfNoLogger()
104+
{
105+
$container = $this->getFunctionalContainer();
106+
107+
$dummyService = $container->register('dummy_service', 'stdClass')
108+
->addTag('monolog.logger', array('channel' => 'test'));
109+
110+
$container->compile();
111+
112+
$this->assertEquals(array(), $dummyService->getArguments());
113+
}
114+
115+
private function getContainer()
67116
{
68117
$container = new ContainerBuilder();
69118
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../../Resources/config'));
@@ -105,7 +154,7 @@ protected function getContainer()
105154
return $container;
106155
}
107156

108-
protected function getContainerWithSetter()
157+
private function getContainerWithSetter()
109158
{
110159
$container = new ContainerBuilder();
111160
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../../Resources/config'));
@@ -130,4 +179,29 @@ protected function getContainerWithSetter()
130179

131180
return $container;
132181
}
182+
183+
private function getFunctionalContainer()
184+
{
185+
$container = new ContainerBuilder();
186+
$container->setParameter('monolog.additional_channels', array());
187+
$container->setParameter('monolog.handlers_to_channels', array());
188+
$container->setParameter('monolog.use_microseconds', true);
189+
190+
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../../Resources/config'));
191+
$loader->load('monolog.xml');
192+
193+
$container->addCompilerPass(new LoggerChannelPass());
194+
195+
// disable removing passes to be able to inspect the container before all the inlining optimizations
196+
$container->getCompilerPassConfig()->setRemovingPasses(array());
197+
198+
return $container;
199+
}
200+
}
201+
202+
class DummyService
203+
{
204+
public function __construct(LoggerInterface $logger)
205+
{
206+
}
133207
}

0 commit comments

Comments
 (0)