1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Symfony\Component\EventDispatcher;
13:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
30: class EventDispatcher implements EventDispatcherInterface
31: {
32: private $listeners = array();
33: private $sorted = array();
34:
35: 36: 37: 38: 39:
40: public function dispatch($eventName, Event $event = null)
41: {
42: if (null === $event) {
43: $event = new Event();
44: }
45:
46: $event->setDispatcher($this);
47: $event->setName($eventName);
48:
49: if (!isset($this->listeners[$eventName])) {
50: return $event;
51: }
52:
53: $this->doDispatch($this->getListeners($eventName), $eventName, $event);
54:
55: return $event;
56: }
57:
58: 59: 60:
61: public function getListeners($eventName = null)
62: {
63: if (null !== $eventName) {
64: if (!isset($this->sorted[$eventName])) {
65: $this->sortListeners($eventName);
66: }
67:
68: return $this->sorted[$eventName];
69: }
70:
71: foreach (array_keys($this->listeners) as $eventName) {
72: if (!isset($this->sorted[$eventName])) {
73: $this->sortListeners($eventName);
74: }
75: }
76:
77: return $this->sorted;
78: }
79:
80: 81: 82:
83: public function hasListeners($eventName = null)
84: {
85: return (Boolean) count($this->getListeners($eventName));
86: }
87:
88: 89: 90: 91: 92:
93: public function addListener($eventName, $listener, $priority = 0)
94: {
95: $this->listeners[$eventName][$priority][] = $listener;
96: unset($this->sorted[$eventName]);
97: }
98:
99: 100: 101:
102: public function removeListener($eventName, $listener)
103: {
104: if (!isset($this->listeners[$eventName])) {
105: return;
106: }
107:
108: foreach ($this->listeners[$eventName] as $priority => $listeners) {
109: if (false !== ($key = array_search($listener, $listeners, true))) {
110: unset($this->listeners[$eventName][$priority][$key], $this->sorted[$eventName]);
111: }
112: }
113: }
114:
115: 116: 117: 118: 119:
120: public function addSubscriber(EventSubscriberInterface $subscriber)
121: {
122: foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
123: if (is_string($params)) {
124: $this->addListener($eventName, array($subscriber, $params));
125: } elseif (is_string($params[0])) {
126: $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
127: } else {
128: foreach ($params as $listener) {
129: $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
130: }
131: }
132: }
133: }
134:
135: 136: 137:
138: public function removeSubscriber(EventSubscriberInterface $subscriber)
139: {
140: foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
141: if (is_array($params) && is_array($params[0])) {
142: foreach ($params as $listener) {
143: $this->removeListener($eventName, array($subscriber, $listener[0]));
144: }
145: } else {
146: $this->removeListener($eventName, array($subscriber, is_string($params) ? $params : $params[0]));
147: }
148: }
149: }
150:
151: 152: 153: 154: 155: 156: 157: 158: 159: 160:
161: protected function doDispatch($listeners, $eventName, Event $event)
162: {
163: foreach ($listeners as $listener) {
164: call_user_func($listener, $event);
165: if ($event->isPropagationStopped()) {
166: break;
167: }
168: }
169: }
170:
171: 172: 173: 174: 175:
176: private function sortListeners($eventName)
177: {
178: $this->sorted[$eventName] = array();
179:
180: if (isset($this->listeners[$eventName])) {
181: krsort($this->listeners[$eventName]);
182: $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
183: }
184: }
185: }
186: