Skip to content

Commit 8444339

Browse files
committed
[HttpKernel] added a check for private event listeners/subscribers
1 parent 427ee19 commit 8444339

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RegisterKernelListenersPass.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ public function process(ContainerBuilder $container)
2525
$definition = $container->getDefinition('event_dispatcher');
2626

2727
foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) {
28+
$def = $container->getDefinition($id);
29+
if (!$def->isPublic()) {
30+
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id));
31+
}
32+
2833
foreach ($events as $event) {
2934
$priority = isset($event['priority']) ? $event['priority'] : 0;
3035

@@ -45,8 +50,13 @@ public function process(ContainerBuilder $container)
4550
}
4651

4752
foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) {
53+
$def = $container->getDefinition($id);
54+
if (!$def->isPublic()) {
55+
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id));
56+
}
57+
4858
// We must assume that the class value has been correctly filled, even if the service is created by a factory
49-
$class = $container->getDefinition($id)->getClass();
59+
$class = $def->getClass();
5060

5161
$refClass = new \ReflectionClass($class);
5262
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/RegisterKernelListenersPassTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ public function testEventSubscriberWithoutInterface()
3131
);
3232

3333
$definition = $this->getMock('Symfony\Component\DependencyInjection\Definition');
34+
$definition->expects($this->atLeastOnce())
35+
->method('isPublic')
36+
->will($this->returnValue(true));
3437
$definition->expects($this->atLeastOnce())
3538
->method('getClass')
3639
->will($this->returnValue('stdClass'));
@@ -60,6 +63,9 @@ public function testValidEventSubscriber()
6063
);
6164

6265
$definition = $this->getMock('Symfony\Component\DependencyInjection\Definition');
66+
$definition->expects($this->atLeastOnce())
67+
->method('isPublic')
68+
->will($this->returnValue(true));
6369
$definition->expects($this->atLeastOnce())
6470
->method('getClass')
6571
->will($this->returnValue('Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\SubscriberService'));
@@ -81,6 +87,34 @@ public function testValidEventSubscriber()
8187
$registerListenersPass = new RegisterKernelListenersPass();
8288
$registerListenersPass->process($builder);
8389
}
90+
91+
/**
92+
* @expectedException \InvalidArgumentException
93+
* @expectedExceptionMessage The service "foo" must be public as event listeners are lazy-loaded.
94+
*/
95+
public function testPrivateEventListener()
96+
{
97+
$container = new ContainerBuilder();
98+
$container->register('foo', 'stdClass')->setPublic(false)->addTag('kernel.event_listener', array());
99+
$container->register('event_dispatcher', 'stdClass');
100+
101+
$registerListenersPass = new RegisterKernelListenersPass();
102+
$registerListenersPass->process($container);
103+
}
104+
105+
/**
106+
* @expectedException \InvalidArgumentException
107+
* @expectedExceptionMessage The service "foo" must be public as event subscribers are lazy-loaded.
108+
*/
109+
public function testPrivateEventSubscriber()
110+
{
111+
$container = new ContainerBuilder();
112+
$container->register('foo', 'stdClass')->setPublic(false)->addTag('kernel.event_subscriber', array());
113+
$container->register('event_dispatcher', 'stdClass');
114+
115+
$registerListenersPass = new RegisterKernelListenersPass();
116+
$registerListenersPass->process($container);
117+
}
84118
}
85119

86120
class SubscriberService implements \Symfony\Component\EventDispatcher\EventSubscriberInterface

0 commit comments

Comments
 (0)