2010-02-17 13:54:36 +00:00
|
|
|
<?php
|
|
|
|
|
2010-07-09 09:12:56 +01:00
|
|
|
namespace Symfony\Framework\Debug;
|
2010-02-17 13:54:36 +00:00
|
|
|
|
2010-07-09 09:12:56 +01:00
|
|
|
use Symfony\Framework\EventDispatcher as BaseEventDispatcher;
|
2010-08-20 22:09:55 +01:00
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
|
|
use Symfony\Component\EventDispatcher\Event;
|
|
|
|
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
2010-02-17 13:54:36 +00:00
|
|
|
|
|
|
|
/*
|
2010-04-07 01:51:29 +01:00
|
|
|
* This file is part of the Symfony package.
|
2010-02-17 13:54:36 +00:00
|
|
|
*
|
|
|
|
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
|
|
|
*
|
|
|
|
* For the full copyright and license information, please view the LICENSE
|
|
|
|
* file that was distributed with this source code.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* EventDispatcher extends the original EventDispatcher class to add some debugging tools.
|
|
|
|
*
|
|
|
|
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
|
|
|
*/
|
2010-08-27 10:24:30 +01:00
|
|
|
class EventDispatcher extends BaseEventDispatcher implements EventDispatcherTraceableInterface
|
2010-02-17 13:54:36 +00:00
|
|
|
{
|
2010-05-06 12:25:53 +01:00
|
|
|
protected $logger;
|
2010-08-27 10:24:30 +01:00
|
|
|
protected $called;
|
2010-05-06 12:25:53 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*
|
|
|
|
* @param LoggerInterface $logger A LoggerInterface instance
|
|
|
|
*/
|
2010-08-27 10:24:30 +01:00
|
|
|
public function __construct(LoggerInterface $logger = null)
|
2010-02-17 13:54:36 +00:00
|
|
|
{
|
2010-05-06 12:25:53 +01:00
|
|
|
$this->logger = $logger;
|
2010-08-27 10:24:30 +01:00
|
|
|
$this->called = array();
|
2010-02-17 13:54:36 +00:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Notifies all listeners of a given event.
|
|
|
|
*
|
|
|
|
* @param Event $event A Event instance
|
|
|
|
*
|
|
|
|
* @return Event The Event instance
|
|
|
|
*/
|
|
|
|
public function notify(Event $event)
|
2010-02-17 13:54:36 +00:00
|
|
|
{
|
2010-05-07 15:09:11 +01:00
|
|
|
foreach ($this->getListeners($event->getName()) as $listener) {
|
2010-08-27 10:24:30 +01:00
|
|
|
$this->addCall($event, $listener, 'notify');
|
2010-05-06 12:25:53 +01:00
|
|
|
|
|
|
|
call_user_func($listener, $event);
|
2010-02-17 13:54:36 +00:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
return $event;
|
2010-02-17 13:54:36 +00:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Notifies all listeners of a given event until one returns a non null value.
|
|
|
|
*
|
|
|
|
* @param Event $event A Event instance
|
|
|
|
*
|
|
|
|
* @return Event The Event instance
|
|
|
|
*/
|
|
|
|
public function notifyUntil(Event $event)
|
2010-02-17 13:54:36 +00:00
|
|
|
{
|
2010-08-26 10:18:15 +01:00
|
|
|
foreach ($this->getListeners($event->getName()) as $i => $listener) {
|
2010-08-27 10:24:30 +01:00
|
|
|
$this->addCall($event, $listener, 'notifyUntil');
|
2010-05-06 12:25:53 +01:00
|
|
|
|
2010-05-07 15:09:11 +01:00
|
|
|
if (call_user_func($listener, $event)) {
|
2010-05-08 14:32:30 +01:00
|
|
|
if (null !== $this->logger) {
|
2010-05-06 12:25:53 +01:00
|
|
|
$this->logger->debug(sprintf('Listener "%s" processed the event "%s"', $this->listenerToString($listener), $event->getName()));
|
2010-08-26 10:18:15 +01:00
|
|
|
|
|
|
|
$listeners = $this->getListeners($event->getName());
|
|
|
|
while (++$i < count($listeners)) {
|
|
|
|
$this->logger->debug(sprintf('Listener "%s" was not called for event "%s"', $this->listenerToString($listeners[$i]), $event->getName()));
|
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$event->setProcessed(true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-02-17 13:54:36 +00:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
return $event;
|
2010-02-17 13:54:36 +00:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
|
|
|
* Filters a value by calling all listeners of a given event.
|
|
|
|
*
|
|
|
|
* @param Event $event A Event instance
|
|
|
|
* @param mixed $value The value to be filtered
|
|
|
|
*
|
|
|
|
* @return Event The Event instance
|
|
|
|
*/
|
|
|
|
public function filter(Event $event, $value)
|
|
|
|
{
|
2010-05-07 15:09:11 +01:00
|
|
|
foreach ($this->getListeners($event->getName()) as $listener) {
|
2010-08-27 10:24:30 +01:00
|
|
|
$this->addCall($event, $listener, 'filter');
|
2010-02-17 13:54:36 +00:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
$value = call_user_func($listener, $event, $value);
|
|
|
|
}
|
2010-02-17 13:54:36 +00:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
$event->setReturnValue($value);
|
2010-02-17 13:54:36 +00:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
return $event;
|
2010-02-17 13:54:36 +00:00
|
|
|
}
|
|
|
|
|
2010-08-27 10:24:30 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
protected function listenerToString($listener)
|
2010-02-17 13:54:36 +00:00
|
|
|
{
|
2010-05-07 15:09:11 +01:00
|
|
|
if (is_object($listener) && $listener instanceof \Closure) {
|
2010-05-06 12:25:53 +01:00
|
|
|
return 'Closure';
|
|
|
|
}
|
|
|
|
|
2010-05-07 15:09:11 +01:00
|
|
|
if (is_string($listener)) {
|
2010-05-06 12:25:53 +01:00
|
|
|
return $listener;
|
|
|
|
}
|
|
|
|
|
2010-05-07 15:09:11 +01:00
|
|
|
if (is_array($listener)) {
|
2010-08-27 10:24:30 +01:00
|
|
|
return sprintf('%s::%s', is_object($listener[0]) ? get_class($listener[0]) : $listener[0], $listener[1]);
|
2010-05-06 12:25:53 +01:00
|
|
|
}
|
2010-02-17 13:54:36 +00:00
|
|
|
}
|
2010-08-27 10:24:30 +01:00
|
|
|
|
|
|
|
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,
|
|
|
|
);
|
|
|
|
}
|
2010-02-17 13:54:36 +00:00
|
|
|
}
|