diff --git a/core/core.events.yml b/core/core.events.yml new file mode 100644 index 0000000..b741431 --- /dev/null +++ b/core/core.events.yml @@ -0,0 +1,20 @@ +subscribers: + config.init: + - callback: Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber::configInit + priority: 30 + kernel.controller: + - callback: Drupal\Core\EventSubscriber\LegacyControllerSubscriber::onKernelControllerLegacy + priority: 30 + kernel.request: + - Drupal\Core\Ajax\AjaxSubscriber::onKernelRequest + - callback: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber::onKernelRequestDetermineSiteStatus + priority: 40 + - callback: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber::onKernelRequestMaintenance + priority: 30 + - Drupal\Core\EventSubscriber\LegacyRequestSubscriber::onKernelRequestLegacy + kernel.response: + - finish_response_subscriber:onRespond + - redirect_response_subscriber:checkRedirectUrl + routing.route_alter: + - paramconverter_manager:onRoutingRouteAlterSetParameterConverters + - route_subscriber.entity:onRoutingRouteAlterSetType diff --git a/core/core.services.yml b/core/core.services.yml index 6f8cce6..2c00bca 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -297,11 +297,6 @@ services: - [setContainer, ['@service_container']] tags: - { name: route_enhancer } - paramconverter_subscriber: - class: Drupal\Core\EventSubscriber\ParamConverterSubscriber - tags: - - { name: event_subscriber } - arguments: ['@paramconverter_manager'] paramconverter.entity: class: Drupal\Core\ParamConverter\EntityConverter tags: @@ -309,8 +304,6 @@ services: arguments: ['@plugin.manager.entity'] route_subscriber.entity: class: Drupal\Core\EventSubscriber\EntityRouteAlterSubscriber - tags: - - { name: event_subscriber } arguments: ['@plugin.manager.entity'] reverse_proxy_subscriber: class: Drupal\Core\EventSubscriber\ReverseProxySubscriber @@ -387,44 +380,24 @@ services: arguments: ['@plugin.manager.entity'] tags: - { name: access_check } - maintenance_mode_subscriber: - class: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber - tags: - - { name: event_subscriber } path_subscriber: class: Drupal\Core\EventSubscriber\PathSubscriber tags: - { name: event_subscriber } arguments: ['@path.alias_manager.cached', '@path_processor_manager'] - legacy_request_subscriber: - class: Drupal\Core\EventSubscriber\LegacyRequestSubscriber - tags: - - { name: event_subscriber } - legacy_controller_subscriber: - class: Drupal\Core\EventSubscriber\LegacyControllerSubscriber - tags: - - { name: event_subscriber } finish_response_subscriber: class: Drupal\Core\EventSubscriber\FinishResponseSubscriber - tags: - - { name: event_subscriber } arguments: ['@language_manager'] scope: request redirect_response_subscriber: class: Drupal\Core\EventSubscriber\RedirectResponseSubscriber arguments: ['@url_generator'] - tags: - - { name: event_subscriber } scope: request request_close_subscriber: class: Drupal\Core\EventSubscriber\RequestCloseSubscriber tags: - { name: event_subscriber } arguments: ['@module_handler'] - config_global_override_subscriber: - class: Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber - tags: - - { name: event_subscriber } config_import_subscriber: class: Drupal\Core\EventSubscriber\ConfigImportSubscriber tags: @@ -481,10 +454,6 @@ services: - { name: event_subscriber } calls: - [setContainer, ['@service_container']] - ajax.subscriber: - class: Drupal\Core\Ajax\AjaxSubscriber - tags: - - { name: event_subscriber } image.toolkit.manager: class: Drupal\system\Plugin\ImageToolkitManager arguments: ['@container.namespaces', '@cache.cache', '@language_manager'] diff --git a/core/lib/Drupal/Core/Ajax/AjaxSubscriber.php b/core/lib/Drupal/Core/Ajax/AjaxSubscriber.php index 595d64e..a08d639 100644 --- a/core/lib/Drupal/Core/Ajax/AjaxSubscriber.php +++ b/core/lib/Drupal/Core/Ajax/AjaxSubscriber.php @@ -7,9 +7,7 @@ namespace Drupal\Core\Ajax; -use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Subscribes to the kernel request event to add the Ajax media type. @@ -17,7 +15,7 @@ * @param \Symfont\Component\HttpKernel\Event\GetResponseEvent $event * The event to process. */ -class AjaxSubscriber implements EventSubscriberInterface { +class AjaxSubscriber { /** * Registers Ajax formats with the Request class. @@ -29,15 +27,4 @@ public function onKernelRequest(GetResponseEvent $event) { $request->setFormat('drupal_modal', 'application/vnd.drupal-modal'); } - /** - * Registers the methods in this class that should be listeners. - * - * @return array - * An array of event listener definitions. - */ - static function getSubscribedEvents(){ - $events[KernelEvents::REQUEST][] = array('onKernelRequest', 50); - return $events; - } - } \ No newline at end of file diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php index a6cb957..77e89ce 100644 --- a/core/lib/Drupal/Core/CoreServiceProvider.php +++ b/core/lib/Drupal/Core/CoreServiceProvider.php @@ -8,6 +8,7 @@ namespace Drupal\Core; use Drupal\Core\Cache\ListCacheBinsPass; +use Drupal\Core\EventListenerPass; use Drupal\Core\DependencyInjection\ServiceProviderInterface; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass; @@ -54,6 +55,7 @@ public function register(ContainerBuilder $container) { $container->addCompilerPass(new RegisterRouteFiltersPass()); // Add a compiler pass for registering event subscribers. $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING); + $container->addCompilerPass(new EventListenerPass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new RegisterAccessChecksPass()); // Add a compiler pass for upcasting route parameters. $container->addCompilerPass(new RegisterParamConvertersPass()); diff --git a/core/lib/Drupal/Core/EventListenerPass.php b/core/lib/Drupal/Core/EventListenerPass.php new file mode 100644 index 0000000..695c864 --- /dev/null +++ b/core/lib/Drupal/Core/EventListenerPass.php @@ -0,0 +1,98 @@ +hasDefinition('event_dispatcher')) { + return; + } + + $event_dispatcher_definition = $container->getDefinition('event_dispatcher'); + $module_handler = $container->get('module_handler'); + + $this->findListeners($container, $event_dispatcher_definition, $module_handler); + } + + protected function findListeners($container, $event_dispatcher_definition, $module_handler) { + $directories = $module_handler->getModuleDirectories(); + $yaml_discovery = new YamlDiscovery('events', array('core') + $directories); + + foreach ($yaml_discovery->findAll() as $info) { + foreach ($info['subscribers'] as $event_id => $listeners) { + foreach ($listeners as $listener) { + list($add_method, $args) = $this->prepareListener($container, $event_id, $listener); + $event_dispatcher_definition->addMethodCall($add_method, $args); + } + } + } + } + + protected function prepareListener($container, $event_id, $listener) { + if (is_array($listener)) { + $callback = $listener['callback']; + if (isset($listener['priority'])) { + $priority = $listener['priority']; + } + } + else { + $callback = $listener; + } + + $callback_parts = $this->parseCallback($callback); + $method = $callback_parts['method']; + if (isset($callback_parts['class'])) { + $callback_parts['service'] = $this->defineService($container, $callback_parts['class']); + } + $args = array($event_id, array($callback_parts['service'], $method)); + $add_method = 'addListenerService'; + + if (isset($priority)) { + $args[] = $priority; + } + return array($add_method, $args); + } + + protected function defineService($container, $class) { + $definition = new Definition(); + $definition->setClass($class); + $name = 'event_listener.' . str_replace("\\", '.', $class); + $container->setDefinition($name, $definition); + return $name; + } + + protected function parseCallback($callback) { + // TODO: This logic should abstracted somewhere. + + // Callback in the service:method notation. + $count = substr_count($callback, ':'); + if ($count == 1) { + list($service, $method) = explode(':', $callback, 2); + return array('service' => $service, 'method' => $method); + } + + // Callback in the class::method notation. + if (strpos($callback, '::') !== FALSE) { + list($class, $method) = explode('::', $callback, 2); + if (!class_exists($class)) { + throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + } + return array('class' => $class, 'method' => $method); + } + else { + throw new \LogicException(sprintf('Unable to parse the callback name "%s".', $callback)); + } + } +} + diff --git a/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php index 02bf2cb..c3dee4e 100644 --- a/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/ConfigGlobalOverrideSubscriber.php @@ -7,14 +7,12 @@ namespace Drupal\Core\EventSubscriber; -use Drupal\Core\Config\Config; use Drupal\Core\Config\ConfigEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Defines a configuration global override for contexts. */ -class ConfigGlobalOverrideSubscriber implements EventSubscriberInterface { +class ConfigGlobalOverrideSubscriber { /** * Overrides configuration values with values in global $conf variable. @@ -31,12 +29,4 @@ public function configInit(ConfigEvent $event) { } } - /** - * Implements EventSubscriberInterface::getSubscribedEvents(). - */ - static function getSubscribedEvents() { - $events['config.init'][] = array('configInit', 30); - return $events; - } - } diff --git a/core/lib/Drupal/Core/EventSubscriber/EntityRouteAlterSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/EntityRouteAlterSubscriber.php index 53f9e31..b3d4551 100644 --- a/core/lib/Drupal/Core/EventSubscriber/EntityRouteAlterSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/EntityRouteAlterSubscriber.php @@ -8,8 +8,6 @@ namespace Drupal\Core\EventSubscriber; use Drupal\Core\Entity\EntityManager; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Drupal\Core\Routing\RoutingEvents; use Drupal\Core\Routing\RouteBuildEvent; /** @@ -23,7 +21,7 @@ * kind of PHP variable (e.g., a type hinted interface) the controller * requires: https://drupal.org/node/2041907. */ -class EntityRouteAlterSubscriber implements EventSubscriberInterface { +class EntityRouteAlterSubscriber { /** * Entity manager. @@ -67,12 +65,4 @@ public function onRoutingRouteAlterSetType(RouteBuildEvent $event) { } } } - - /** - * {@inheritdoc} - */ - static function getSubscribedEvents() { - $events[RoutingEvents::ALTER][] = array('onRoutingRouteAlterSetType', 100); - return $events; - } } diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php index 0c7307e..e556422 100644 --- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php @@ -10,14 +10,12 @@ use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManager; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; -use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Response subscriber to handle finished responses. */ -class FinishResponseSubscriber implements EventSubscriberInterface { +class FinishResponseSubscriber { /** * The LanguageManager object for retrieving the correct language code. @@ -110,14 +108,4 @@ public function onRespond(FilterResponseEvent $event) { } } - /** - * Registers the methods in this class that should be listeners. - * - * @return array - * An array of event listener definitions. - */ - static function getSubscribedEvents() { - $events[KernelEvents::RESPONSE][] = array('onRespond'); - return $events; - } } diff --git a/core/lib/Drupal/Core/EventSubscriber/LegacyControllerSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/LegacyControllerSubscriber.php index f88fa0e..0a7741c 100644 --- a/core/lib/Drupal/Core/EventSubscriber/LegacyControllerSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/LegacyControllerSubscriber.php @@ -7,14 +7,12 @@ namespace Drupal\Core\EventSubscriber; -use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Access subscriber for controller requests. */ -class LegacyControllerSubscriber implements EventSubscriberInterface { +class LegacyControllerSubscriber { /** * Wraps legacy controllers in a closure to handle old-style arguments. @@ -49,15 +47,4 @@ public function onKernelControllerLegacy(FilterControllerEvent $event) { } } - /** - * Registers the methods in this class that should be listeners. - * - * @return array - * An array of event listener definitions. - */ - static function getSubscribedEvents() { - $events[KernelEvents::CONTROLLER][] = array('onKernelControllerLegacy', 30); - - return $events; - } } diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php index c4d2f74..92ee298 100644 --- a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php @@ -9,14 +9,12 @@ use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Maintenance mode subscriber for controller requests. */ -class MaintenanceModeSubscriber implements EventSubscriberInterface { +class MaintenanceModeSubscriber { /** * Determine whether the page is configured to be offline. @@ -58,14 +56,4 @@ public function onKernelRequestMaintenance(GetResponseEvent $event) { } } - /** - * {@inheritdoc} - */ - static function getSubscribedEvents() { - // In order to change the maintenance status an event subscriber with a - // priority between 30 and 40 should be added. - $events[KernelEvents::REQUEST][] = array('onKernelRequestDetermineSiteStatus', 40); - $events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenance', 30); - return $events; - } } diff --git a/core/lib/Drupal/Core/EventSubscriber/ParamConverterSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ParamConverterSubscriber.php deleted file mode 100644 index f9a0a69..0000000 --- a/core/lib/Drupal/Core/EventSubscriber/ParamConverterSubscriber.php +++ /dev/null @@ -1,55 +0,0 @@ -paramConverterManager = $param_converter_manager; - } - - /** - * Applies parameter converters to route parameters. - * - * @param \Drupal\Core\Routing\RouteBuildEvent $event - * The event to process. - */ - public function onRoutingRouteAlterSetParameterConverters(RouteBuildEvent $event) { - $this->paramConverterManager->setRouteParameterConverters($event->getRouteCollection()); - } - - /** - * {@inheritdoc} - */ - static function getSubscribedEvents() { - $events[RoutingEvents::ALTER][] = array('onRoutingRouteAlterSetParameterConverters', 10); - return $events; - } -} diff --git a/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php index 9da318e..b40a787 100644 --- a/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php @@ -8,16 +8,14 @@ namespace Drupal\Core\EventSubscriber; use Drupal\Core\Routing\PathBasedGeneratorInterface; -use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Access subscriber for controller requests. */ -class RedirectResponseSubscriber implements EventSubscriberInterface { +class RedirectResponseSubscriber { /** * The url generator service. @@ -68,14 +66,4 @@ public function checkRedirectUrl(FilterResponseEvent $event) { } } - /** - * Registers the methods in this class that should be listeners. - * - * @return array - * An array of event listener definitions. - */ - static function getSubscribedEvents() { - $events[KernelEvents::RESPONSE][] = array('checkRedirectUrl'); - return $events; - } } diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php index c510192..be3dbe3 100644 --- a/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -900,4 +900,15 @@ public function uninstall($module_list = array(), $uninstall_dependents = TRUE) return TRUE; } + /** + * {@inheritdoc} + */ + public function getModuleDirectories() { + $dirs = array(); + foreach ($this->getModuleList() as $module => $filename) { + $dirs[$module] = dirname($filename); + } + return $dirs; + } + } diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php index f4b8a31..30c78e6 100644 --- a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php +++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php @@ -7,6 +7,7 @@ namespace Drupal\Core\ParamConverter; +use Drupal\Core\Routing\RouteBuildEvent; use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface; use Symfony\Cmf\Component\Routing\RouteObjectInterface; @@ -186,5 +187,15 @@ public function enhance(array $defaults, Request $request) { return $defaults; } + /** + * Applies parameter converters to route parameters. + * + * @param \Drupal\Core\Routing\RouteBuildEvent $event + * The event to process. + */ + public function onRoutingRouteAlterSetParameterConverters(RouteBuildEvent $event) { + $this->setRouteParameterConverters($event->getRouteCollection()); + } + } diff --git a/core/modules/image/image.events.yml b/core/modules/image/image.events.yml new file mode 100644 index 0000000..f45dcdc --- /dev/null +++ b/core/modules/image/image.events.yml @@ -0,0 +1,3 @@ +subscribers: + routing.route_dynamic: + - Drupal\image\EventSubscriber\RouteSubscriber::dynamicRoutes diff --git a/core/modules/image/image.services.yml b/core/modules/image/image.services.yml index 2af4f1c..946e58e 100644 --- a/core/modules/image/image.services.yml +++ b/core/modules/image/image.services.yml @@ -1,8 +1,4 @@ services: - image.route_subscriber: - class: Drupal\image\EventSubscriber\RouteSubscriber - tags: - - { name: 'event_subscriber' } path_processor.image_styles: class: Drupal\image\PathProcessor\PathProcessorImageStyles tags: diff --git a/core/modules/user/user.events.yml b/core/modules/user/user.events.yml new file mode 100644 index 0000000..4862e71 --- /dev/null +++ b/core/modules/user/user.events.yml @@ -0,0 +1,4 @@ +subscribers: + kernel.request: + - callback: Drupal\user\EventSubscriber\MaintenanceModeSubscriber::onKernelRequestMaintenance + priority: 35 diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml index 6fb7d47..468955d 100644 --- a/core/modules/user/user.services.yml +++ b/core/modules/user/user.services.yml @@ -21,7 +21,3 @@ services: user.autocomplete: class: Drupal\user\UserAutocomplete arguments: ['@database', '@config.factory'] - user_maintenance_mode_subscriber: - class: Drupal\user\EventSubscriber\MaintenanceModeSubscriber - tags: - - { name: event_subscriber } diff --git a/core/modules/views/views.events.yml b/core/modules/views/views.events.yml new file mode 100644 index 0000000..c68c984 --- /dev/null +++ b/core/modules/views/views.events.yml @@ -0,0 +1,3 @@ +subscribers: + routing.route_dynamic: + - Drupal\views\EventSubscriber\RouteSubscriber::dynamicRoutes diff --git a/core/modules/views/views.services.yml b/core/modules/views/views.services.yml index d5ab9d9..0f41597 100644 --- a/core/modules/views/views.services.yml +++ b/core/modules/views/views.services.yml @@ -81,11 +81,6 @@ services: factory_method: get factory_service: cache_factory arguments: [views_results] - views.route_subscriber: - class: Drupal\views\EventSubscriber\RouteSubscriber - arguments: ['@config.factory'] - tags: - - { name: 'event_subscriber' } views.route_access_check: class: Drupal\views\ViewsAccessCheck tags: