PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.4
VikBooking Hotel Booking Engine & PMS v1.6.4
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
vikbooking / admin / helpers / widgets / latest_from_guests.php

latest_from_guests.php in VikBooking Hotel Booking Engine & PMS 1.6.4, at admin/helpers/widgets/latest_from_guests.php

727 lines 23.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 * @link https://vikwp.com
9 */
10
11 defined('ABSPATH') or die('No script kiddies please!');
12
13 /**
14 * Class handler for admin widget "latest from guests".
15 *
16 * @since 1.14.0 (J) - 1.4.0 (WP)
17 */
18 class VikBookingAdminWidgetLatestFromGuests extends VikBookingAdminWidget
19 {
20 /**
21 * The instance counter of this widget.
22 *
23 * @var int
24 */
25 protected static $instance_counter = -1;
26
27 /**
28 * Number of activities per page. Should be an even number.
29 *
30 * @var int
31 */
32 protected $activities_per_page = 6;
33
34 /**
35 * Number of activities per type. Should be half of numer per page.
36 *
37 * @var int
38 */
39 protected $activities_per_type = 3;
40
41 /**
42 * Today Y-m-d string
43 *
44 * @var string
45 */
46 protected $today_ymd = null;
47
48 /**
49 * The path to the VCM lib to see if it's available.
50 *
51 * @var string
52 */
53 protected $vcm_lib_path = '';
54
55 /**
56 * Tells whether VCM is installed and updated.
57 *
58 * @var bool
59 */
60 protected $vcm_exists = true;
61
62 /**
63 * Class constructor will define the widget name and identifier.
64 */
65 public function __construct()
66 {
67 // call parent constructor
68 parent::__construct();
69
70 $this->widgetName = JText::translate('VBO_W_LATESTFROMGUESTS_TITLE');
71 $this->widgetDescr = JText::translate('VBO_W_LATESTFROMGUESTS_DESCR');
72 $this->widgetId = basename(__FILE__, '.php');
73
74 /**
75 * Define widget and icon and style name.
76 *
77 * @since 1.15.0 (J) - 1.5.0 (WP)
78 */
79 $this->widgetIcon = '<i class="' . VikBookingIcons::i('comments') . '"></i>';
80 $this->widgetStyleName = 'green';
81
82 // activities per type is half the total number of activities
83 $this->activities_per_type = ceil($this->activities_per_page / 2);
84
85 // today Y-m-d date
86 $this->today_ymd = date('Y-m-d');
87
88 // the path to the VCM library
89 $this->vcm_lib_path = VCM_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'lib.vikchannelmanager.php';
90
91 // whether VCM is available
92 $this->vcm_exists = true;
93 if (is_file($this->vcm_lib_path)) {
94 // require the dependencies
95 if (!class_exists('VikChannelManager')) {
96 require_once $this->vcm_lib_path;
97 }
98 if (!method_exists('VikChannelManager', 'getLatestFromGuests')) {
99 // VCM is outdated
100 $this->vcm_exists = false;
101 }
102 } else {
103 $this->vcm_exists = false;
104 }
105
106 // avoid queries on certain pages, as VCM may not have been activated yet
107 if (VBOPlatformDetection::isWordPress() && $this->vcm_exists) {
108 global $pagenow;
109 $skip_pages = ['update.php', 'plugins.php', 'plugin-install.php'];
110 if (isset($pagenow) && in_array($pagenow, $skip_pages)) {
111 $this->vcm_exists = false;
112 }
113 }
114 }
115
116 /**
117 * This widget returns the latest activity information to schedule
118 * periodic watch data in order to be able to trigger notifications.
119 * No CSS/JS assets are needed during preloading.
120 *
121 * @return void|object
122 */
123 public function preload()
124 {
125 if (!$this->vcm_exists) {
126 return null;
127 }
128
129 // use VCM to load the latest guest activity ids
130 $latest_activities = [];
131 try {
132 $latest_activities = VikChannelManager::getLatestFromGuests(['messages', 'reviews'], 0, 1);
133 } catch (Exception $e) {
134 // do nothing
135 }
136
137 if (!is_array($latest_activities) || !$latest_activities) {
138 return null;
139 }
140
141 // default watch-data values to monitor
142 $watch_data = new stdClass;
143 $watch_data->guest_review = 0;
144 $watch_data->guest_message = '';
145 $watch_data->message_id = 0;
146 $watch_data->message_bid = 0;
147
148 foreach ($latest_activities as $activity) {
149 if (isset($activity->id_review) && empty($watch_data->guest_review)) {
150 // this is a guest review
151 $watch_data->guest_review = $activity->id_review;
152 } elseif (!isset($activity->id_review) && empty($watch_data->message_id)) {
153 // this is a guest message
154 $watch_data->guest_message = $activity->content;
155 $watch_data->message_id = $activity->id_message;
156 $watch_data->message_bid = $activity->idorder;
157 }
158 }
159
160 return $watch_data;
161 }
162
163 /**
164 * Checks for new notifications by using the previous preloaded watch-data.
165 *
166 * @param VBONotificationWatchdata $watch_data the preloaded watch-data object.
167 *
168 * @return array data object to watch next and notifications array.
169 *
170 * @see preload()
171 *
172 * @since 1.15.0 (J) - 1.5.0 (WP)
173 */
174 public function getNotifications(VBONotificationWatchdata $watch_data = null)
175 {
176 // default empty values
177 $watch_next = null;
178 $notifications = null;
179
180 if (!$this->vcm_exists || !$watch_data) {
181 return [$watch_next, $notifications];
182 }
183
184 // grab latest watch data values
185 $latest_guest_review = (int)$watch_data->get('guest_review', 0);
186 $latest_guest_message = $watch_data->get('guest_message', '');
187 $latest_message_id = (int)$watch_data->get('message_id', 0);
188 $latest_message_bid = (int)$watch_data->get('message_bid', 0);
189
190 // use VCM to load the latest guest activity ids
191 $latest_activities = [];
192 try {
193 $latest_activities = VikChannelManager::getLatestFromGuests(['messages', 'reviews'], 0, 1);
194 } catch (Exception $e) {
195 // do nothing
196 }
197
198 if (!is_array($latest_activities) || !$latest_activities) {
199 return [$watch_next, $notifications];
200 }
201
202 // default watch-data next values to monitor
203 $watch_next = new stdClass;
204 $watch_next->guest_review = $latest_guest_review;
205 $watch_next->guest_message = $latest_guest_message;
206 $watch_next->message_id = $latest_message_id;
207 $watch_next->message_bid = $latest_message_bid;
208
209 // new notifications pool (if any)
210 $notifications = [];
211
212 foreach ($latest_activities as $activity) {
213 if (isset($activity->id_review)) {
214 // this is a guest review
215 if ($activity->id_review > $latest_guest_review) {
216 // set the next watch data value
217 $watch_next->guest_review = $activity->id_review;
218 // compose the notification(s) to dispatch for the guest review(s)
219 $review_notifications = VBONotificationScheduler::getInstance()->buildReviewDataObjects([$activity]);
220 if (!empty($review_notifications) && is_array($review_notifications)) {
221 $notifications = array_merge($notifications, $review_notifications);
222 }
223 }
224 } else {
225 // this is a guest message
226 if ($activity->id_message > $latest_message_id && ($activity->idorder != $latest_message_bid || $activity->content != $latest_guest_message)) {
227 $watch_next->guest_message = $activity->content;
228 $watch_next->message_id = $activity->id_message;
229 $watch_next->message_bid = $activity->idorder;
230 // compose the notification(s) to dispatch for the guest message(s)
231 $guestmess_notifications = VBONotificationScheduler::getInstance()->buildGuestMessageDataObjects([$activity]);
232 if (!empty($guestmess_notifications) && is_array($guestmess_notifications)) {
233 $notifications = array_merge($notifications, $guestmess_notifications);
234 }
235 }
236 }
237 }
238
239 return [$watch_next, $notifications];
240 }
241
242 /**
243 * Custom method for this widget only to load the latest guest activities.
244 * The method is called by the admin controller through an AJAX request.
245 * The visibility should be public, it should not exit the process, and
246 * any content sent to output will be returned to the AJAX response.
247 *
248 * It's the actual rendering of the widget which also allows navigation.
249 */
250 public function loadActivities()
251 {
252 $offset = VikRequest::getInt('offset', 0, 'request');
253 $length = VikRequest::getInt('length', $this->activities_per_type, 'request');
254 $wrapper = VikRequest::getString('wrapper', '', 'request');
255
256 if (!$this->vcm_exists) {
257 echo 'e4j.error.missing or outdated VCM';
258 return;
259 }
260
261 // load latest activities
262 $latest_activities = [];
263 try {
264 $latest_activities = VikChannelManager::getLatestFromGuests(['messages', 'reviews'], $offset, $length);
265 } catch (Exception $e) {
266 // do nothing
267 }
268
269 foreach ($latest_activities as $activity) {
270 $activity_type = isset($activity->id_review) ? 'review' : 'message';
271 $activity_content = $activity->content;
272 if (empty($activity_content)) {
273 $activity_content = '.....';
274 } elseif (strlen($activity_content) > 90) {
275 if (function_exists('mb_substr')) {
276 $activity_content = mb_substr($activity_content, 0, 90, 'UTF-8');
277 } else {
278 $activity_content = substr($activity_content, 0, 90);
279 }
280 $activity_content .= '...';
281 }
282
283 ?>
284 <div class="vbo-dashboard-guest-activity vbo-dashboard-guest-activity-<?php echo $activity_type; ?>" onclick="vboWidgetLatestFromGuestsOpenBooking('<?php echo $activity->idorder; ?>', '<?php echo $activity_type == 'message' ? '#messaging' : ''; ?>');">
285 <div class="vbo-dashboard-guest-activity-avatar">
286 <?php
287 if (!empty($activity->guest_avatar)) {
288 // highest priority goes to the profile picture, not always available
289 ?>
290 <img class="vbo-dashboard-guest-activity-avatar-profile" src="<?php echo $activity->guest_avatar; ?>" />
291 <?php
292 } elseif (!empty($activity->pic)) {
293 // customer profile picture is not the same as the photo avatar
294 ?>
295 <img class="vbo-dashboard-guest-activity-avatar-profile" src="<?php echo strpos($activity->pic, 'http') === 0 ? $activity->pic : VBO_SITE_URI . 'resources/uploads/' . $activity->pic; ?>" />
296 <?php
297 } elseif (!empty($activity->channel_logo)) {
298 // channel logo goes as second option
299 ?>
300 <img class="vbo-dashboard-guest-activity-avatar-profile" src="<?php echo $activity->channel_logo; ?>" />
301 <?php
302 } else {
303 // we use an icon as fallback
304 VikBookingIcons::e('user', 'vbo-dashboard-guest-activity-avatar-icon');
305 }
306 ?>
307 </div>
308 <div class="vbo-dashboard-guest-activity-content">
309 <div class="vbo-dashboard-guest-activity-content-head">
310 <div class="vbo-dashboard-guest-activity-content-info-details">
311 <h4><?php echo $activity->first_name . (!empty($activity->last_name) ? ' ' . $activity->last_name : ''); ?></h4>
312 <div class="vbo-dashboard-guest-activity-content-info-icon">
313 <?php
314 if ($activity_type == 'review') {
315 // we display an icon as well as the score
316 VikBookingIcons::e('star');
317 ?>
318 <span class="vbo-dashboard-guest-activity-content-info-rate"><?php echo round(($activity->score / 2), 1); ?></span>
319 <?php
320 } else {
321 // we use just an icon to tell that it's a chat guest message
322 if (empty($activity->read_dt)) {
323 // print also an icon to inform that the message was not read
324 VikBookingIcons::e('exclamation-circle');
325 echo ' ';
326 }
327 VikBookingIcons::e('comment-dots');
328 }
329 ?>
330 </div>
331 </div>
332 <div class="vbo-dashboard-guest-activity-content-info-date">
333 <?php
334 $activity_ts = strtotime($activity->last_updated);
335 ?>
336 <span><?php echo date('H:i', $activity_ts); ?></span>
337 <?php
338 if (date('Y-m-d', $activity_ts) != $this->today_ymd) {
339 // format and print the date
340 ?>
341 <span><?php echo date(str_replace('/', $this->datesep, $this->df), $activity_ts); ?></span>
342 <?php
343 } else {
344 // print "today"
345 ?>
346 <span><?php echo JText::translate('VBTODAY'); ?></span>
347 <?php
348 }
349 ?>
350 </div>
351 </div>
352 <div class="vbo-dashboard-guest-activity-content-info-msg">
353 <p><?php echo $activity_content; ?></p>
354 </div>
355 </div>
356 </div>
357 <?php
358 }
359
360 // append navigation
361 ?>
362 <div class="vbo-guestactivitywidget-commands">
363 <div class="vbo-guestactivitywidget-commands-main">
364 <?php
365 if ($offset > 0) {
366 // show backward navigation button
367 ?>
368 <div class="vbo-guestactivitywidget-command-chevron vbo-guestactivitywidget-command-prev">
369 <span class="vbo-guestactivitywidget-prev" onclick="vboWidgetLatestFromGuestsNavigate('<?php echo $wrapper; ?>', -1);"><?php VikBookingIcons::e('chevron-left'); ?></span>
370 </div>
371 <?php
372 }
373 ?>
374 <div class="vbo-guestactivitywidget-command-chevron vbo-guestactivitywidget-command-next">
375 <span class="vbo-guestactivitywidget-next" onclick="vboWidgetLatestFromGuestsNavigate('<?php echo $wrapper; ?>', 1);"><?php VikBookingIcons::e('chevron-right'); ?></span>
376 </div>
377 </div>
378 </div>
379 <?php
380
381 // append the total number of activities displayed, the current offset and the latest activity datetime
382 $tot_activities = count($latest_activities);
383 $latest_datetime = $tot_activities > 0 && $offset === 0 ? $latest_activities[0]->last_updated : null;
384
385 echo ';' . __FUNCTION__ . ';' . $tot_activities . ';' . __FUNCTION__ . ';' . $offset . ';' . __FUNCTION__ . ';' . $latest_datetime;
386 }
387
388 /**
389 * Custom method for this widget only to watch the latest guest activities.
390 * The method is called by the admin controller through an AJAX request.
391 * The visibility should be public, it should not exit the process, and
392 * any content sent to output will be returned to the AJAX response.
393 *
394 * Outputs the new number of activities found from the latest datetime.
395 */
396 public function watchActivities()
397 {
398 $latest_dt = VikRequest::getString('latest_dt', '', 'request');
399 if (empty($latest_dt)) {
400 echo '0';
401 return;
402 }
403
404 if (!$this->vcm_exists) {
405 echo 'e4j.error.missing or outdated VCM';
406 return;
407 }
408
409 // load the latest activity (one is sufficient)
410 $latest_activities = [];
411 try {
412 $latest_activities = VikChannelManager::getLatestFromGuests(['messages', 'reviews'], 0, 1);
413 } catch (Exception $e) {
414 // do nothing
415 }
416
417 if (!count($latest_activities) || $latest_activities[0]->last_updated == $latest_dt) {
418 // no newest activities found
419 echo '0';
420 return;
421 }
422
423 // print 1 to indicate that new activities should be reloaded
424 echo '1';
425 }
426
427 public function render(VBOMultitaskData $data = null)
428 {
429 // increase widget's instance counter
430 static::$instance_counter++;
431
432 // check whether the widget is being rendered via AJAX when adding it through the customizer
433 $is_ajax = $this->isAjaxRendering();
434
435 // generate a unique ID for the latest from guests wrapper instance
436 $wrapper_instance = !$is_ajax ? static::$instance_counter : rand();
437 $wrapper_id = 'vbo-widget-latest-from-guests-' . $wrapper_instance;
438
439 // this widget will work only if VCM is available and updated, and if permissions are met
440 $vbo_auth_bookings = JFactory::getUser()->authorise('core.vbo.bookings', 'com_vikbooking');
441 if (!$this->vcm_exists || !$vbo_auth_bookings) {
442 return;
443 }
444
445 // multitask data event identifier for intervals
446 $js_intvals_id = '';
447 if ($data && $data->isModalRendering()) {
448 $js_intvals_id = $data->getModalJsIdentifier();
449 }
450
451 ?>
452 <div class="vbo-admin-widget-wrapper">
453 <div class="vbo-admin-widget-head">
454 <h4><?php echo $this->widgetIcon; ?> <span><?php echo $this->widgetName; ?></span></h4>
455 </div>
456 <div id="<?php echo $wrapper_id; ?>" class="vbo-dashboard-guests-latest" data-offset="0" data-length="<?php echo $this->activities_per_type; ?>" data-latestdt="">
457 <div class="vbo-dashboard-guest-activities-inner">
458 <div class="vbo-dashboard-guest-activities-list">
459 <?php
460 for ($i = 0; $i < $this->activities_per_page; $i++) {
461 ?>
462 <div class="vbo-dashboard-guest-activity vbo-dashboard-guest-activity-skeleton">
463 <div class="vbo-dashboard-guest-activity-avatar">
464 <div class="vbo-skeleton-loading vbo-skeleton-loading-avatar"></div>
465 </div>
466 <div class="vbo-dashboard-guest-activity-content">
467 <div class="vbo-dashboard-guest-activity-content-head">
468 <div class="vbo-skeleton-loading vbo-skeleton-loading-title"></div>
469 </div>
470 <div class="vbo-dashboard-guest-activity-content-subhead">
471 <div class="vbo-skeleton-loading vbo-skeleton-loading-subtitle"></div>
472 </div>
473 <div class="vbo-dashboard-guest-activity-content-info-msg">
474 <div class="vbo-skeleton-loading vbo-skeleton-loading-content"></div>
475 </div>
476 </div>
477 </div>
478 <?php
479 }
480 ?>
481 </div>
482 </div>
483 </div>
484 </div>
485
486 <?php
487 if (static::$instance_counter === 0 || $is_ajax) {
488 // HTML helper tag for URL routing and some JS functions should be loaded once per widget instance
489 $admin_file_base = VBOPlatformDetection::isWordPress() ? 'admin.php' : 'index.php';
490 ?>
491 <a class="vbo-widget-latest-from-guests-basenavuri" href="<?php echo $admin_file_base; ?>?option=com_vikbooking&task=editorder&cid[]=%d" style="display: none;"></a>
492
493 <script type="text/javascript">
494
495 /**
496 * Open the booking details page for the clicked activity
497 */
498 function vboWidgetLatestFromGuestsOpenBooking(id, url_suffix) {
499 var open_url = jQuery('.vbo-widget-latest-from-guests-basenavuri').first().attr('href');
500 open_url = open_url.replace('%d', id) + url_suffix;
501 // navigate
502 document.location.href = open_url;
503 }
504
505 /**
506 * Display the loading skeletons.
507 */
508 function vboWidgetLatestFromGuestsSkeletons(wrapper) {
509 var widget_instance = jQuery('#' + wrapper);
510 if (!widget_instance.length) {
511 return false;
512 }
513 widget_instance.find('.vbo-dashboard-guest-activities-list').html('');
514 for (var i = 0; i < <?php echo $this->activities_per_page; ?>; i++) {
515 var skeleton = '';
516 skeleton += '<div class="vbo-dashboard-guest-activity vbo-dashboard-guest-activity-skeleton">';
517 skeleton += ' <div class="vbo-dashboard-guest-activity-avatar">';
518 skeleton += ' <div class="vbo-skeleton-loading vbo-skeleton-loading-avatar"></div>';
519 skeleton += ' </div>';
520 skeleton += ' <div class="vbo-dashboard-guest-activity-content">';
521 skeleton += ' <div class="vbo-dashboard-guest-activity-content-head">';
522 skeleton += ' <div class="vbo-skeleton-loading vbo-skeleton-loading-title"></div>';
523 skeleton += ' </div>';
524 skeleton += ' <div class="vbo-dashboard-guest-activity-content-subhead">';
525 skeleton += ' <div class="vbo-skeleton-loading vbo-skeleton-loading-subtitle"></div>';
526 skeleton += ' </div>';
527 skeleton += ' <div class="vbo-dashboard-guest-activity-content-info-msg">';
528 skeleton += ' <div class="vbo-skeleton-loading vbo-skeleton-loading-content"></div>';
529 skeleton += ' </div>';
530 skeleton += ' </div>';
531 skeleton += '</div>';
532 // append skeleton
533 jQuery(skeleton).appendTo(widget_instance.find('.vbo-dashboard-guest-activities-list'));
534 }
535 }
536
537 /**
538 * Perform the request to load the latest activities.
539 */
540 function vboWidgetLatestFromGuestsLoad(wrapper) {
541 var widget_instance = jQuery('#' + wrapper);
542 if (!widget_instance.length) {
543 return false;
544 }
545 var current_offset = parseInt(widget_instance.attr('data-offset'));
546 var length_per_page = parseInt(widget_instance.attr('data-length'));
547
548 // the widget method to call
549 var call_method = 'loadActivities';
550
551 // make a request to load the activities
552 VBOCore.doAjax(
553 "<?php echo $this->getExecWidgetAjaxUri(); ?>",
554 {
555 widget_id: "<?php echo $this->getIdentifier(); ?>",
556 call: call_method,
557 offset: current_offset,
558 length: length_per_page,
559 wrapper: wrapper,
560 tmpl: "component"
561 },
562 (response) => {
563 try {
564 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
565 if (!obj_res.hasOwnProperty(call_method)) {
566 console.error('Unexpected JSON response', obj_res);
567 return false;
568 }
569 // response must contain 4 values separated by ";call_method;"
570 var activities_data = obj_res[call_method].split(';' + call_method + ';');
571 if (activities_data.length != 4) {
572 return;
573 }
574 // replace HTML with new activities
575 widget_instance.find('.vbo-dashboard-guest-activities-list').html(activities_data[0]);
576 // check if latest datetime is set
577 if (activities_data[3].length) {
578 widget_instance.attr('data-latestdt', activities_data[3]);
579 }
580 // check results
581 if (!isNaN(activities_data[1]) && parseInt(activities_data[1]) < 1) {
582 // no results can indicate the offset is invalid or too high
583 if (!isNaN(activities_data[2]) && parseInt(activities_data[2]) > 0) {
584 // reset offset to 0
585 widget_instance.attr('data-offset', 0);
586 // show loading skeletons
587 vboWidgetLatestFromGuestsSkeletons(wrapper);
588 // reload the first page
589 vboWidgetLatestFromGuestsLoad(wrapper);
590 }
591 }
592 } catch(err) {
593 console.error('could not parse JSON response', err, response);
594 }
595 },
596 (error) => {
597 // remove the skeleton loading
598 widget_instance.find('.vbo-dashboard-guest-activities-list').find('.vbo-dashboard-guest-activity-skeleton').remove();
599 console.error(error);
600 }
601 );
602 }
603
604 /**
605 * Navigate between the various pages of the activities.
606 */
607 function vboWidgetLatestFromGuestsNavigate(wrapper, direction) {
608 var widget_instance = jQuery('#' + wrapper);
609 if (!widget_instance.length) {
610 return false;
611 }
612
613 // current offset
614 var current_offset = parseInt(widget_instance.attr('data-offset'));
615
616 // steps per type
617 var steps = <?php echo $this->activities_per_type; ?>;
618
619 // show loading skeletons
620 vboWidgetLatestFromGuestsSkeletons(wrapper);
621
622 // check direction and update offset for next nav
623 if (direction > 0) {
624 // navigate forward
625 widget_instance.attr('data-offset', (current_offset + steps));
626 } else {
627 // navigate backward
628 var new_offset = current_offset - steps;
629 new_offset = new_offset >= 0 ? new_offset : 0;
630 widget_instance.attr('data-offset', new_offset);
631 }
632
633 // launch navigation
634 vboWidgetLatestFromGuestsLoad(wrapper);
635 }
636
637 /**
638 * Watch periodically if there are new activities to be displayed.
639 */
640 function vboWidgetLatestFromGuestsWatch(wrapper) {
641 var widget_instance = jQuery('#' + wrapper);
642 if (!widget_instance.length) {
643 return false;
644 }
645
646 var latest_dt = widget_instance.attr('data-latestdt');
647 if (!latest_dt || !latest_dt.length) {
648 return false;
649 }
650
651 // the widget method to call
652 var call_method = 'watchActivities';
653
654 // make a request to watch the activities
655 VBOCore.doAjax(
656 "<?php echo $this->getExecWidgetAjaxUri(); ?>",
657 {
658 widget_id: "<?php echo $this->getIdentifier(); ?>",
659 call: call_method,
660 latest_dt: latest_dt,
661 tmpl: "component"
662 },
663 (response) => {
664 try {
665 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
666 if (!obj_res.hasOwnProperty(call_method)) {
667 console.error('Unexpected JSON response', obj_res);
668 return false;
669 }
670 // response will contain the number of new activities
671 if (isNaN(obj_res[call_method]) || parseInt(obj_res[call_method]) < 1) {
672 // do nothing
673 return;
674 }
675 // new activities found, reset the offset and re-load the first page
676 widget_instance.attr('data-offset', 0);
677 // show loading skeletons
678 vboWidgetLatestFromGuestsSkeletons(wrapper);
679 // reload the first page
680 vboWidgetLatestFromGuestsLoad(wrapper);
681 } catch(err) {
682 console.error('could not parse JSON response', err, response);
683 }
684 },
685 (error) => {
686 // do nothing
687 console.error(error);
688 }
689 );
690 }
691
692 </script>
693 <?php
694 }
695 ?>
696
697 <script type="text/javascript">
698
699 jQuery(function() {
700
701 // when document is ready, load latest activities for this widget's instance
702 vboWidgetLatestFromGuestsLoad('<?php echo $wrapper_id; ?>');
703
704 // set interval for loading new activities automatically
705 var watch_intv = setInterval(function() {
706 vboWidgetLatestFromGuestsWatch('<?php echo $wrapper_id; ?>');
707 }, 60000);
708
709 <?php
710 if ($js_intvals_id) {
711 // widget can be dismissed through the modal
712 ?>
713 document.addEventListener(VBOCore.widget_modal_dismissed + '<?php echo $js_intvals_id; ?>', (e) => {
714 clearInterval(watch_intv);
715 });
716 <?php
717 }
718 ?>
719
720 });
721
722 </script>
723
724 <?php
725 }
726 }
727