* @copyright 2014 Fabian Grutschus. All rights reserved. * @license BSD * @link http://github.com/fabiang/xmpp */ namespace Fabiang\Xmpp\Event; use Fabiang\Xmpp\Exception\InvalidArgumentException; /** * Event manager. * * The EventManager holds and triggers events. * * @package Xmpp\Event */ class EventManager implements EventManagerInterface { const WILDCARD = '*'; /** * Attached events. * * @var array */ protected $events = [self::WILDCARD => []]; /** * Event object. * * @var EventInterface */ protected $eventObject; /** * Constructor sets default event object. * * @param EventInterface $eventObject Event object */ public function __construct(EventInterface $eventObject = null) { if (null === $eventObject) { $eventObject = new Event; } $this->eventObject = $eventObject; } /** * {@inheritDoc} */ public function attach($event, $callback) { if (!is_callable($callback, true)) { throw new InvalidArgumentException( 'Second argument of "' . __CLASS__ . '"::attach must be a valid callback' ); } if (!isset($this->events[$event])) { $this->events[$event] = []; } if (!in_array($callback, $this->events[$event], true)) { $this->events[$event][] = $callback; } } /** * {@inheritDoc} */ public function trigger($event, $caller, array $parameters) { if (empty($this->events[$event]) && empty($this->events[self::WILDCARD])) { return; } $events = []; if (!empty($this->events[$event])) { $events = $this->events[$event]; } $callbacks = array_merge($events, $this->events[self::WILDCARD]); $previous = []; $eventObject = clone $this->getEventObject(); $eventObject->setName($event); $eventObject->setTarget($caller); $eventObject->setParameters($parameters); do { $current = array_shift($callbacks); call_user_func($current, $eventObject); $previous[] = $current; $eventObject = clone $eventObject; $eventObject->setEventStack($previous); } while (count($callbacks) > 0); } /** * {@inheritDoc} */ public function getEventObject() { return $this->eventObject; } /** * {@inheritDoc} */ public function setEventObject(EventInterface $eventObject) { $this->eventObject = $eventObject; return $this; } /** * Return list of events. * * @return array */ public function getEventList() { return $this->events; } }