Skip to content

Commit 89b8e0a

Browse files
committed
[EventDispatcher][HttpKernel] Move RegisterListenersPass from HttpKernel to EventDispatcher.
1 parent 8b08888 commit 89b8e0a

File tree

7 files changed

+127
-91
lines changed

7 files changed

+127
-91
lines changed

UPGRADE-3.0.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ UPGRADE FROM 2.x to 3.0
292292
* The `Symfony\Component\HttpKernel\EventListener\ExceptionListener` now
293293
passes the Request format as the `_format` argument instead of `format`.
294294

295+
* The `Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass` has been renamed to
296+
`Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass` and moved to the EventDispatcher component.
297+
295298
### Locale
296299

297300
* The Locale component was removed and replaced by the Intl component.

src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
use Symfony\Component\DependencyInjection\ContainerBuilder;
3131
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
3232
use Symfony\Component\DependencyInjection\Scope;
33+
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
3334
use Symfony\Component\HttpFoundation\Request;
3435
use Symfony\Component\HttpKernel\Bundle\Bundle;
35-
use Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass;
3636

3737
/**
3838
* Bundle.

src/Symfony/Component/EventDispatcher/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
2.5.0
5+
-----
6+
7+
* added RegisterListenersPass (originally in HttpKernel)
8+
49
2.1.0
510
-----
611

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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\Component\EventDispatcher\DependencyInjection;
13+
14+
use Symfony\Component\DependencyInjection\ContainerBuilder;
15+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
17+
/**
18+
* Compiler pass to register tagged services for an event dispatcher.
19+
*/
20+
class RegisterListenersPass implements CompilerPassInterface
21+
{
22+
/**
23+
* @var string
24+
*/
25+
protected $dispatcherService;
26+
27+
/**
28+
* @var string
29+
*/
30+
protected $listenerTag;
31+
32+
/**
33+
* @var string
34+
*/
35+
protected $subscriberTag;
36+
37+
/**
38+
* Constructor.
39+
*
40+
* @param string $dispatcherService Service name of the event dispatcher in processed container
41+
* @param string $listenerTag Tag name used for listener
42+
* @param string $subscriberTag Tag name used for subscribers
43+
*/
44+
public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber')
45+
{
46+
$this->dispatcherService = $dispatcherService;
47+
$this->listenerTag = $listenerTag;
48+
$this->subscriberTag = $subscriberTag;
49+
}
50+
51+
public function process(ContainerBuilder $container)
52+
{
53+
if (!$container->hasDefinition($this->dispatcherService) && !$container->hasAlias($this->dispatcherService)) {
54+
return;
55+
}
56+
57+
$definition = $container->findDefinition($this->dispatcherService);
58+
59+
foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) {
60+
$def = $container->getDefinition($id);
61+
if (!$def->isPublic()) {
62+
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id));
63+
}
64+
65+
if ($def->isAbstract()) {
66+
throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id));
67+
}
68+
69+
foreach ($events as $event) {
70+
$priority = isset($event['priority']) ? $event['priority'] : 0;
71+
72+
if (!isset($event['event'])) {
73+
throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id));
74+
}
75+
76+
if (!isset($event['method'])) {
77+
$event['method'] = 'on'.preg_replace_callback(array(
78+
'/(?<=\b)[a-z]/i',
79+
'/[^a-z0-9]/i',
80+
), function ($matches) { return strtoupper($matches[0]); }, $event['event']);
81+
$event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
82+
}
83+
84+
$definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority));
85+
}
86+
}
87+
88+
foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) {
89+
$def = $container->getDefinition($id);
90+
if (!$def->isPublic()) {
91+
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id));
92+
}
93+
94+
// We must assume that the class value has been correctly filled, even if the service is created by a factory
95+
$class = $def->getClass();
96+
97+
$refClass = new \ReflectionClass($class);
98+
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
99+
if (!$refClass->implementsInterface($interface)) {
100+
throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
101+
}
102+
103+
$definition->addMethodCall('addSubscriberService', array($id, $class));
104+
}
105+
}
106+
}

src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterListenersPassTest.php renamed to src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\HttpKernel\Tests\DependencyInjection;
12+
namespace Symfony\Component\EventDispatcher\Tests\DependencyInjection;
1313

1414
use Symfony\Component\DependencyInjection\ContainerBuilder;
15-
use Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass;
15+
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
1616

1717
class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase
1818
{
@@ -67,7 +67,7 @@ public function testValidEventSubscriber()
6767
->will($this->returnValue(true));
6868
$definition->expects($this->atLeastOnce())
6969
->method('getClass')
70-
->will($this->returnValue('Symfony\Component\HttpKernel\Tests\DependencyInjection\SubscriberService'));
70+
->will($this->returnValue('Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService'));
7171

7272
$builder = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder');
7373
$builder->expects($this->any())

src/Symfony/Component/HttpKernel/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
2.5.0
5+
-----
6+
7+
* deprecated `Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass`, use `Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass` instead
8+
49
2.4.0
510
-----
611

src/Symfony/Component/HttpKernel/DependencyInjection/RegisterListenersPass.php

Lines changed: 4 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -11,96 +11,13 @@
1111

1212
namespace Symfony\Component\HttpKernel\DependencyInjection;
1313

14-
use Symfony\Component\DependencyInjection\ContainerBuilder;
15-
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
14+
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass as BaseRegisterListenersPass;
1615

1716
/**
1817
* Compiler pass to register tagged services for an event dispatcher.
18+
*
19+
* @deprecated Deprecated in 2.5, to be removed in 3.0. Use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass instead.
1920
*/
20-
class RegisterListenersPass implements CompilerPassInterface
21+
class RegisterListenersPass extends BaseRegisterListenersPass
2122
{
22-
/**
23-
* @var string
24-
*/
25-
protected $dispatcherService;
26-
27-
/**
28-
* @var string
29-
*/
30-
protected $listenerTag;
31-
32-
/**
33-
* @var string
34-
*/
35-
protected $subscriberTag;
36-
37-
/**
38-
* Constructor.
39-
*
40-
* @param string $dispatcherService Service name of the event dispatcher in processed container
41-
* @param string $listenerTag Tag name used for listener
42-
* @param string $subscriberTag Tag name used for subscribers
43-
*/
44-
public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber')
45-
{
46-
$this->dispatcherService = $dispatcherService;
47-
$this->listenerTag = $listenerTag;
48-
$this->subscriberTag = $subscriberTag;
49-
}
50-
51-
public function process(ContainerBuilder $container)
52-
{
53-
if (!$container->hasDefinition($this->dispatcherService) && !$container->hasAlias($this->dispatcherService)) {
54-
return;
55-
}
56-
57-
$definition = $container->findDefinition($this->dispatcherService);
58-
59-
foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) {
60-
$def = $container->getDefinition($id);
61-
if (!$def->isPublic()) {
62-
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id));
63-
}
64-
65-
if ($def->isAbstract()) {
66-
throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id));
67-
}
68-
69-
foreach ($events as $event) {
70-
$priority = isset($event['priority']) ? $event['priority'] : 0;
71-
72-
if (!isset($event['event'])) {
73-
throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id));
74-
}
75-
76-
if (!isset($event['method'])) {
77-
$event['method'] = 'on'.preg_replace_callback(array(
78-
'/(?<=\b)[a-z]/i',
79-
'/[^a-z0-9]/i',
80-
), function ($matches) { return strtoupper($matches[0]); }, $event['event']);
81-
$event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
82-
}
83-
84-
$definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority));
85-
}
86-
}
87-
88-
foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) {
89-
$def = $container->getDefinition($id);
90-
if (!$def->isPublic()) {
91-
throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id));
92-
}
93-
94-
// We must assume that the class value has been correctly filled, even if the service is created by a factory
95-
$class = $def->getClass();
96-
97-
$refClass = new \ReflectionClass($class);
98-
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
99-
if (!$refClass->implementsInterface($interface)) {
100-
throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
101-
}
102-
103-
$definition->addMethodCall('addSubscriberService', array($id, $class));
104-
}
105-
}
10623
}

0 commit comments

Comments
 (0)