PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
← All changes | admin/helpers/src/notification/scheduler.php +436 -0 1.6.3 → 1.8.16 View file →
@@ -1,0 +1,436 @@
1 +<?php
2 +/**
3 + * @package VikBooking
4 + * @subpackage core
5 + * @author Alessio Gaggii - E4J s.r.l.
6 + * @copyright Copyright (C) 2022 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 + * Browser notifications scheduler handler.
16 + *
17 + * @since 1.15.0 (J) - 1.5.0 (WP)
18 + */
19 +final class VBONotificationScheduler
20 +{
21 + /**
22 + * @var mixed
23 + */
24 + private $data = null;
25 +
26 + /**
27 + * @var JDocument
28 + */
29 + private $doc = null;
30 +
31 + /**
32 + * Proxy to immediately access the object.
33 + *
34 + * @param mixed $data optional data to set.
35 + * @param JDocument $doc optional document object.
36 + *
37 + * @return self
38 + */
39 + public static function getInstance($data = null, $doc = null)
40 + {
41 + return new static($data, $doc);
42 + }
43 +
44 + /**
45 + * Class constructor.
46 + *
47 + * @param mixed $data
48 + */
49 + public function __construct($data = null, $doc = null)
50 + {
51 + // bind data
52 + $this->data = $data;
53 +
54 + // set the document object
55 + if (!$doc) {
56 + $doc = JFactory::getDocument();
57 + }
58 + $this->doc = $doc;
59 + }
60 +
61 + /**
62 + * Given a reminder record object, composes the notification
63 + * data object to schedule a browser notification.
64 + *
65 + * @param object $reminder the reminder record object.
66 + * @param int $max_future_hours optional value to check if the reminder
67 + * is too far ahead in the future.
68 + *
69 + * @return null|object
70 + */
71 + public function getReminderDataObject($reminder, $max_future_hours = 0)
72 + {
73 + if (!is_object($reminder) || empty($reminder->id) || empty($reminder->duedate)) {
74 + return null;
75 + }
76 +
77 + if ($max_future_hours > 0) {
78 + // this reminder requires a validation of the future time
79 + $now_info = getdate();
80 + $next_hours = ($now_info['hours'] + $max_future_hours);
81 + $max_future_ts = mktime($next_hours, $now_info['minutes'], 0, $now_info['mon'], $now_info['mday'], $now_info['year']);
82 + $scheduled_ts = strtotime($reminder->duedate);
83 + if ($scheduled_ts > $max_future_ts) {
84 + // no need to schedule a notification for this reminder as it's too far ahead
85 + return null;
86 + }
87 + }
88 +
89 + // get a new notification data object
90 + $notification = VBONotificationDataReminder::getInstance();
91 +
92 + // immediately parse the reminder record to check its validity and importance
93 + $notification->parseReminderImportance($reminder);
94 +
95 + // set data
96 + $notification->setReminderId($reminder->id);
97 + $notification->setDateTime($reminder->duedate);
98 + if (!$reminder->usetime) {
99 + $notification->setNoTime(true);
100 + }
101 +
102 + return $notification->toDataObject();
103 + }
104 +
105 + /**
106 + * Builds a notification display data object for a recent history
107 + * event involving a reservation. This kind of notification will
108 + * be actually dispatched immediately with no scheduling, and so
109 + * so it won't provide a build-URL, it will provide display data.
110 + *
111 + * @param object $h_event history record object to parse.
112 + *
113 + * @return null|object
114 + */
115 + public function getHistoryDataObject($h_event)
116 + {
117 + if (!is_object($h_event) || empty($h_event->idorder)) {
118 + return null;
119 + }
120 +
121 + // get a new notification data object
122 + $notification = VBONotificationDataHistory::getInstance();
123 +
124 + // inject all record properties as "reserved" properties
125 + foreach ($h_event as $prop => $val) {
126 + // properties starting with an underscore are "reserved"
127 + $notification->set("_{$prop}", $val);
128 + }
129 +
130 + // the notification will be dispatched immediately
131 + $notification->setDateTime('now');
132 +
133 + // let the notification build the display data
134 + $notification->buildDisplayData();
135 +
136 + // return the notification data-object
137 + return $notification->toDataObject();
138 + }
139 +
140 + /**
141 + * Given a list of recent worthy-of-notification history events,
142 + * builds a list of notification data objects of type "history".
143 + * Such notifications will be actually dispatched immediately,
144 + * with no needs to schedule a notification timer. Moreover,
145 + * these notifications will contain immediately the necessary
146 + * display data without needing to build them through a callback.
147 + *
148 + * @param array $events list of recent history record objects.
149 + *
150 + * @return array list of browser notification display data objects.
151 + */
152 + public function buildHistoryDataObjects($events = [])
153 + {
154 + if (!is_array($events) || !$events) {
155 + return [];
156 + }
157 +
158 + // container of notification display data objects
159 + $data_objects = [];
160 +
161 + foreach ($events as $history) {
162 + $data_object = $this->getHistoryDataObject($history);
163 + if ($data_object) {
164 + $data_objects[] = $data_object;
165 + }
166 + }
167 +
168 + return $data_objects;
169 + }
170 +
171 + /**
172 + * Builds a notification display data object for a recent guest
173 + * review involving a reservation. This kind of notification will
174 + * be actually dispatched immediately with no scheduling, and so
175 + * so it won't provide a build-URL, it will provide display data.
176 + *
177 + * @param object $review guest activity record object to parse.
178 + *
179 + * @return null|object
180 + */
181 + public function getReviewDataObject($review)
182 + {
183 + if (!is_object($review) || empty($review->id_review) || empty($review->idorder)) {
184 + return null;
185 + }
186 +
187 + // get a new notification data object
188 + $notification = VBONotificationDataReview::getInstance();
189 +
190 + // inject all record properties as "reserved" properties
191 + foreach ($review as $prop => $val) {
192 + // properties starting with an underscore are "reserved"
193 + $notification->set("_{$prop}", $val);
194 + }
195 +
196 + // the notification will be dispatched immediately
197 + $notification->setDateTime('now');
198 +
199 + // let the notification build the display data
200 + $notification->buildDisplayData();
201 +
202 + // return the notification data-object
203 + return $notification->toDataObject();
204 + }
205 +
206 + /**
207 + * Given a list of recent guest activity records, builds a list
208 + * of notification data objects of type "review".
209 + * Such notifications will be actually dispatched immediately,
210 + * with no needs to schedule a notification timer. Moreover,
211 + * these notifications will contain immediately the necessary
212 + * display data without needing to build them through a callback.
213 + *
214 + * @param array $reviews list of recent guest activity record objects.
215 + *
216 + * @return array list of browser notification display data objects.
217 + */
218 + public function buildReviewDataObjects($reviews = [])
219 + {
220 + if (!is_array($reviews) || !$reviews) {
221 + return [];
222 + }
223 +
224 + // container of notification display data objects
225 + $data_objects = [];
226 +
227 + foreach ($reviews as $review) {
228 + $data_object = $this->getReviewDataObject($review);
229 + if ($data_object) {
230 + $data_objects[] = $data_object;
231 + }
232 + }
233 +
234 + return $data_objects;
235 + }
236 +
237 + /**
238 + * Builds a notification display data object for a recent guest
239 + * message involving a reservation. This kind of notification will
240 + * be actually dispatched immediately with no scheduling, and so
241 + * so it won't provide a build-URL, it will provide display data.
242 + *
243 + * @param object $message guest activity record object to parse.
244 + *
245 + * @return null|object
246 + */
247 + public function getGuestMessageDataObject($message)
248 + {
249 + if (!is_object($message) || empty($message->idorder)) {
250 + return null;
251 + }
252 +
253 + // get a new notification data object
254 + $notification = VBONotificationDataMessage::getInstance();
255 +
256 + // inject all record properties as "reserved" properties
257 + foreach ($message as $prop => $val) {
258 + // properties starting with an underscore are "reserved"
259 + $notification->set("_{$prop}", $val);
260 + }
261 +
262 + // the notification will be dispatched immediately
263 + $notification->setDateTime('now');
264 +
265 + // let the notification build the display data
266 + $notification->buildDisplayData();
267 +
268 + // return the notification data-object
269 + return $notification->toDataObject();
270 + }
271 +
272 + /**
273 + * Given a list of recent guest activity records, builds a list
274 + * of notification data objects of type (guest) "message".
275 + * Such notifications will be actually dispatched immediately,
276 + * with no needs to schedule a notification timer. Moreover,
277 + * these notifications will contain immediately the necessary
278 + * display data without needing to build them through a callback.
279 + *
280 + * @param array $messages list of recent guest activity record objects.
281 + *
282 + * @return array list of browser notification display data objects.
283 + */
284 + public function buildGuestMessageDataObjects($messages = [])
285 + {
286 + if (!is_array($messages) || !$messages) {
287 + return [];
288 + }
289 +
290 + // container of notification display data objects
291 + $data_objects = [];
292 +
293 + foreach ($messages as $message) {
294 + $data_object = $this->getGuestMessageDataObject($message);
295 + if ($data_object) {
296 + $data_objects[] = $data_object;
297 + }
298 + }
299 +
300 + return $data_objects;
301 + }
302 +
303 + /**
304 + * Builds a notification display data object for a recent operator
305 + * chat message for an administrator. This kind of notification will
306 + * be actually dispatched immediately with no scheduling, and so
307 + * so it won't provide a build-URL, it will provide display data.
308 + *
309 + * @param object $message Operator chat message record object to parse.
310 + *
311 + * @return ?object
312 + *
313 + * @since 1.18.0 (J) - 1.8.0 (WP)
314 + */
315 + public function getOperatorsChatDataObject($message)
316 + {
317 + if (!$message instanceof VBOChatMessage) {
318 + return null;
319 + }
320 +
321 + // get a new notification data object
322 + $notification = VBONotificationDataOperatormessage::getInstance();
323 +
324 + // inject all record properties as "reserved" properties
325 + foreach ($message->jsonSerialize() as $prop => $val) {
326 + // properties starting with an underscore are "reserved"
327 + $notification->set("_{$prop}", $val);
328 + }
329 +
330 + // the notification will be dispatched immediately
331 + $notification->setDateTime('now');
332 +
333 + // let the notification build the display data
334 + $notification->buildDisplayData();
335 +
336 + // return the notification data-object
337 + return $notification->toDataObject();
338 + }
339 +
340 + /**
341 + * Given a list of recent operators chat messages for the administrators,
342 + * builds a list of notification data objects of type (operator) "message".
343 + * Such notifications will be immediately dispatched, and they will contain
344 + * the necessary data for display without being built through a callback.
345 + *
346 + * @param array $messages List of recent operators chat message objects for the admin.
347 + *
348 + * @return array List of browser notification display data objects.
349 + *
350 + * @since 1.18.0 (J) - 1.8.0 (WP)
351 + */
352 + public function buildOperatorsChatDataObjects(array $messages)
353 + {
354 + // container of notification display data objects
355 + $data_objects = [];
356 +
357 + foreach ($messages as $message) {
358 + if ($data_object = $this->getOperatorsChatDataObject($message)) {
359 + $data_objects[] = $data_object;
360 + }
361 + }
362 +
363 + return $data_objects;
364 + }
365 +
366 + /**
367 + * Enqueues a list of notification objects for the overdue reminders.
368 + * This should be called upon a regular page loading, not during AJAX
369 + * requests, as it attachs a script declaration to the document.
370 + *
371 + * @param array $reminders list of reminder record objects.
372 + *
373 + * @return void
374 + */
375 + public function enqueueReminders(array $reminders)
376 + {
377 + // build the queue of reminders to be scheduled
378 + $queue = [];
379 +
380 + foreach ($reminders as $reminder) {
381 + if (empty($reminder->duedate)) {
382 + continue;
383 + }
384 +
385 + // compose reminder data object
386 + $notification = $this->getReminderDataObject($reminder);
387 + if ($notification) {
388 + // push reminder to queue
389 + $queue[] = $notification;
390 + }
391 + }
392 +
393 + if (!$queue) {
394 + return;
395 + }
396 +
397 + $js_queue = json_encode($queue);
398 +
399 + $this->doc->addScriptDeclaration(
400 +<<<JS
401 +jQuery(function() {
402 + setTimeout(() => {
403 + VBOCore.enqueueNotifications($js_queue);
404 + }, 300);
405 +});
406 +JS
407 + );
408 + }
409 +
410 + /**
411 + * Registers a list of widgets watching data.
412 + *
413 + * @param array $watch_data associative list of widgets
414 + * and preloaded watch data.
415 + *
416 + * @return void
417 + */
418 + public function registerWatchData($watch_data = [])
419 + {
420 + if (!is_array($watch_data) || !$watch_data) {
421 + return;
422 + }
423 +
424 + $js_watch_data = json_encode($watch_data);
425 +
426 + $this->doc->addScriptDeclaration(
427 +<<<JS
428 +jQuery(function() {
429 + setTimeout(() => {
430 + VBOCore.registerWatchData($js_watch_data);
431 + }, 300);
432 +});
433 +JS
434 + );
435 + }
436 +}