PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.20
VikAppointments Services Booking Calendar v1.2.20
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / event / dispatcher.php
vikappointments / site / helpers / libraries / event Last commit date
dispatcher.php 1 month ago index.html 1 month ago
dispatcher.php
418 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 /**
15 * This class is a bridge to implement and extend the methods
16 * provided by the Joomla! framework to trigger and dispatch
17 * the plugin events.
18 *
19 * @since 1.6
20 * @since 1.7 Renamed from UIEventDispatcher
21 */
22 class VAPEventDispatcher
23 {
24 /**
25 * A list of instances.
26 *
27 * @var array
28 */
29 protected static $instances = array();
30
31 /**
32 * The class used to dispatch events.
33 *
34 * @var mixed
35 */
36 protected $dispatcher;
37
38 /**
39 * An array of options to push always as last
40 * element within the event arguments.
41 * This array may contain information about the
42 * caller, such as alias, version and client.
43 *
44 * @var array
45 */
46 protected $options;
47
48 /**
49 * Returns a new instance of this object, only creating it
50 * if it doesn't already exist.
51 *
52 * @param array $option An array of options.
53 * @param mixed $dispatcher The real dispatcher instance.
54 *
55 * @return self A new instance.
56 */
57 public static function getInstance(array $options = array(), $dispatcher = null)
58 {
59 $sign = is_object($dispatcher) ? get_class($dispatcher) : null;
60
61 if (!isset(static::$instances[$sign]))
62 {
63 static::$instances[$sign] = new static($options, $dispatcher);
64 }
65 else
66 {
67 // the instance already exists, update all the options
68 foreach ($options as $k => $v)
69 {
70 static::$instances[$sign]->setOption($k, $v);
71 }
72 }
73
74 return static::$instances[$sign];
75 }
76
77 /**
78 * Class constructor.
79 *
80 * @param array $option An array of options.
81 * @param mixed $dispatcher The real dispatcher instance.
82 *
83 * @uses import()
84 */
85 public function __construct(array $options = array(), $dispatcher = null)
86 {
87 if (is_null($dispatcher))
88 {
89 /**
90 * In case of Joomla 4, use the main application
91 * as event dispatcher.
92 *
93 * @since 1.7
94 */
95 if (VersionListener::isJoomla4x())
96 {
97 $dispatcher = array(JFactory::getApplication(), 'triggerEvent');
98 }
99 else
100 {
101 $dispatcher = JEventDispatcher::getInstance();
102 }
103 }
104
105 $this->dispatcher = $dispatcher;
106 $this->options = $options;
107
108 // always import plugins that belong to "vikappointments" and "e4j" folders
109 $this->import(array('vikappointments', 'e4j'));
110 }
111
112 /**
113 * Updates an option value.
114 *
115 * @param string $key The option name.
116 * @param mixed $value The option value.
117 *
118 * @return self This object to support chaining.
119 */
120 public function setOption($key, $value)
121 {
122 $this->option[$key] = $value;
123
124 return $this;
125 }
126
127 /**
128 * Imports all the plugins that belong to the specified group.
129 *
130 * @param mixed $group The plugins folder to import or a list of folders.
131 *
132 * @return self This object to support chaining.
133 */
134 public function import($group)
135 {
136 // cast the group to an array as it may be possible
137 // to import multiple folders at once
138 foreach ((array) $group as $folder)
139 {
140 JPluginHelper::importPlugin($folder);
141 }
142
143 return $this;
144 }
145
146 /**
147 * Triggers an event by dispatching arguments to all observers that handle
148 * the specified event and returning all their values.
149 *
150 * @param mixed $event The event to trigger or an array containing the
151 * event name [0] and the plugins folder to import [1].
152 * @param array $args An array of arguments.
153 *
154 * @return array An array of results from each function call.
155 *
156 * @uses import()
157 */
158 public function trigger($event, array $args = array())
159 {
160 if (is_array($event))
161 {
162 $arr = $event;
163
164 // an array was passed, obtain the event name and the
165 // folder name to import all the related plugins
166 $event = array_shift($arr);
167 $group = array_shift($arr);
168
169 if ($group)
170 {
171 // groups was specified, import the plugins
172 $this->import($group);
173 }
174 }
175
176 if ($this->options)
177 {
178 // push the options as last argument
179 $args[] = $this->options;
180 }
181
182 if (is_array($this->dispatcher))
183 {
184 // retrieve dispatcher instance and the related trigger method
185 list($dispatcher, $trigger) = $this->dispatcher;
186 }
187 else
188 {
189 // use the default trigger method instead
190 $dispatcher = $this->dispatcher;
191 $trigger = 'trigger';
192 }
193
194 // trigger event with the specified dispatcher
195 $result = $dispatcher->{$trigger}($event, $args);
196
197 if (!preg_match("/web_?hook/i", $event))
198 {
199 // in case the event doesn't contain "webhook" word, register related web hook
200 VAPLoader::import('libraries.webhook.queue');
201 VAPWebHookQueue::getInstance()->register($event, $args);
202 }
203
204 return $result;
205 }
206
207 /**
208 * Triggers an event by dispatching arguments to all observers that handle
209 * the specified event and returning only the first value.
210 *
211 * @param mixed $event The event to trigger or an array containing the
212 * event name and the plugins folder to import.
213 * @param array $args An array of arguments.
214 *
215 * @return mixed The first value.
216 *
217 * @uses trigger()
218 */
219 public function triggerOnce($event, array $args = array())
220 {
221 $res = $this->trigger($event, $args);
222
223 // get the first positive (bool) value
224 foreach ($res as $value)
225 {
226 if ($value)
227 {
228 return $value;
229 }
230 }
231
232 // No positive value, the array is probably empty or
233 // contains empty values (null, false, empty string or 0).
234 // Get the first one in case the array has length, otherwise
235 // null will be returned.
236 return array_shift($res);
237 }
238
239 /**
240 * Triggers an event by dispatching arguments to all observers that handle
241 * the specified event and make sure at least a plugin returned a positive value (bool).
242 *
243 * @param mixed $event The event to trigger or an array containing the
244 * event name and the plugins folder to import.
245 * @param array $args An array of arguments.
246 *
247 * @return boolean True on success, otherwise false.
248 *
249 * @uses trigger()
250 */
251 public function is($event, array $args = array())
252 {
253 $res = $this->trigger($event, $args);
254
255 return (bool) array_filter($res);
256 }
257
258 /**
259 * Triggers an event by dispatching arguments to all observers that handle
260 * the specified event and make sure at least a plugin returned a negative value (bool).
261 *
262 * @param mixed $event The event to trigger or an array containing the
263 * event name and the plugins folder to import.
264 * @param array $args An array of arguments.
265 *
266 * @return boolean True on success, otherwise false.
267 *
268 * @uses trigger()
269 */
270 public function not($event, array $args = array())
271 {
272 $res = $this->trigger($event, $args);
273
274 foreach ($res as $r)
275 {
276 if (!$r)
277 {
278 // negative response
279 return true;
280 }
281 }
282
283 // no response or only successful values
284 return false;
285 }
286
287 /**
288 * Triggers an event by dispatching arguments to all observers that handle
289 * the specified event and make sure at least a plugin returned TRUE.
290 *
291 * @param mixed $event The event to trigger or an array containing the
292 * event name and the plugins folder to import.
293 * @param array $args An array of arguments.
294 *
295 * @return boolean True if verified, false otherwise.
296 *
297 * @since 1.7
298 *
299 * @uses trigger()
300 */
301 public function true($event, array $args = array())
302 {
303 $res = $this->trigger($event, $args);
304
305 return in_array(true, $res, true);
306 }
307
308 /**
309 * Triggers an event by dispatching arguments to all observers that handle
310 * the specified event and make sure at least a plugin returned FALSE.
311 *
312 * @param mixed $event The event to trigger or an array containing the
313 * event name and the plugins folder to import.
314 * @param array $args An array of arguments.
315 *
316 * @return boolean True if verified, false otherwise.
317 *
318 * @since 1.7
319 *
320 * @uses trigger()
321 */
322 public function false($event, array $args = array())
323 {
324 $res = $this->trigger($event, $args);
325
326 return in_array(false, $res, true);
327 }
328
329 /**
330 * Triggers an event by dispatching arguments to all observers that handle
331 * the specified event and make sure at least a plugin returned TRUE.
332 * Alternatively it looks for an element equals to FALSE.
333 *
334 * @param mixed $event The event to trigger or an array containing the
335 * event name and the plugins folder to import.
336 * @param array $args An array of arguments.
337 *
338 * @return mixed A boolean in case of true/false, null otherwise.
339 *
340 * @since 1.7
341 *
342 * @uses trigger()
343 */
344 public function trueOrFalse($event, array $args = array())
345 {
346 $res = $this->trigger($event, $args);
347
348 if (in_array(true, $res, true))
349 {
350 return true;
351 }
352
353 if (in_array(false, $res, true))
354 {
355 return false;
356 }
357
358 return null;
359 }
360
361 /**
362 * Triggers an event by dispatching arguments to all observers that handle
363 * the specified event and make sure at least a plugin returned FALSE.
364 * Alternatively it looks for an element equals to TRUE.
365 *
366 * @param mixed $event The event to trigger or an array containing the
367 * event name and the plugins folder to import.
368 * @param array $args An array of arguments.
369 *
370 * @return mixed A boolean in case of false/true, null otherwise.
371 *
372 * @since 1.7
373 *
374 * @uses trigger()
375 */
376 public function falseOrTrue($event, array $args = array())
377 {
378 $res = $this->trigger($event, $args);
379
380 if (in_array(false, $res, true))
381 {
382 return false;
383 }
384
385 if (in_array(true, $res, true))
386 {
387 return true;
388 }
389
390 return null;
391 }
392
393 /**
394 * Triggers an event by dispatching arguments to all observers that handle
395 * the specified event and filters the returned values to take only numbers.
396 *
397 * @param mixed $event The event to trigger or an array containing the
398 * event name and the plugins folder to import.
399 * @param array $args An array of arguments.
400 *
401 * @return array The returned values.
402 *
403 * @since 1.7
404 *
405 * @uses trigger()
406 */
407 public function numbers($event, array $args = array())
408 {
409 $res = $this->trigger($event, $args);
410
411 // filter the returned values and take only integers and floats
412 return array_filter($res, function($return)
413 {
414 return is_int($return) || is_float($return);
415 });
416 }
417 }
418