Skip to content

Commit aed4d74

Browse files
committed
Merge remote-tracking branch 'hason/priority_bug'
2 parents 7fe7f71 + 696c83d commit aed4d74

12 files changed

+279
-193
lines changed

DependencyInjection/MonologExtension.php

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,22 @@ public function load(array $configs, ContainerBuilder $container)
4747
$handlers = array();
4848

4949
foreach ($config['handlers'] as $name => $handler) {
50-
$handlers[] = array(
50+
$handlers[$handler['priority']][] = array(
5151
'id' => $this->buildHandler($container, $name, $handler),
52-
'priority' => $handler['priority'],
5352
'channels' => isset($handler['channels']) ? $handler['channels'] : null
5453
);
5554
}
5655

57-
$handlers = array_reverse($handlers);
58-
uasort($handlers, function($a, $b) {
59-
if ($a['priority'] == $b['priority']) {
60-
return 0;
56+
ksort($handlers);
57+
$sortedHandlers = array();
58+
foreach ($handlers as $priorityHandlers) {
59+
foreach (array_reverse($priorityHandlers) as $handler) {
60+
$sortedHandlers[] = $handler;
6161
}
62+
}
6263

63-
return $a['priority'] < $b['priority'] ? -1 : 1;
64-
});
6564
$handlersToChannels = array();
66-
foreach ($handlers as $handler) {
65+
foreach ($sortedHandlers as $handler) {
6766
if (!in_array($handler['id'], $this->nestedHandlers)) {
6867
$handlersToChannels[$handler['id']] = $handler['channels'];
6968
}

Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public function testProcess()
2929
$service = $container->getDefinition('test');
3030
$this->assertEquals('monolog.logger.test', (string) $service->getArgument(1), '->process replaces the logger by the new one');
3131

32-
3332
// pushHandlers for service "test"
3433
$expected = array(
3534
'test' => array('monolog.handler.a', 'monolog.handler.b', 'monolog.handler.c'),
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection;
13+
14+
use Symfony\Bundle\MonologBundle\Tests\TestCase;
15+
16+
abstract class DependencyInjectionTest extends TestCase
17+
{
18+
/**
19+
* Assertion on the Class of a DIC Service Definition.
20+
*
21+
* @param \Symfony\Component\DependencyInjection\Definition $definition
22+
* @param string $expectedClass
23+
*/
24+
protected function assertDICDefinitionClass($definition, $expectedClass)
25+
{
26+
$this->assertEquals($expectedClass, $definition->getClass(), "Expected Class of the DIC Container Service Definition is wrong.");
27+
}
28+
29+
protected function assertDICConstructorArguments($definition, $args)
30+
{
31+
$this->assertEquals($args, $definition->getArguments(), "Expected and actual DIC Service constructor arguments of definition '".$definition->getClass()."' don't match.");
32+
}
33+
34+
protected function assertDICDefinitionMethodCallAt($pos, $definition, $methodName, array $params = null)
35+
{
36+
$calls = $definition->getMethodCalls();
37+
if (isset($calls[$pos][0])) {
38+
$this->assertEquals($methodName, $calls[$pos][0], "Method '".$methodName."' is expected to be called at position $pos.");
39+
40+
if ($params !== null) {
41+
$this->assertEquals($params, $calls[$pos][1], "Expected parameters to methods '".$methodName."' do not match the actual parameters.");
42+
}
43+
} else {
44+
$this->fail("Method '".$methodName."' is expected to be called at position $pos.");
45+
}
46+
}
47+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection;
13+
14+
use Symfony\Bundle\MonologBundle\DependencyInjection\MonologExtension;
15+
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
19+
abstract class FixtureMonologExtensionTest extends DependencyInjectionTest
20+
{
21+
public function testLoadWithSeveralHandlers()
22+
{
23+
$container = $this->getContainer('multiple_handlers');
24+
25+
$this->assertTrue($container->hasDefinition('monolog.logger'));
26+
$this->assertTrue($container->hasDefinition('monolog.handler.custom'));
27+
$this->assertTrue($container->hasDefinition('monolog.handler.main'));
28+
$this->assertTrue($container->hasDefinition('monolog.handler.nested'));
29+
30+
$logger = $container->getDefinition('monolog.logger');
31+
$this->assertCount(2, $logger->getMethodCalls());
32+
$this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom')));
33+
$this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main')));
34+
35+
$handler = $container->getDefinition('monolog.handler.custom');
36+
$this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%');
37+
$this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::ERROR, false));
38+
39+
$handler = $container->getDefinition('monolog.handler.main');
40+
$this->assertDICDefinitionClass($handler, '%monolog.handler.fingers_crossed.class%');
41+
$this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), \Monolog\Logger::ERROR, 0, true, true));
42+
}
43+
44+
public function testLoadWithOverwriting()
45+
{
46+
$container = $this->getContainer('overwriting');
47+
48+
$this->assertTrue($container->hasDefinition('monolog.logger'));
49+
$this->assertTrue($container->hasDefinition('monolog.handler.custom'));
50+
$this->assertTrue($container->hasDefinition('monolog.handler.main'));
51+
$this->assertTrue($container->hasDefinition('monolog.handler.nested'));
52+
53+
$logger = $container->getDefinition('monolog.logger');
54+
$this->assertCount(2, $logger->getMethodCalls());
55+
$this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom')));
56+
$this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main')));
57+
58+
$handler = $container->getDefinition('monolog.handler.custom');
59+
$this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%');
60+
$this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::WARNING, true));
61+
62+
$handler = $container->getDefinition('monolog.handler.main');
63+
$this->assertDICDefinitionClass($handler, '%monolog.handler.fingers_crossed.class%');
64+
$this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), \Monolog\Logger::ERROR, 0, true, true));
65+
}
66+
67+
public function testLoadWithNewAtEnd()
68+
{
69+
$container = $this->getContainer('new_at_end');
70+
71+
$this->assertTrue($container->hasDefinition('monolog.logger'));
72+
$this->assertTrue($container->hasDefinition('monolog.handler.custom'));
73+
$this->assertTrue($container->hasDefinition('monolog.handler.main'));
74+
$this->assertTrue($container->hasDefinition('monolog.handler.nested'));
75+
$this->assertTrue($container->hasDefinition('monolog.handler.new'));
76+
77+
$logger = $container->getDefinition('monolog.logger');
78+
$this->assertCount(3, $logger->getMethodCalls());
79+
$this->assertDICDefinitionMethodCallAt(2, $logger, 'pushHandler', array(new Reference('monolog.handler.custom')));
80+
$this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.main')));
81+
$this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.new')));
82+
83+
$handler = $container->getDefinition('monolog.handler.new');
84+
$this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%');
85+
$this->assertDICConstructorArguments($handler, array('/tmp/monolog.log', \Monolog\Logger::ERROR, true));
86+
}
87+
88+
public function testLoadWithNewAndPriority()
89+
{
90+
$container = $this->getContainer('new_and_priority');
91+
92+
$this->assertTrue($container->hasDefinition('monolog.logger'));
93+
$this->assertTrue($container->hasDefinition('monolog.handler.custom'));
94+
$this->assertTrue($container->hasDefinition('monolog.handler.main'));
95+
$this->assertTrue($container->hasDefinition('monolog.handler.nested'));
96+
$this->assertTrue($container->hasDefinition('monolog.handler.first'));
97+
$this->assertTrue($container->hasDefinition('monolog.handler.last'));
98+
99+
$logger = $container->getDefinition('monolog.logger');
100+
$this->assertCount(4, $logger->getMethodCalls());
101+
$this->assertDICDefinitionMethodCallAt(3, $logger, 'pushHandler', array(new Reference('monolog.handler.first')));
102+
$this->assertDICDefinitionMethodCallAt(2, $logger, 'pushHandler', array(new Reference('monolog.handler.custom')));
103+
$this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.main')));
104+
$this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.last')));
105+
106+
$handler = $container->getDefinition('monolog.handler.main');
107+
$this->assertDICDefinitionClass($handler, '%monolog.handler.buffer.class%');
108+
$this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), 0, \Monolog\Logger::INFO, true));
109+
110+
$handler = $container->getDefinition('monolog.handler.first');
111+
$this->assertDICDefinitionClass($handler, '%monolog.handler.rotating_file.class%');
112+
$this->assertDICConstructorArguments($handler, array('/tmp/monolog.log', 0, \Monolog\Logger::ERROR, true));
113+
114+
$handler = $container->getDefinition('monolog.handler.last');
115+
$this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%');
116+
$this->assertDICConstructorArguments($handler, array('/tmp/last.log', \Monolog\Logger::ERROR, true));
117+
}
118+
119+
public function testHandlersWithChannels()
120+
{
121+
$container = $this->getContainer('handlers_with_channels');
122+
123+
$this->assertEquals(
124+
array(
125+
'monolog.handler.custom' => array('type' => 'inclusive', 'elements' => array('foo')),
126+
'monolog.handler.main' => array('type' => 'exclusive', 'elements' => array('foo', 'bar')),
127+
'monolog.handler.extra' => null,
128+
'monolog.handler.more' => array('type' => 'inclusive', 'elements' => array('security', 'doctrine')),
129+
),
130+
$container->getParameter('monolog.handlers_to_channels')
131+
);
132+
}
133+
134+
protected function getContainer($fixture)
135+
{
136+
$container = new ContainerBuilder();
137+
$container->registerExtension(new MonologExtension());
138+
139+
$this->loadFixture($container, $fixture);
140+
141+
$container->getCompilerPassConfig()->setOptimizationPasses(array());
142+
$container->getCompilerPassConfig()->setRemovingPasses(array());
143+
$container->addCompilerPass(new LoggerChannelPass());
144+
$container->compile();
145+
146+
return $container;
147+
}
148+
149+
abstract protected function loadFixture(ContainerBuilder $container, $fixture);
150+
}
Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,49 @@
11
<?xml version="1.0" ?>
22

3-
<srv:container xmlns="http://symfony.com/schema/dic/monolog"
3+
<container xmlns="http://symfony.com/schema/dic/services"
44
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5-
xmlns:srv="http://symfony.com/schema/dic/services"
5+
xmlns:monolog="http://symfony.com/schema/dic/monolog"
66
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
77
http://symfony.com/schema/dic/monolog http://symfony.com/schema/dic/monolog/monolog-1.0.xsd">
88

9-
<config>
10-
<handler name="custom" type="stream" path="/tmp/symfony.log" bubble="false" level="ERROR">
11-
<channels>
12-
<channel>foo</channel>
13-
</channels>
14-
</handler>
15-
<handler name="main" type="group" handler="nested">
16-
<member>nested</member>
17-
<channels>
18-
<channel>!foo</channel>
19-
<channel>!bar</channel>
20-
</channels>
21-
</handler>
22-
<handler name="nested" type="stream" />
23-
<handler name="extra" type="syslog" ident="monolog" facility="user" level="ALERT" />
24-
<handler name="more" type="native_mailer" to-email="[email protected]" from-email="[email protected]" subject="Monolog report" level="CRITICAL">
25-
<channels type="inclusive">
26-
<channel>security</channel>
27-
<channel>doctrine</channel>
28-
</channels>
29-
</handler>
30-
</config>
31-
</srv:container>
9+
<services>
10+
<service id="security_logger" class="Foo">
11+
<tag name="monolog.logger" channel="security" />
12+
</service>
13+
14+
<service id="doctrine_logger" class="Foo">
15+
<tag name="monolog.logger" channel="doctrine" />
16+
</service>
17+
18+
<service id="foo_logger" class="Foo">
19+
<tag name="monolog.logger" channel="foo" />
20+
</service>
21+
22+
<service id="bar_logger" class="Foo">
23+
<tag name="monolog.logger" channel="bar" />
24+
</service>
25+
</services>
26+
27+
<monolog:config>
28+
<monolog:handler name="custom" type="stream" path="/tmp/symfony.log" bubble="false" level="ERROR">
29+
<monolog:channels>
30+
<monolog:channel>foo</monolog:channel>
31+
</monolog:channels>
32+
</monolog:handler>
33+
<monolog:handler name="main" type="group" handler="nested">
34+
<monolog:member>nested</monolog:member>
35+
<monolog:channels>
36+
<monolog:channel>!foo</monolog:channel>
37+
<monolog:channel>!bar</monolog:channel>
38+
</monolog:channels>
39+
</monolog:handler>
40+
<monolog:handler name="nested" type="stream" />
41+
<monolog:handler name="extra" type="syslog" ident="monolog" facility="user" level="ALERT" />
42+
<monolog:handler name="more" type="native_mailer" to-email="[email protected]" from-email="[email protected]" subject="Monolog report" level="CRITICAL">
43+
<monolog:channels type="inclusive">
44+
<monolog:channel>security</monolog:channel>
45+
<monolog:channel>doctrine</monolog:channel>
46+
</monolog:channels>
47+
</monolog:handler>
48+
</monolog:config>
49+
</container>

Tests/DependencyInjection/Fixtures/yml/handlers_with_channels.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
services:
2+
security_logger:
3+
class: Foo
4+
tags: [{ name: monolog.logger, channel: security }]
5+
6+
doctrine_logger:
7+
class: Foo
8+
tags: [{ name: monolog.logger, channel: doctrine }]
9+
10+
foo_logger:
11+
class: Foo
12+
tags: [{ name: monolog.logger, channel: foo }]
13+
14+
bar_logger:
15+
class: Foo
16+
tags: [{ name: monolog.logger, channel: bar }]
17+
118
monolog:
219
handlers:
320
custom:

Tests/DependencyInjection/Fixtures/yml/new_and_priority_import.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ monolog:
1010
level: INFO
1111
handler: nested
1212
nested:
13-
type: stream
13+
type: stream

Tests/DependencyInjection/Fixtures/yml/new_at_end_import.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ monolog:
1010
action_level: ERROR
1111
handler: nested
1212
nested:
13-
type: stream
13+
type: stream

Tests/DependencyInjection/Fixtures/yml/overwriting_import.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ monolog:
1010
action_level: ERROR
1111
handler: nested
1212
nested:
13-
type: stream
13+
type: stream

0 commit comments

Comments
 (0)