diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 26519c7cc2..d1d26696e7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -5,6 +5,8 @@ CHANGELOG ----- * Added support for configuring PHP error level to log levels +* Added the `dispatcher` option to `debug:event-dispatcher` +* Added the `event_dispatcher.dispatcher` tag 5.2.0 ----- diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php index 5ff002d3c1..a053d96dd8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; +use Psr\Container\ContainerInterface; use Symfony\Bundle\FrameworkBundle\Console\Helper\DescriptorHelper; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -29,14 +30,16 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; */ class EventDispatcherDebugCommand extends Command { - protected static $defaultName = 'debug:event-dispatcher'; - private $dispatcher; + private const DEFAULT_DISPATCHER = 'event_dispatcher'; - public function __construct(EventDispatcherInterface $dispatcher) + protected static $defaultName = 'debug:event-dispatcher'; + private $dispatchers; + + public function __construct(ContainerInterface $dispatchers) { parent::__construct(); - $this->dispatcher = $dispatcher; + $this->dispatchers = $dispatchers; } /** @@ -47,6 +50,7 @@ class EventDispatcherDebugCommand extends Command $this ->setDefinition([ new InputArgument('event', InputArgument::OPTIONAL, 'An event name or a part of the event name'), + new InputOption('dispatcher', null, InputOption::VALUE_REQUIRED, 'To view events of a specific event dispatcher', self::DEFAULT_DISPATCHER), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'), ]) @@ -74,12 +78,21 @@ EOF $io = new SymfonyStyle($input, $output); $options = []; + $dispatcherServiceName = $input->getOption('dispatcher'); + if (!$this->dispatchers->has($dispatcherServiceName)) { + $io->getErrorStyle()->error(sprintf('Event dispatcher "%s" is not available.', $dispatcherServiceName)); + + return 1; + } + + $dispatcher = $this->dispatchers->get($dispatcherServiceName); + if ($event = $input->getArgument('event')) { - if ($this->dispatcher->hasListeners($event)) { + if ($dispatcher->hasListeners($event)) { $options = ['event' => $event]; } else { // if there is no direct match, try find partial matches - $events = $this->searchForEvent($this->dispatcher, $event); + $events = $this->searchForEvent($dispatcher, $event); if (0 === \count($events)) { $io->getErrorStyle()->warning(sprintf('The event "%s" does not have any registered listeners.', $event)); @@ -93,10 +106,15 @@ EOF } $helper = new DescriptorHelper(); + + if (self::DEFAULT_DISPATCHER !== $dispatcherServiceName) { + $options['dispatcher_service_name'] = $dispatcherServiceName; + } + $options['format'] = $input->getOption('format'); $options['raw_text'] = $input->getOption('raw'); $options['output'] = $io; - $helper->describe($io, $this->dispatcher, $options); + $helper->describe($io, $dispatcher, $options); return 0; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php index 5b97dab462..634fbb4750 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php @@ -287,8 +287,14 @@ class MarkdownDescriptor extends Descriptor protected function describeEventDispatcherListeners(EventDispatcherInterface $eventDispatcher, array $options = []) { $event = \array_key_exists('event', $options) ? $options['event'] : null; + $dispatcherServiceName = $options['dispatcher_service_name'] ?? null; $title = 'Registered listeners'; + + if (null !== $dispatcherServiceName) { + $title .= sprintf(' of event dispatcher "%s"', $dispatcherServiceName); + } + if (null !== $event) { $title .= sprintf(' for event `%s` ordered by descending priority', $event); $registeredListeners = $eventDispatcher->getListeners($event); diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index d68b4c4282..e83f15c65d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -474,12 +474,19 @@ class TextDescriptor extends Descriptor protected function describeEventDispatcherListeners(EventDispatcherInterface $eventDispatcher, array $options = []) { $event = \array_key_exists('event', $options) ? $options['event'] : null; + $dispatcherServiceName = $options['dispatcher_service_name'] ?? null; + + $title = 'Registered Listeners'; + + if (null !== $dispatcherServiceName) { + $title .= sprintf(' of Event Dispatcher "%s"', $dispatcherServiceName); + } if (null !== $event) { - $title = sprintf('Registered Listeners for "%s" Event', $event); + $title .= sprintf(' for "%s" Event', $event); $registeredListeners = $eventDispatcher->getListeners($event); } else { - $title = 'Registered Listeners Grouped by Event'; + $title .= ' Grouped by Event'; // Try to see if "events" exists $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(function ($event) use ($eventDispatcher) { return $eventDispatcher->getListeners($event); }, $options['events'])) : $eventDispatcher->getListeners(); } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php index 37f545468d..a38cde35d1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php @@ -43,6 +43,7 @@ class UnusedTagsPass implements CompilerPassInterface 'controller.argument_value_resolver', 'controller.service_arguments', 'data_collector', + 'event_dispatcher.dispatcher', 'form.type', 'form.type_extension', 'form.type_guesser', @@ -72,9 +73,9 @@ class UnusedTagsPass implements CompilerPassInterface 'routing.expression_language_provider', 'routing.loader', 'routing.route_loader', + 'security.authenticator.login_linker', 'security.expression_language_provider', 'security.remember_me_aware', - 'security.authenticator.login_linker', 'security.voter', 'serializer.encoder', 'serializer.normalizer', diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index a45de43954..bcf4f05c5d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -160,6 +160,7 @@ use Symfony\Component\Yaml\Yaml; use Symfony\Contracts\Cache\CacheInterface; use Symfony\Contracts\Cache\CallbackInterface; use Symfony\Contracts\Cache\TagAwareCacheInterface; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\Service\ResetInterface; use Symfony\Contracts\Service\ServiceSubscriberInterface; @@ -479,6 +480,8 @@ class FrameworkExtension extends Extension ->addTag('kernel.cache_clearer'); $container->registerForAutoconfiguration(CacheWarmerInterface::class) ->addTag('kernel.cache_warmer'); + $container->registerForAutoconfiguration(EventDispatcherInterface::class) + ->addTag('event_dispatcher.dispatcher'); $container->registerForAutoconfiguration(EventSubscriberInterface::class) ->addTag('kernel.event_subscriber'); $container->registerForAutoconfiguration(LocaleAwareInterface::class) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php index e9b3d2e36a..81531599f1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/console.php @@ -129,7 +129,7 @@ return static function (ContainerConfigurator $container) { ->set('console.command.event_dispatcher_debug', EventDispatcherDebugCommand::class) ->args([ - service('event_dispatcher'), + tagged_locator('event_dispatcher.dispatcher'), ]) ->tag('console.command', ['command' => 'debug:event-dispatcher']) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php index 4df97ed19c..a0603b2cf3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.php @@ -65,6 +65,7 @@ return static function (ContainerConfigurator $container) { ->set('event_dispatcher', EventDispatcher::class) ->public() ->tag('container.hot_path') + ->tag('event_dispatcher.dispatcher') ->alias(EventDispatcherInterfaceComponentAlias::class, 'event_dispatcher') ->alias(EventDispatcherInterface::class, 'event_dispatcher') diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 3c84bf3407..e297aeeb99 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -358,7 +358,8 @@ class SecurityExtension extends Extension implements PrependExtensionInterface // Register Firewall-specific event dispatcher $firewallEventDispatcherId = 'security.event_dispatcher.'.$id; - $container->register($firewallEventDispatcherId, EventDispatcher::class); + $container->register($firewallEventDispatcherId, EventDispatcher::class) + ->addTag('event_dispatcher.dispatcher'); // Register listeners $listeners = [];