Skip to content

Commit

Permalink
changed the EventDispatcher and Event interfaces
Browse files Browse the repository at this point in the history
The three notification methods do not return the Event instance anymore.

notify() does not return anything
notifyUntil() returns the returned value of the event that has processed the event
filter() returns the filtered value

Upgrading your listeners:
Listeners for notify() and filter() events: nothing to change
Listeners for notifyUntil() events:

Before:

    $event->setReturnValue('foo');
    return true;

After:

    $event->setProcessed();
    return 'foo';

If you notify events, the processing also need to be changed:

For filter() notifications: the filtered value is now available as
the returned value of the filter() method.

For notifyUntil() notifications:

Before:

    $event = $dispatcher->notifyUntil($event);
    if ($event->isProcessed()) {
        $ret = $event->getReturnValue();

        // do something with $ret
    }

After:

    $ret = $dispatcher->notifyUntil($event);
    if ($event->isProcessed()) {
        // do something with $ret
    }
  • Loading branch information
fabpot committed Jan 26, 2011
1 parent a66d050 commit 8b62df7
Show file tree
Hide file tree
Showing 19 changed files with 95 additions and 149 deletions.
14 changes: 4 additions & 10 deletions src/Symfony/Bundle/FrameworkBundle/Debug/EventDispatcher.php
Expand Up @@ -55,8 +55,6 @@ public function notify(EventInterface $event)

call_user_func($listener, $event);
}

return $event;
}

/**
Expand All @@ -71,7 +69,8 @@ public function notifyUntil(EventInterface $event)

$this->addCall($event, $listener, 'notifyUntil');

if (call_user_func($listener, $event)) {
$ret = call_user_func($listener, $event);
if ($event->isProcessed()) {
if (null !== $this->logger) {
$this->logger->debug(sprintf('Listener "%s" processed the event "%s"', $this->listenerToString($listener), $event->getName()));

Expand All @@ -81,12 +80,9 @@ public function notifyUntil(EventInterface $event)
}
}

$event->setProcessed(true);
break;
return $ret;
}
}

return $event;
}

/**
Expand All @@ -104,9 +100,7 @@ public function filter(EventInterface $event, $value)
$value = call_user_func($listener, $event, $value);
}

$event->setReturnValue($value);

return $event;
return $value;
}

/**
Expand Down
15 changes: 5 additions & 10 deletions src/Symfony/Bundle/FrameworkBundle/EventDispatcher.php
Expand Up @@ -50,8 +50,6 @@ public function notify(EventInterface $event)
}
call_user_func($listener, $event);
}

return $event;
}

/**
Expand All @@ -63,13 +61,12 @@ public function notifyUntil(EventInterface $event)
if (is_array($listener) && is_string($listener[0])) {
$listener[0] = $this->container->get($listener[0]);
}
if (call_user_func($listener, $event)) {
$event->setProcessed(true);
break;

$ret = call_user_func($listener, $event);
if ($event->isProcessed()) {
return $ret;
}
}

return $event;
}

/**
Expand All @@ -84,8 +81,6 @@ public function filter(EventInterface $event, $value)
$value = call_user_func($listener, $event, $value);
}

$event->setReturnValue($value);

return $event;
return $value;
}
}
34 changes: 10 additions & 24 deletions src/Symfony/Component/EventDispatcher/Event.php
Expand Up @@ -59,38 +59,24 @@ public function getName()
}

/**
* Sets the return value for this event.
* Sets the processed flag to true.
*
* @param mixed $value The return value
* This method must be called by listeners when
* it has processed the event (it is only meaninful
* when the event has been notified with the notifyUntil()
* dispatcher method.
*/
public function setReturnValue($value)
public function setProcessed()
{
$this->value = $value;
}

/**
* Returns the return value.
*
* @return mixed The return value
*/
public function getReturnValue()
{
return $this->value;
}

/**
* Sets the processed flag.
*
* @param Boolean $processed The processed flag value
*/
public function setProcessed($processed)
{
$this->processed = (Boolean) $processed;
$this->processed = true;
}

/**
* Returns whether the event has been processed by a listener or not.
*
* This method is only meaningful for events notified
* with notifyUntil().
*
* @return Boolean true if the event has been processed, false otherwise
*/
public function isProcessed()
Expand Down
22 changes: 7 additions & 15 deletions src/Symfony/Component/EventDispatcher/EventDispatcher.php
Expand Up @@ -73,35 +73,29 @@ public function disconnect($name, $listener = null)
* Notifies all listeners of a given event.
*
* @param EventInterface $event An EventInterface instance
*
* @return EventInterface The EventInterface instance
*/
public function notify(EventInterface $event)
{
foreach ($this->getListeners($event->getName()) as $listener) {
call_user_func($listener, $event);
}

return $event;
}

/**
* Notifies all listeners of a given event until one returns a non null value.
* Notifies all listeners of a given event until one processes the event.
*
* @param EventInterface $event An EventInterface instance
*
* @return EventInterface The EventInterface instance
* @return mixed The returned value of the listener that processed the event
*/
public function notifyUntil(EventInterface $event)
{
foreach ($this->getListeners($event->getName()) as $listener) {
if (call_user_func($listener, $event)) {
$event->setProcessed(true);
break;
$ret = call_user_func($listener, $event);
if ($event->isProcessed()) {
return $ret;
}
}

return $event;
}

/**
Expand All @@ -110,17 +104,15 @@ public function notifyUntil(EventInterface $event)
* @param EventInterface $event An EventInterface instance
* @param mixed $value The value to be filtered
*
* @return EventInterface The EventInterface instance
* @return mixed The filtered value
*/
public function filter(EventInterface $event, $value)
{
foreach ($this->getListeners($event->getName()) as $listener) {
$value = call_user_func($listener, $event, $value);
}

$event->setReturnValue($value);

return $event;
return $value;
}

/**
Expand Down
Expand Up @@ -45,17 +45,20 @@ function disconnect($name, $listener = null);
* Notifies all listeners of a given event.
*
* @param EventInterface $event An EventInterface instance
*
* @return EventInterface The EventInterface instance
*/
function notify(EventInterface $event);

/**
* Notifies all listeners of a given event until one returns a non null value.
* Notifies all listeners of a given event until one processes the event.
*
* A listener tells the dispatcher that it has processed the event
* by calling the setProcessed() method on it.
*
* It can then return a value that will be fowarded to the caller.
*
* @param EventInterface $event An EventInterface instance
*
* @return EventInterface The EventInterface instance
* @return mixed The returned value of the listener that processed the event
*/
function notifyUntil(EventInterface $event);

Expand All @@ -65,7 +68,7 @@ function notifyUntil(EventInterface $event);
* @param EventInterface $event An EventInterface instance
* @param mixed $value The value to be filtered
*
* @return EventInterface The EventInterface instance
* @return mixed The filtered value
*/
function filter(EventInterface $event, $value);

Expand Down
26 changes: 9 additions & 17 deletions src/Symfony/Component/EventDispatcher/EventInterface.php
Expand Up @@ -33,29 +33,21 @@ function getSubject();
function getName();

/**
* Sets the return value for this event.
* Sets the processed flag to true.
*
* @param mixed $value The return value
* This method must be called by listeners when
* it has processed the event (it is only meaninful
* when the event has been notified with the notifyUntil()
* dispatcher method.
*/
function setReturnValue($value);

/**
* Returns the return value.
*
* @return mixed The return value
*/
function getReturnValue();

/**
* Sets the processed flag.
*
* @param Boolean $processed The processed flag value
*/
function setProcessed($processed);
function setProcessed();

/**
* Returns whether the event has been processed by a listener or not.
*
* This method is only meaningful for events notified
* with notifyUntil().
*
* @return Boolean true if the event has been processed, false otherwise
*/
function isProcessed();
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/HttpKernel/Debug/ExceptionListener.php
Expand Up @@ -81,10 +81,10 @@ public function handle(EventInterface $event)
throw $exception;
}

$event->setReturnValue($response);
$event->setProcessed();

$handling = false;

return true;
return $response;
}
}
18 changes: 8 additions & 10 deletions src/Symfony/Component/HttpKernel/HttpKernel.php
Expand Up @@ -54,12 +54,12 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ

// exception
$event = new Event($this, 'core.exception', array('request_type' => $type, 'request' => $request, 'exception' => $e));
$this->dispatcher->notifyUntil($event);
$response = $this->dispatcher->notifyUntil($event);
if (!$event->isProcessed()) {
throw $e;
}

$response = $this->filterResponse($event->getReturnValue(), $request, 'A "core.exception" listener returned a non response object.', $type);
$response = $this->filterResponse($response, $request, 'A "core.exception" listener returned a non response object.', $type);
}

return $response;
Expand All @@ -82,9 +82,9 @@ protected function handleRaw(Request $request, $type = self::MASTER_REQUEST)
{
// request
$event = new Event($this, 'core.request', array('request_type' => $type, 'request' => $request));
$this->dispatcher->notifyUntil($event);
$response = $this->dispatcher->notifyUntil($event);
if ($event->isProcessed()) {
return $this->filterResponse($event->getReturnValue(), $request, 'A "core.request" listener returned a non response object.', $type);
return $this->filterResponse($response, $request, 'A "core.request" listener returned a non response object.', $type);
}

// load controller
Expand All @@ -93,8 +93,7 @@ protected function handleRaw(Request $request, $type = self::MASTER_REQUEST)
}

$event = new Event($this, 'core.controller', array('request_type' => $type, 'request' => $request));
$this->dispatcher->filter($event, $controller);
$controller = $event->getReturnValue();
$controller = $this->dispatcher->filter($event, $controller);

// controller must be a callable
if (!is_callable($controller)) {
Expand All @@ -109,9 +108,9 @@ protected function handleRaw(Request $request, $type = self::MASTER_REQUEST)

// view
$event = new Event($this, 'core.view', array('request_type' => $type, 'request' => $request));
$this->dispatcher->filter($event, $retval);
$response = $this->dispatcher->filter($event, $retval);

return $this->filterResponse($event->getReturnValue(), $request, sprintf('The controller must return a response (instead of %s).', is_object($event->getReturnValue()) ? 'an object of class '.get_class($event->getReturnValue()) : is_array($event->getReturnValue()) ? 'an array' : str_replace("\n", '', var_export($event->getReturnValue(), true))), $type);
return $this->filterResponse($response, $request, sprintf('The controller must return a response (instead of %s).', is_object($response) ? 'an object of class '.get_class($response) : is_array($response) ? 'an array' : str_replace("\n", '', var_export($response, true))), $type);
}

/**
Expand All @@ -131,8 +130,7 @@ protected function filterResponse($response, $request, $message, $type)
throw new \RuntimeException($message);
}

$event = $this->dispatcher->filter(new Event($this, 'core.response', array('request_type' => $type, 'request' => $request)), $response);
$response = $event->getReturnValue();
$response = $this->dispatcher->filter(new Event($this, 'core.response', array('request_type' => $type, 'request' => $request)), $response);

if (!$response instanceof Response) {
throw new \RuntimeException('A "core.response" listener returned a non response object.');
Expand Down
10 changes: 4 additions & 6 deletions src/Symfony/Component/HttpKernel/Security/Firewall.php
Expand Up @@ -85,13 +85,11 @@ public function handle(EventInterface $event)
}

// initiate the listener chain
$e = $this->dispatcher->notifyUntil(new Event($request, 'core.security', array('request' => $request)));
if ($e->isProcessed()) {
$event->setReturnValue($e->getReturnValue());
$ret = $this->dispatcher->notifyUntil($event = new Event($request, 'core.security', array('request' => $request)));
if ($event->isProcessed()) {
$event->setProcessed();

return true;
return $ret;
}

return;
}
}
Expand Up @@ -101,9 +101,9 @@ public function handle(EventInterface $event)
return;
}

$event->setReturnValue($this->authenticationEntryPoint->start($request, $failed));
$event->setProcessed();

return true;
return $this->authenticationEntryPoint->start($request, $failed);
}
}
}
Expand Up @@ -70,19 +70,19 @@ public function handle(EventInterface $event)
$this->logger->debug('Redirecting to HTTPS');
}

$event->setReturnValue($this->authenticationEntryPoint->start($request));
$event->setProcessed();

return true;
return $this->authenticationEntryPoint->start($request);
}

if ('http' === $channel && $request->isSecure()) {
if (null !== $this->logger) {
$this->logger->debug('Redirecting to HTTP');
}

$event->setReturnValue($this->authenticationEntryPoint->start($request));
$event->setProcessed();

return true;
return $this->authenticationEntryPoint->start($request);
}
}
}

0 comments on commit 8b62df7

Please sign in to comment.