From 89b8e0a9498101d352207011b83821574fc71a93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Mon, 16 Dec 2013 18:44:05 +0100 Subject: [PATCH] [EventDispatcher][HttpKernel] Move RegisterListenersPass from HttpKernel to EventDispatcher. --- UPGRADE-3.0.md | 3 + .../FrameworkBundle/FrameworkBundle.php | 2 +- .../Component/EventDispatcher/CHANGELOG.md | 5 + .../RegisterListenersPass.php | 106 ++++++++++++++++++ .../RegisterListenersPassTest.php | 6 +- src/Symfony/Component/HttpKernel/CHANGELOG.md | 5 + .../RegisterListenersPass.php | 91 +-------------- 7 files changed, 127 insertions(+), 91 deletions(-) create mode 100644 src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php rename src/Symfony/Component/{HttpKernel => EventDispatcher}/Tests/DependencyInjection/RegisterListenersPassTest.php (94%) diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index 4e41a20491..ce5d772627 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -292,6 +292,9 @@ UPGRADE FROM 2.x to 3.0 * The `Symfony\Component\HttpKernel\EventListener\ExceptionListener` now passes the Request format as the `_format` argument instead of `format`. + * The `Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass` has been renamed to + `Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass` and moved to the EventDispatcher component. + ### Locale * The Locale component was removed and replaced by the Intl component. diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 5418121dd6..30d06fd7af 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -30,9 +30,9 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SerializerPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\Scope; +use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Bundle\Bundle; -use Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass; /** * Bundle. diff --git a/src/Symfony/Component/EventDispatcher/CHANGELOG.md b/src/Symfony/Component/EventDispatcher/CHANGELOG.md index 536c5ac729..067c6c233f 100644 --- a/src/Symfony/Component/EventDispatcher/CHANGELOG.md +++ b/src/Symfony/Component/EventDispatcher/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.5.0 +----- + + * added RegisterListenersPass (originally in HttpKernel) + 2.1.0 ----- diff --git a/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php b/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php new file mode 100644 index 0000000000..210b9b610e --- /dev/null +++ b/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\EventDispatcher\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Compiler pass to register tagged services for an event dispatcher. + */ +class RegisterListenersPass implements CompilerPassInterface +{ + /** + * @var string + */ + protected $dispatcherService; + + /** + * @var string + */ + protected $listenerTag; + + /** + * @var string + */ + protected $subscriberTag; + + /** + * Constructor. + * + * @param string $dispatcherService Service name of the event dispatcher in processed container + * @param string $listenerTag Tag name used for listener + * @param string $subscriberTag Tag name used for subscribers + */ + public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber') + { + $this->dispatcherService = $dispatcherService; + $this->listenerTag = $listenerTag; + $this->subscriberTag = $subscriberTag; + } + + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition($this->dispatcherService) && !$container->hasAlias($this->dispatcherService)) { + return; + } + + $definition = $container->findDefinition($this->dispatcherService); + + foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) { + $def = $container->getDefinition($id); + if (!$def->isPublic()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id)); + } + + if ($def->isAbstract()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id)); + } + + foreach ($events as $event) { + $priority = isset($event['priority']) ? $event['priority'] : 0; + + if (!isset($event['event'])) { + throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id)); + } + + if (!isset($event['method'])) { + $event['method'] = 'on'.preg_replace_callback(array( + '/(?<=\b)[a-z]/i', + '/[^a-z0-9]/i', + ), function ($matches) { return strtoupper($matches[0]); }, $event['event']); + $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']); + } + + $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); + } + } + + foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) { + $def = $container->getDefinition($id); + if (!$def->isPublic()) { + throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id)); + } + + // We must assume that the class value has been correctly filled, even if the service is created by a factory + $class = $def->getClass(); + + $refClass = new \ReflectionClass($class); + $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; + if (!$refClass->implementsInterface($interface)) { + throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); + } + + $definition->addMethodCall('addSubscriberService', array($id, $class)); + } + } +} diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterListenersPassTest.php b/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php similarity index 94% rename from src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterListenersPassTest.php rename to src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php index b82053ece6..5959db0d42 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/RegisterListenersPassTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\HttpKernel\Tests\DependencyInjection; +namespace Symfony\Component\EventDispatcher\Tests\DependencyInjection; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass; +use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass; class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase { @@ -67,7 +67,7 @@ class RegisterListenersPassTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(true)); $definition->expects($this->atLeastOnce()) ->method('getClass') - ->will($this->returnValue('Symfony\Component\HttpKernel\Tests\DependencyInjection\SubscriberService')); + ->will($this->returnValue('Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService')); $builder = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); $builder->expects($this->any()) diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md index 66219ae116..2b2e827d97 100644 --- a/src/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.5.0 +----- + + * deprecated `Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass`, use `Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass` instead + 2.4.0 ----- diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterListenersPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterListenersPass.php index 0e70b350bd..0e14e91652 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterListenersPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterListenersPass.php @@ -11,96 +11,13 @@ namespace Symfony\Component\HttpKernel\DependencyInjection; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass as BaseRegisterListenersPass; /** * Compiler pass to register tagged services for an event dispatcher. + * + * @deprecated Deprecated in 2.5, to be removed in 3.0. Use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass instead. */ -class RegisterListenersPass implements CompilerPassInterface +class RegisterListenersPass extends BaseRegisterListenersPass { - /** - * @var string - */ - protected $dispatcherService; - - /** - * @var string - */ - protected $listenerTag; - - /** - * @var string - */ - protected $subscriberTag; - - /** - * Constructor. - * - * @param string $dispatcherService Service name of the event dispatcher in processed container - * @param string $listenerTag Tag name used for listener - * @param string $subscriberTag Tag name used for subscribers - */ - public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber') - { - $this->dispatcherService = $dispatcherService; - $this->listenerTag = $listenerTag; - $this->subscriberTag = $subscriberTag; - } - - public function process(ContainerBuilder $container) - { - if (!$container->hasDefinition($this->dispatcherService) && !$container->hasAlias($this->dispatcherService)) { - return; - } - - $definition = $container->findDefinition($this->dispatcherService); - - foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) { - $def = $container->getDefinition($id); - if (!$def->isPublic()) { - throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event listeners are lazy-loaded.', $id)); - } - - if ($def->isAbstract()) { - throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as event listeners are lazy-loaded.', $id)); - } - - foreach ($events as $event) { - $priority = isset($event['priority']) ? $event['priority'] : 0; - - if (!isset($event['event'])) { - throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id)); - } - - if (!isset($event['method'])) { - $event['method'] = 'on'.preg_replace_callback(array( - '/(?<=\b)[a-z]/i', - '/[^a-z0-9]/i', - ), function ($matches) { return strtoupper($matches[0]); }, $event['event']); - $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']); - } - - $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); - } - } - - foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) { - $def = $container->getDefinition($id); - if (!$def->isPublic()) { - throw new \InvalidArgumentException(sprintf('The service "%s" must be public as event subscribers are lazy-loaded.', $id)); - } - - // We must assume that the class value has been correctly filled, even if the service is created by a factory - $class = $def->getClass(); - - $refClass = new \ReflectionClass($class); - $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; - if (!$refClass->implementsInterface($interface)) { - throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); - } - - $definition->addMethodCall('addSubscriberService', array($id, $class)); - } - } }