From eeb0742826509ebd48c0bd9947ee2fedc8fa1c26 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 27 Aug 2010 11:24:30 +0200 Subject: [PATCH] [Framework] added a way to retrieve called and not-called events for a given dispatcher --- .../Framework/Debug/EventDispatcher.php | 63 ++++++++++++++----- .../EventDispatcherTraceableInterface.php | 22 +++++++ src/Symfony/Framework/EventDispatcher.php | 6 +- .../Framework/Resources/config/debug.xml | 4 +- .../Framework/Resources/config/services.xml | 4 +- 5 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 src/Symfony/Framework/Debug/EventDispatcherTraceableInterface.php diff --git a/src/Symfony/Framework/Debug/EventDispatcher.php b/src/Symfony/Framework/Debug/EventDispatcher.php index 652b25cfca3a..90a9adfd7894 100644 --- a/src/Symfony/Framework/Debug/EventDispatcher.php +++ b/src/Symfony/Framework/Debug/EventDispatcher.php @@ -6,7 +6,6 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\HttpKernel\Log\LoggerInterface; -use Symfony\Component\DependencyInjection\ContainerInterface; /* * This file is part of the Symfony package. @@ -22,20 +21,20 @@ * * @author Fabien Potencier */ -class EventDispatcher extends BaseEventDispatcher +class EventDispatcher extends BaseEventDispatcher implements EventDispatcherTraceableInterface { protected $logger; + protected $called; /** * Constructor. * * @param LoggerInterface $logger A LoggerInterface instance */ - public function __construct(ContainerInterface $container, LoggerInterface $logger = null) + public function __construct(LoggerInterface $logger = null) { $this->logger = $logger; - - parent::__construct($container); + $this->called = array(); } /** @@ -48,9 +47,7 @@ public function __construct(ContainerInterface $container, LoggerInterface $logg public function notify(Event $event) { foreach ($this->getListeners($event->getName()) as $listener) { - if (null !== $this->logger) { - $this->logger->debug(sprintf('Notifying event "%s" to listener "%s"', $event->getName(), $this->listenerToString($listener))); - } + $this->addCall($event, $listener, 'notify'); call_user_func($listener, $event); } @@ -68,9 +65,7 @@ public function notify(Event $event) public function notifyUntil(Event $event) { foreach ($this->getListeners($event->getName()) as $i => $listener) { - if (null !== $this->logger) { - $this->logger->debug(sprintf('Notifying (until) event "%s" to listener "%s"', $event->getName(), $this->listenerToString($listener))); - } + $this->addCall($event, $listener, 'notifyUntil'); if (call_user_func($listener, $event)) { if (null !== $this->logger) { @@ -101,9 +96,7 @@ public function notifyUntil(Event $event) public function filter(Event $event, $value) { foreach ($this->getListeners($event->getName()) as $listener) { - if (null !== $this->logger) { - $this->logger->debug(sprintf('Notifying (filter) event "%s" to listener "%s"', $event->getName(), $this->listenerToString($listener))); - } + $this->addCall($event, $listener, 'filter'); $value = call_user_func($listener, $event, $value); } @@ -113,6 +106,31 @@ public function filter(Event $event, $value) return $event; } + public function getCalledEvents() + { + return $this->called; + } + + public function getNotCalledEvents() + { + $notCalled = array(); + + foreach (array_keys($this->listeners) as $name) { + foreach ($this->getListeners($name) as $listener) { + $listener = $this->listenerToString($listener); + + if (!isset($this->called[$name.'.'.$listener])) { + $notCalled[] = array( + 'event' => $name, + 'listener' => $listener, + ); + } + } + } + + return $notCalled; + } + protected function listenerToString($listener) { if (is_object($listener) && $listener instanceof \Closure) { @@ -124,7 +142,22 @@ protected function listenerToString($listener) } if (is_array($listener)) { - return sprintf('(%s, %s)', is_object($listener[0]) ? get_class($listener[0]) : $listener[0], $listener[1]); + return sprintf('%s::%s', is_object($listener[0]) ? get_class($listener[0]) : $listener[0], $listener[1]); } } + + protected function addCall(Event $event, $listener, $type) + { + $listener = $this->listenerToString($listener); + + if (null !== $this->logger) { + $this->logger->debug(sprintf('Notified event "%s" to listener "%s" (%s)', $event->getName(), $listener, $type)); + } + + $this->called[$event->getName().'.'.$listener] = array( + 'event' => $event->getName(), + 'caller' => null !== $event->getSubject() ? get_class($event->getSubject()) : null, + 'listener' => $listener, + ); + } } diff --git a/src/Symfony/Framework/Debug/EventDispatcherTraceableInterface.php b/src/Symfony/Framework/Debug/EventDispatcherTraceableInterface.php new file mode 100644 index 000000000000..0ddce45229e5 --- /dev/null +++ b/src/Symfony/Framework/Debug/EventDispatcherTraceableInterface.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @author Fabien Potencier + */ +interface EventDispatcherTraceableInterface +{ + function getCalledEvents(); + + function getNotCalledEvents(); +} diff --git a/src/Symfony/Framework/EventDispatcher.php b/src/Symfony/Framework/EventDispatcher.php index 9b336be73a2e..f573e90439db 100644 --- a/src/Symfony/Framework/EventDispatcher.php +++ b/src/Symfony/Framework/EventDispatcher.php @@ -22,11 +22,7 @@ */ class EventDispatcher extends BaseEventDispatcher { - /** - * Constructor. - * - */ - public function __construct(ContainerInterface $container) + public function setContainer(ContainerInterface $container) { foreach ($container->findTaggedServiceIds('kernel.listener') as $id => $attributes) { $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; diff --git a/src/Symfony/Framework/Resources/config/debug.xml b/src/Symfony/Framework/Resources/config/debug.xml index b63decc0877d..2519e88437ce 100644 --- a/src/Symfony/Framework/Resources/config/debug.xml +++ b/src/Symfony/Framework/Resources/config/debug.xml @@ -10,8 +10,10 @@ - + + + diff --git a/src/Symfony/Framework/Resources/config/services.xml b/src/Symfony/Framework/Resources/config/services.xml index b18ed59de225..7f688a537924 100644 --- a/src/Symfony/Framework/Resources/config/services.xml +++ b/src/Symfony/Framework/Resources/config/services.xml @@ -15,7 +15,9 @@ - + + +