PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.5
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.5
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / vendor / wpfluent / framework / src / WPFluent / Foundation / Dispatcher.php

Dispatcher.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.5, at vendor/wpfluent/framework/src/WPFluent/Foundation/Dispatcher.php

355 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\Framework\Foundation;
4
5 use FluentForm\Framework\Support\Str;
6 use FluentForm\Framework\Foundation\Container;
7
8 class Dispatcher {
9
10 /**
11 * The IoC container instance.
12 *
13 * @var \Illuminate\Container\Container
14 */
15 protected $container;
16
17 /**
18 * The registered event listeners.
19 *
20 * @var array
21 */
22 protected $listeners = array();
23
24 /**
25 * The wildcard listeners.
26 *
27 * @var array
28 */
29 protected $wildcards = array();
30
31 /**
32 * The sorted event listeners.
33 *
34 * @var array
35 */
36 protected $sorted = array();
37
38 /**
39 * The event firing stack.
40 *
41 * @var array
42 */
43 protected $firing = array();
44
45 /**
46 * Create a new event dispatcher instance.
47 *
48 * @param \Illuminate\Container\Container $container
49 * @return void
50 */
51 public function __construct(Container $container = null)
52 {
53 $this->container = $container ?: new Container;
54 }
55
56 /**
57 * Register an event listener with the dispatcher.
58 *
59 * @param string|array $events
60 * @param mixed $listener
61 * @param int $priority
62 * @return void
63 */
64 public function listen($events, $listener, $priority = 0)
65 {
66 foreach ((array) $events as $event)
67 {
68 if (Str::contains($event, '*'))
69 {
70 $this->setupWildcardListen($event, $listener);
71 }
72 else
73 {
74 $this->listeners[$event][$priority][] = $this->makeListener($listener);
75
76 unset($this->sorted[$event]);
77 }
78 }
79 }
80
81 /**
82 * Setup a wildcard listener callback.
83 *
84 * @param string $event
85 * @param mixed $listener
86 * @return void
87 */
88 protected function setupWildcardListen($event, $listener)
89 {
90 $this->wildcards[$event][] = $this->makeListener($listener);
91 }
92
93 /**
94 * Determine if a given event has listeners.
95 *
96 * @param string $eventName
97 * @return bool
98 */
99 public function hasListeners($eventName)
100 {
101 return isset($this->listeners[$eventName]);
102 }
103
104 /**
105 * Register a queued event and payload.
106 *
107 * @param string $event
108 * @param array $payload
109 * @return void
110 */
111 public function queue($event, $payload = array())
112 {
113 $this->listen($event.'_queue', function() use ($event, $payload)
114 {
115 $this->fire($event, $payload);
116 });
117 }
118
119 /**
120 * Register an event subscriber with the dispatcher.
121 *
122 * @param string $subscriber
123 * @return void
124 */
125 public function subscribe($subscriber)
126 {
127 $subscriber = $this->resolveSubscriber($subscriber);
128
129 $subscriber->subscribe($this);
130 }
131
132 /**
133 * Resolve the subscriber instance.
134 *
135 * @param mixed $subscriber
136 * @return mixed
137 */
138 protected function resolveSubscriber($subscriber)
139 {
140 if (is_string($subscriber))
141 {
142 return $this->container->make($subscriber);
143 }
144
145 return $subscriber;
146 }
147
148 /**
149 * Fire an event until the first non-null response is returned.
150 *
151 * @param string $event
152 * @param array $payload
153 * @return mixed
154 */
155 public function until($event, $payload = array())
156 {
157 return $this->fire($event, $payload, true);
158 }
159
160 /**
161 * Flush a set of queued events.
162 *
163 * @param string $event
164 * @return void
165 */
166 public function flush($event)
167 {
168 $this->fire($event.'_queue');
169 }
170
171 /**
172 * Get the event that is currently firing.
173 *
174 * @return string
175 */
176 public function firing()
177 {
178 return end($this->firing);
179 }
180
181 /**
182 * Fire an event and call the listeners.
183 *
184 * @param string $event
185 * @param mixed $payload
186 * @param bool $halt
187 * @return array|null
188 */
189 public function fire($event, $payload = array(), $halt = false)
190 {
191 $responses = array();
192
193 // If an array is not given to us as the payload, we will turn it into one so
194 // we can easily use call_user_func_array on the listeners, passing in the
195 // payload to each of them so that they receive each of these arguments.
196 if ( ! is_array($payload)) $payload = array($payload);
197
198 $this->firing[] = $event;
199
200 foreach ($this->getListeners($event) as $listener)
201 {
202 $response = call_user_func_array($listener, $payload);
203
204 // If a response is returned from the listener and event halting is enabled
205 // we will just return this response, and not call the rest of the event
206 // listeners. Otherwise we will add the response on the response list.
207 if ( ! is_null($response) && $halt)
208 {
209 array_pop($this->firing);
210
211 return $response;
212 }
213
214 // If a boolean false is returned from a listener, we will stop propagating
215 // the event to any further listeners down in the chain, else we keep on
216 // looping through the listeners and firing every one in our sequence.
217 if ($response === false) break;
218
219 $responses[] = $response;
220 }
221
222 array_pop($this->firing);
223
224 return $halt ? null : $responses;
225 }
226
227 /**
228 * Get all of the listeners for a given event name.
229 *
230 * @param string $eventName
231 * @return array
232 */
233 public function getListeners($eventName)
234 {
235 $wildcards = $this->getWildcardListeners($eventName);
236
237 if ( ! isset($this->sorted[$eventName]))
238 {
239 $this->sortListeners($eventName);
240 }
241
242 return array_merge($this->sorted[$eventName], $wildcards);
243 }
244
245 /**
246 * Get the wildcard listeners for the event.
247 *
248 * @param string $eventName
249 * @return array
250 */
251 protected function getWildcardListeners($eventName)
252 {
253 $wildcards = array();
254
255 foreach ($this->wildcards as $key => $listeners)
256 {
257 if (Str::is($key, $eventName)) $wildcards = array_merge($wildcards, $listeners);
258 }
259
260 return $wildcards;
261 }
262
263 /**
264 * Sort the listeners for a given event by priority.
265 *
266 * @param string $eventName
267 * @return array
268 */
269 protected function sortListeners($eventName)
270 {
271 $this->sorted[$eventName] = array();
272
273 // If listeners exist for the given event, we will sort them by the priority
274 // so that we can call them in the correct order. We will cache off these
275 // sorted event listeners so we do not have to re-sort on every events.
276 if (isset($this->listeners[$eventName]))
277 {
278 krsort($this->listeners[$eventName]);
279
280 $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]);
281 }
282 }
283
284 /**
285 * Register an event listener with the dispatcher.
286 *
287 * @param mixed $listener
288 * @return mixed
289 */
290 public function makeListener($listener)
291 {
292 if (is_string($listener))
293 {
294 $listener = $this->createClassListener($listener);
295 }
296
297 return $listener;
298 }
299
300 /**
301 * Create a class based listener using the IoC container.
302 *
303 * @param mixed $listener
304 * @return \Closure
305 */
306 public function createClassListener($listener)
307 {
308 $container = $this->container;
309
310 return function() use ($listener, $container)
311 {
312 // If the listener has an @ sign, we will assume it is being used to delimit
313 // the class name from the handle method name. This allows for handlers
314 // to run multiple handler methods in a single class for convenience.
315 $segments = explode('@', $listener);
316
317 $method = count($segments) == 2 ? $segments[1] : 'handle';
318
319 $callable = array($container->make($segments[0]), $method);
320
321 // We will make a callable of the listener instance and a method that should
322 // be called on that instance, then we will pass in the arguments that we
323 // received in this method into this listener class instance's methods.
324 $data = func_get_args();
325
326 return call_user_func_array($callable, $data);
327 };
328 }
329
330 /**
331 * Remove a set of listeners from the dispatcher.
332 *
333 * @param string $event
334 * @return void
335 */
336 public function forget($event)
337 {
338 unset($this->listeners[$event], $this->sorted[$event]);
339 }
340
341 /**
342 * Forget all of the queued listeners.
343 *
344 * @return void
345 */
346 public function forgetQueued()
347 {
348 foreach ($this->listeners as $key => $value)
349 {
350 if (Str::endsWith($key, '_queue')) $this->forget($key);
351 }
352 }
353
354 }
355