2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\EventDispatcher ;
/**
* The EventDispatcherInterface is the central point of Symfony ' s event listener system .
*
* Listeners are registered on the manager and events are dispatched through the
* manager .
*
* @ 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 >
* @ author Fabien Potencier < fabien @ symfony . com >
* @ author Jordi Boggiano < j . boggiano @ seld . be >
* @ author Jordan Alliot < jordan . alliot @ gmail . com >
*/
class EventDispatcher implements EventDispatcherInterface
{
private $listeners = array ();
private $sorted = array ();
/**
2015-10-08 11:40:12 -07:00
* { @ inheritdoc }
2015-08-17 17:00:26 -07:00
*/
public function dispatch ( $eventName , Event $event = null )
{
if ( null === $event ) {
$event = new Event ();
}
$event -> setDispatcher ( $this );
$event -> setName ( $eventName );
2015-10-08 11:40:12 -07:00
if ( $listeners = $this -> getListeners ( $eventName )) {
$this -> doDispatch ( $listeners , $eventName , $event );
2015-08-17 17:00:26 -07:00
}
return $event ;
}
/**
2015-10-08 11:40:12 -07:00
* { @ inheritdoc }
2015-08-17 17:00:26 -07:00
*/
public function getListeners ( $eventName = null )
{
if ( null !== $eventName ) {
2015-10-08 11:40:12 -07:00
if ( ! isset ( $this -> listeners [ $eventName ])) {
return array ();
}
2015-08-17 17:00:26 -07:00
if ( ! isset ( $this -> sorted [ $eventName ])) {
$this -> sortListeners ( $eventName );
}
return $this -> sorted [ $eventName ];
}
foreach ( $this -> listeners as $eventName => $eventListeners ) {
if ( ! isset ( $this -> sorted [ $eventName ])) {
$this -> sortListeners ( $eventName );
}
}
return array_filter ( $this -> sorted );
}
2016-04-20 09:56:34 -07:00
/**
* Gets the listener priority for a specific event .
*
* Returns null if the event or the listener does not exist .
*
* @ param string $eventName The name of the event
* @ param callable $listener The listener
*
* @ return int | null The event listener priority
*/
public function getListenerPriority ( $eventName , $listener )
{
if ( ! isset ( $this -> listeners [ $eventName ])) {
return ;
}
foreach ( $this -> listeners [ $eventName ] as $priority => $listeners ) {
2017-02-02 16:28:38 -08:00
if ( false !== in_array ( $listener , $listeners , true )) {
2016-04-20 09:56:34 -07:00
return $priority ;
}
}
}
2015-08-17 17:00:26 -07:00
/**
2015-10-08 11:40:12 -07:00
* { @ inheritdoc }
2015-08-17 17:00:26 -07:00
*/
public function hasListeners ( $eventName = null )
{
2017-04-13 15:53:35 +01:00
return ( bool ) $this -> getListeners ( $eventName );
2015-08-17 17:00:26 -07:00
}
/**
2015-10-08 11:40:12 -07:00
* { @ inheritdoc }
2015-08-17 17:00:26 -07:00
*/
public function addListener ( $eventName , $listener , $priority = 0 )
{
$this -> listeners [ $eventName ][ $priority ][] = $listener ;
unset ( $this -> sorted [ $eventName ]);
}
/**
2015-10-08 11:40:12 -07:00
* { @ inheritdoc }
2015-08-17 17:00:26 -07:00
*/
public function removeListener ( $eventName , $listener )
{
if ( ! isset ( $this -> listeners [ $eventName ])) {
return ;
}
foreach ( $this -> listeners [ $eventName ] as $priority => $listeners ) {
if ( false !== ( $key = array_search ( $listener , $listeners , true ))) {
unset ( $this -> listeners [ $eventName ][ $priority ][ $key ], $this -> sorted [ $eventName ]);
}
}
}
/**
2015-10-08 11:40:12 -07:00
* { @ inheritdoc }
2015-08-17 17:00:26 -07:00
*/
public function addSubscriber ( EventSubscriberInterface $subscriber )
{
foreach ( $subscriber -> getSubscribedEvents () as $eventName => $params ) {
if ( is_string ( $params )) {
$this -> addListener ( $eventName , array ( $subscriber , $params ));
} elseif ( is_string ( $params [ 0 ])) {
$this -> addListener ( $eventName , array ( $subscriber , $params [ 0 ]), isset ( $params [ 1 ]) ? $params [ 1 ] : 0 );
} else {
foreach ( $params as $listener ) {
$this -> addListener ( $eventName , array ( $subscriber , $listener [ 0 ]), isset ( $listener [ 1 ]) ? $listener [ 1 ] : 0 );
}
}
}
}
/**
2015-10-08 11:40:12 -07:00
* { @ inheritdoc }
2015-08-17 17:00:26 -07:00
*/
public function removeSubscriber ( EventSubscriberInterface $subscriber )
{
foreach ( $subscriber -> getSubscribedEvents () as $eventName => $params ) {
if ( is_array ( $params ) && is_array ( $params [ 0 ])) {
foreach ( $params as $listener ) {
$this -> removeListener ( $eventName , array ( $subscriber , $listener [ 0 ]));
}
} else {
$this -> removeListener ( $eventName , array ( $subscriber , is_string ( $params ) ? $params : $params [ 0 ]));
}
}
}
/**
* Triggers the listeners of an event .
*
* This method can be overridden to add functionality that is executed
* for each listener .
*
2017-02-02 16:28:38 -08:00
* @ param callable [] $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
2015-08-17 17:00:26 -07:00
*/
protected function doDispatch ( $listeners , $eventName , Event $event )
{
foreach ( $listeners as $listener ) {
if ( $event -> isPropagationStopped ()) {
break ;
}
2017-02-02 16:28:38 -08:00
call_user_func ( $listener , $event , $eventName , $this );
2015-08-17 17:00:26 -07:00
}
}
/**
* Sorts the internal list of listeners for the given event by priority .
*
2017-02-02 16:28:38 -08:00
* @ param string $eventName The name of the event
2015-08-17 17:00:26 -07:00
*/
private function sortListeners ( $eventName )
{
2015-10-08 11:40:12 -07:00
krsort ( $this -> listeners [ $eventName ]);
$this -> sorted [ $eventName ] = call_user_func_array ( 'array_merge' , $this -> listeners [ $eventName ]);
2015-08-17 17:00:26 -07:00
}
}