2010-01-04 14:26:20 +00:00
< ? php
/*
2011-03-13 18:03:18 +00:00
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
2010-04-07 02:07:59 +01:00
*
2011-03-13 18:03:18 +00:00
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL . For more information , see
* < http :// www . doctrine - project . org >.
2010-01-04 14:26:20 +00:00
*/
2011-01-15 13:29:43 +00:00
namespace Symfony\Component\EventDispatcher ;
2010-01-04 14:26:20 +00:00
/**
2011-03-17 14:27:42 +00:00
* The EventDispatcherInterface is the central point of Symfony ' s event listener system .
*
2011-03-13 18:03:18 +00:00
* Listeners are registered on the manager and events are dispatched through the
* manager .
2010-01-04 14:26:20 +00:00
*
2011-03-13 18:03:18 +00:00
* @ license http :// www . opensource . org / licenses / lgpl - license . php LGPL
* @ author Guilherme Blanco < guilhermeblanco @ hotmail . com >
* @ author Jonathan Wage < jonwage @ gmail . com >
* @ author Roman Borschel < roman @ code - factory . org >
* @ author Bernhard Schussek < bschussek @ gmail . com >
2011-03-18 08:01:19 +00:00
* @ author Fabien Potencier < fabien @ symfony . com >
2011-05-05 08:15:48 +01:00
* @ author Jordi Boggiano < j . boggiano @ seld . be >
2011-03-24 09:06:26 +00:00
*
* @ api
2010-01-04 14:26:20 +00:00
*/
2011-01-25 13:23:23 +00:00
class EventDispatcher implements EventDispatcherInterface
2010-01-04 14:26:20 +00:00
{
2011-03-13 18:03:18 +00:00
private $listeners = array ();
private $sorted = array ();
/**
2011-03-17 14:27:42 +00:00
* @ see EventDispatcherInterface :: dispatch
2011-03-24 09:06:26 +00:00
*
* @ api
2011-03-13 18:03:18 +00:00
*/
2011-03-17 14:27:42 +00:00
public function dispatch ( $eventName , Event $event = null )
2010-01-04 14:26:20 +00:00
{
2011-03-18 08:01:19 +00:00
if ( ! isset ( $this -> listeners [ $eventName ])) {
return ;
}
2010-12-03 17:47:54 +00:00
2011-03-18 08:01:19 +00:00
if ( null === $event ) {
$event = new Event ();
}
2011-03-13 18:03:18 +00:00
2011-05-05 08:15:48 +01:00
$this -> doDispatch ( $this -> getListeners ( $eventName ), $eventName , $event );
2010-01-04 14:26:20 +00:00
}
2010-05-06 12:25:53 +01:00
/**
2011-03-13 18:03:18 +00:00
* @ see EventDispatcherInterface :: getListeners
2011-03-24 09:06:26 +00:00
*
* @ api
2010-05-06 12:25:53 +01:00
*/
2011-03-13 18:03:18 +00:00
public function getListeners ( $eventName = null )
2010-01-04 14:26:20 +00:00
{
2011-03-18 08:01:19 +00:00
if ( null !== $eventName ) {
if ( ! isset ( $this -> sorted [ $eventName ])) {
$this -> sortListeners ( $eventName );
}
2011-03-13 18:03:18 +00:00
2011-03-18 08:01:19 +00:00
return $this -> sorted [ $eventName ];
2011-03-13 18:03:18 +00:00
}
2011-03-18 17:48:26 +00:00
foreach ( array_keys ( $this -> listeners ) as $eventName ) {
2011-03-18 08:01:19 +00:00
if ( ! isset ( $this -> sorted [ $eventName ])) {
$this -> sortListeners ( $eventName );
}
if ( $this -> sorted [ $eventName ]) {
$sorted [ $eventName ] = $this -> sorted [ $eventName ];
}
2010-05-06 12:25:53 +01:00
}
2011-05-05 08:20:23 +01:00
return $this -> sorted ;
2010-01-04 14:26:20 +00:00
}
2010-05-06 12:25:53 +01:00
/**
2011-03-13 18:03:18 +00:00
* @ see EventDispatcherInterface :: hasListeners
2011-03-24 09:06:26 +00:00
*
* @ api
2010-05-06 12:25:53 +01:00
*/
2011-03-18 08:01:19 +00:00
public function hasListeners ( $eventName = null )
2010-01-04 14:26:20 +00:00
{
2011-03-18 08:01:19 +00:00
return ( Boolean ) count ( $this -> getListeners ( $eventName ));
2010-01-04 14:26:20 +00:00
}
2010-05-06 12:25:53 +01:00
/**
2011-03-17 14:27:42 +00:00
* @ see EventDispatcherInterface :: addListener
2011-03-24 09:06:26 +00:00
*
* @ api
2010-05-06 12:25:53 +01:00
*/
2011-05-05 18:02:52 +01:00
public function addListener ( $eventName , $listener , $priority = 0 )
2010-01-04 14:26:20 +00:00
{
2011-05-05 18:02:52 +01:00
$this -> listeners [ $eventName ][ $priority ][] = $listener ;
unset ( $this -> sorted [ $eventName ]);
2011-03-13 18:03:18 +00:00
}
2010-01-04 14:26:20 +00:00
2011-03-13 18:03:18 +00:00
/**
2011-03-17 14:27:42 +00:00
* @ see EventDispatcherInterface :: removeListener
2011-03-13 18:03:18 +00:00
*/
2011-05-05 18:02:52 +01:00
public function removeListener ( $eventName , $listener )
2011-03-13 18:03:18 +00:00
{
2011-05-05 18:02:52 +01:00
if ( ! isset ( $this -> listeners [ $eventName ])) {
return ;
}
2011-03-18 08:01:19 +00:00
2011-05-05 18:02:52 +01:00
foreach ( $this -> listeners [ $eventName ] as $priority => $listeners ) {
if ( false !== ( $key = array_search ( $listener , $listeners ))) {
unset ( $this -> listeners [ $eventName ][ $priority ][ $key ], $this -> sorted [ $eventName ]);
2011-03-13 18:03:18 +00:00
}
}
}
2010-08-26 13:08:42 +01:00
2011-03-13 18:03:18 +00:00
/**
2011-03-17 14:27:42 +00:00
* @ see EventDispatcherInterface :: addSubscriber
2011-03-13 18:03:18 +00:00
*/
2011-03-17 14:27:42 +00:00
public function addSubscriber ( EventSubscriberInterface $subscriber , $priority = 0 )
2011-03-13 18:03:18 +00:00
{
2011-05-05 18:02:52 +01:00
foreach (( array ) $subscriber -> getSubscribedEvents () as $eventName => $method ) {
if ( is_numeric ( $eventName )) {
$eventName = $method ;
}
$this -> addListener ( $eventName , array ( $subscriber , $method ), $priority );
}
2011-03-17 14:27:42 +00:00
}
2011-03-18 08:00:58 +00:00
/**
* @ see EventDispatcherInterface :: removeSubscriber
*/
public function removeSubscriber ( EventSubscriberInterface $subscriber )
{
2011-05-05 18:02:52 +01:00
foreach (( array ) $subscriber -> getSubscribedEvents () as $eventName => $method ) {
if ( is_numeric ( $eventName )) {
$eventName = $method ;
}
$this -> removeListener ( $eventName , array ( $subscriber , $method ));
}
2011-03-18 08:00:58 +00:00
}
2011-03-17 14:27:42 +00:00
/**
2011-05-05 08:15:48 +01:00
* Triggers the listeners of an event .
2011-03-17 14:27:42 +00:00
*
* This method can be overridden to add functionality that is executed
* for each listener .
*
2011-05-05 08:15:48 +01:00
* @ param array [ callback ] $listeners The event listeners .
* @ param string $eventName The name of the event to dispatch .
* @ param Event $event The event object to pass to the event handlers / listeners .
2011-03-17 14:27:42 +00:00
*/
2011-05-05 08:15:48 +01:00
protected function doDispatch ( $listeners , $eventName , Event $event )
2011-03-17 14:27:42 +00:00
{
2011-05-05 08:15:48 +01:00
foreach ( $listeners as $listener ) {
2011-05-05 18:02:52 +01:00
// TODO: remove this before final release, temporary transitional code
if ( is_object ( $listener ) && method_exists ( $listener , $eventName )) {
2011-05-05 08:15:48 +01:00
$listener -> $eventName ( $event );
2011-05-05 18:02:52 +01:00
//trigger_error('Event listeners should now be registered using a complete callback as the listener instead of just an instance. Adjust your code ASAP.', E_USER_DEPRECATED);
} else {
// only this call should remain
call_user_func ( $listener , $event );
2011-05-05 08:15:48 +01:00
}
if ( $event -> isPropagationStopped ()) {
break ;
}
2011-03-17 14:27:42 +00:00
}
}
/**
* Sorts the internal list of listeners for the given event by priority .
*
2011-03-18 08:01:19 +00:00
* @ param string $eventName The name of the event .
2011-03-17 14:27:42 +00:00
*/
private function sortListeners ( $eventName )
{
2011-03-18 08:01:19 +00:00
$this -> sorted [ $eventName ] = array ();
if ( isset ( $this -> listeners [ $eventName ])) {
krsort ( $this -> listeners [ $eventName ]);
2011-03-18 17:48:26 +00:00
foreach ( $this -> listeners [ $eventName ] as $listeners ) {
foreach ( $listeners as $listener ) {
$this -> sorted [ $eventName ][] = $listener ;
}
}
2011-03-17 14:27:42 +00:00
}
2010-05-06 12:25:53 +01:00
}
2011-03-17 14:27:42 +00:00
}