Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 liveuser 1
<?php
2
 
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <fabien@symfony.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
namespace Symfony\Component\EventDispatcher;
13
 
14
/**
15
 * The EventDispatcherInterface is the central point of Symfony's event listener system.
16
 *
17
 * Listeners are registered on the manager and events are dispatched through the
18
 * manager.
19
 *
20
 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
21
 * @author Jonathan Wage <jonwage@gmail.com>
22
 * @author Roman Borschel <roman@code-factory.org>
23
 * @author Bernhard Schussek <bschussek@gmail.com>
24
 * @author Fabien Potencier <fabien@symfony.com>
25
 * @author Jordi Boggiano <j.boggiano@seld.be>
26
 * @author Jordan Alliot <jordan.alliot@gmail.com>
27
 */
28
class EventDispatcher implements EventDispatcherInterface
29
{
30
    private $listeners = array();
31
    private $sorted = array();
32
 
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function dispatch($eventName, Event $event = null)
37
    {
38
        if (null === $event) {
39
            $event = new Event();
40
        }
41
 
42
        if ($listeners = $this->getListeners($eventName)) {
43
            $this->doDispatch($listeners, $eventName, $event);
44
        }
45
 
46
        return $event;
47
    }
48
 
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function getListeners($eventName = null)
53
    {
54
        if (null !== $eventName) {
55
            if (!isset($this->listeners[$eventName])) {
56
                return array();
57
            }
58
 
59
            if (!isset($this->sorted[$eventName])) {
60
                $this->sortListeners($eventName);
61
            }
62
 
63
            return $this->sorted[$eventName];
64
        }
65
 
66
        foreach ($this->listeners as $eventName => $eventListeners) {
67
            if (!isset($this->sorted[$eventName])) {
68
                $this->sortListeners($eventName);
69
            }
70
        }
71
 
72
        return array_filter($this->sorted);
73
    }
74
 
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function getListenerPriority($eventName, $listener)
79
    {
80
        if (!isset($this->listeners[$eventName])) {
81
            return;
82
        }
83
 
84
        foreach ($this->listeners[$eventName] as $priority => $listeners) {
85
            if (false !== ($key = array_search($listener, $listeners, true))) {
86
                return $priority;
87
            }
88
        }
89
    }
90
 
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function hasListeners($eventName = null)
95
    {
96
        return (bool) count($this->getListeners($eventName));
97
    }
98
 
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function addListener($eventName, $listener, $priority = 0)
103
    {
104
        $this->listeners[$eventName][$priority][] = $listener;
105
        unset($this->sorted[$eventName]);
106
    }
107
 
108
    /**
109
     * {@inheritdoc}
110
     */
111
    public function removeListener($eventName, $listener)
112
    {
113
        if (!isset($this->listeners[$eventName])) {
114
            return;
115
        }
116
 
117
        foreach ($this->listeners[$eventName] as $priority => $listeners) {
118
            if (false !== ($key = array_search($listener, $listeners, true))) {
119
                unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]);
120
            }
121
        }
122
    }
123
 
124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function addSubscriber(EventSubscriberInterface $subscriber)
128
    {
129
        foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
130
            if (is_string($params)) {
131
                $this->addListener($eventName, array($subscriber, $params));
132
            } elseif (is_string($params[0])) {
133
                $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
134
            } else {
135
                foreach ($params as $listener) {
136
                    $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
137
                }
138
            }
139
        }
140
    }
141
 
142
    /**
143
     * {@inheritdoc}
144
     */
145
    public function removeSubscriber(EventSubscriberInterface $subscriber)
146
    {
147
        foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
148
            if (is_array($params) && is_array($params[0])) {
149
                foreach ($params as $listener) {
150
                    $this->removeListener($eventName, array($subscriber, $listener[0]));
151
                }
152
            } else {
153
                $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0]));
154
            }
155
        }
156
    }
157
 
158
    /**
159
     * Triggers the listeners of an event.
160
     *
161
     * This method can be overridden to add functionality that is executed
162
     * for each listener.
163
     *
164
     * @param callable[] $listeners The event listeners
165
     * @param string     $eventName The name of the event to dispatch
166
     * @param Event      $event     The event object to pass to the event handlers/listeners
167
     */
168
    protected function doDispatch($listeners, $eventName, Event $event)
169
    {
170
        foreach ($listeners as $listener) {
171
            if ($event->isPropagationStopped()) {
172
                break;
173
            }
174
            call_user_func($listener, $event, $eventName, $this);
175
        }
176
    }
177
 
178
    /**
179
     * Sorts the internal list of listeners for the given event by priority.
180
     *
181
     * @param string $eventName The name of the event
182
     */
183
    private function sortListeners($eventName)
184
    {
185
        krsort($this->listeners[$eventName]);
186
        $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
187
    }
188
}