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/admin_widgets.php +106 -24 1.6.7 → 1.8.16 View file →
@@ -31,8 +31,17 @@
31 31 */
32 32 protected static $helper = null;
33 33
34 34 /**
35 + * List of preloaded widgets.
36 + *
37 + * @var array
38 + *
39 + * @since 1.18.3 (J) - 1.8.3 (WP)
40 + */
41 + protected static $preloaded = [];
42 +
43 + /**
35 44 * The database handler instance.
36 45 *
37 46 * @var object
38 47 */
@@ -45,8 +54,17 @@
45 54 */
46 55 protected $widgets;
47 56
48 57 /**
58 + * The list of widget positions in the multitask panel.
59 + *
60 + * @var array
61 + *
62 + * @since 1.16.10 (J) - 1.6.10 (WP)
63 + */
64 + protected $widgets_pos_list;
65 +
66 + /**
49 67 * Class constructor is protected.
50 68 *
51 69 * @see getInstance()
52 70 */
@@ -54,8 +72,9 @@
54 72 {
55 73 static::$helper = [];
56 74 $this->dbo = JFactory::getDbo();
57 75 $this->widgets = [];
76 + $this->widgets_pos_list = (array) VBOFactory::getConfig()->getArray('multitasking_wpos', []);
58 77 $this->load();
59 78 }
60 79
61 80 /**
@@ -143,10 +162,19 @@
143 162 if (class_exists($classname)) {
144 163 // instantiate widget object
145 164 $widget = new $classname();
146 165
147 - // push widget object
148 - array_push($this->widgets, $widget);
166 + /**
167 + * Call the widget's preflight method to see if it's compatible with the current environment.
168 + *
169 + * @since 1.16.10 (J) - 1.6.10 (WP)
170 + */
171 + if (!$widget->preflight()) {
172 + continue;
173 + }
174 +
175 + // push the installed widget object
176 + $this->widgets[] = $widget;
149 177 }
150 178 } catch (Exception $e) {
151 179 // do nothing
152 180 }
@@ -198,8 +226,9 @@
198 226 // start container
199 227 $container = new stdClass;
200 228 $container->size = 'small';
201 229 $container->widgets = [
230 + 'aitools',
202 231 'forecast',
203 232 'bookings_calendar',
204 233 'reminders',
205 234 ];
@@ -248,8 +277,9 @@
248 277 $container = new stdClass;
249 278 $container->size = 'medium';
250 279 $container->widgets = [
251 280 'finance',
281 + 'inquiries_chat',
252 282 'currency_converter',
253 283 ];
254 284 // push container
255 285 array_push($section->containers, $container);
@@ -367,30 +397,58 @@
367 397 $descr = $widget->getDescription();
368 398
369 399 if ($preload) {
370 400 // preload widget's CSS/JS assets (if any)
371 - $watch_data = $widget->preload();
401 + $watch_data = array_key_exists($id, static::$preloaded) ? static::$preloaded[$id] : $widget->preload();
402 +
372 403 if ($watch_data) {
373 404 // assign watching data to this widget
374 405 $watch[$id] = $watch_data;
375 406 }
407 +
408 + // overwrite cache for the preloaded widget result
409 + static::$preloaded[$id] = $watch_data;
376 410 }
377 411
378 412 // build widget info object
379 413 $wtdata = new stdClass;
380 - $wtdata->id = $id;
381 - $wtdata->name = $name;
382 - $wtdata->descr = $descr;
383 - $wtdata->icon = $widget->getIcon();
384 - $wtdata->style = str_replace(array(' ', '_'), '-', $widget->getStyleName());
414 + $wtdata->id = $id;
415 + $wtdata->name = $name;
416 + $wtdata->descr = $descr;
417 + $wtdata->icon = $widget->getIcon();
418 + $wtdata->style = str_replace(array(' ', '_'), '-', $widget->getStyleName());
419 + $wtdata->priority = $widget->getPriority();
385 420
386 421 // set object for sorting
387 - $names[$name] = $wtdata;
422 + $names[$name] = $wtdata;
388 423 }
389 424
390 425 // apply sorting by name
391 426 ksort($names);
392 427
428 + // apply sorting by priority
429 + usort($names, function($a, $b) {
430 + // the higher the priority is, the higher the position will be
431 + return $b->priority - $a->priority;
432 + });
433 +
434 + if ($this->widgets_pos_list) {
435 + // get the custom positions list
436 + $widgets_pos_list = $this->widgets_pos_list;
437 + // apply custom sorting
438 + usort($names, function($a, $b) use ($widgets_pos_list) {
439 + $wa_id = $a->id;
440 + $wb_id = $b->id;
441 +
442 + if (($widgets_pos_list[$wa_id] ?? null) && ($widgets_pos_list[$wb_id] ?? null)) {
443 + // the higher the custom position is, the lower the sorting position will be
444 + return $widgets_pos_list[$wa_id] > $widgets_pos_list[$wb_id] ? 1 : -1;
445 + }
446 +
447 + return 0;
448 + });
449 + }
450 +
393 451 // push sorted widgets to pool
394 452 foreach ($names as $wtdata) {
395 453 $pool[] = $wtdata;
396 454 }
@@ -398,9 +456,9 @@
398 456 /**
399 457 * In case some widgets were pre-loaded for watching certain
400 458 * events, enqueue the watch-data list to the document.
401 459 */
402 - if (count($watch)) {
460 + if ($watch) {
403 461 // schedule the browser notifications watching data
404 462 VBONotificationScheduler::getInstance()->registerWatchData($watch);
405 463 }
406 464
@@ -416,11 +474,12 @@
416 474 * containers and widgets.
417 475 */
418 476 public function getWidgetsMap()
419 477 {
420 - $q = "SELECT `setting` FROM `#__vikbooking_config` WHERE `param`='admin_widgets_map';";
421 - $this->dbo->setQuery($q);
422 - $map = $this->dbo->loadResult();
478 + $config = VBOFactory::getConfig();
479 +
480 + $map = $config->get('admin_widgets_map', null);
481 +
423 482 if ($map) {
424 483 $map = json_decode($map);
425 484 return is_object($map) && !empty($map->sections) && is_array($map->sections) ? $map : $this->getDefaultWidgetsMap();
426 485 }
@@ -425,12 +484,11 @@
425 484 return is_object($map) && !empty($map->sections) && is_array($map->sections) ? $map : $this->getDefaultWidgetsMap();
426 485 }
427 486
428 487 $default_map = $this->getDefaultWidgetsMap();
429 - $q = "INSERT INTO `#__vikbooking_config` (`param`,`setting`) VALUES ('admin_widgets_map', " . $this->dbo->quote(json_encode($default_map)) . ");";
430 - $this->dbo->setQuery($q);
431 - $this->dbo->execute();
432 488
489 + $config->set('admin_widgets_map', $default_map);
490 +
433 491 return $default_map;
434 492 }
435 493
436 494 /**
@@ -441,9 +499,9 @@
441 499 * @return bool True on success, false otherwise.
442 500 */
443 501 public function updateWidgetsMap($sections)
444 502 {
445 - if (!is_array($sections) || !count($sections)) {
503 + if (!is_array($sections) || !$sections) {
446 504 return false;
447 505 }
448 506
449 507 // prepare new map object
@@ -449,11 +507,9 @@
449 507 // prepare new map object
450 508 $map = new stdClass;
451 509 $map->sections = $sections;
452 510
453 - $q = "UPDATE `#__vikbooking_config` SET `setting`=" . $this->dbo->quote(json_encode($map)) . " WHERE `param`='admin_widgets_map';";
454 - $this->dbo->setQuery($q);
455 - $this->dbo->execute();
511 + VBOFactory::getConfig()->set('admin_widgets_map', $map);
456 512
457 513 return true;
458 514 }
459 515
@@ -477,13 +533,13 @@
477 533 /**
478 534 * Forces the rendering of a specific widget identifier.
479 535 *
480 536 * @param string $id the widget identifier.
481 - * @param VBOMultitaskData $data optional multitask data for the widget.
537 + * @param ?VBOMultitaskData $data optional multitask data for the widget.
482 538 *
483 539 * @return void
484 540 */
485 - public function renderWidget($id, VBOMultitaskData $data = null)
541 + public function renderWidget($id, ?VBOMultitaskData $data = null)
486 542 {
487 543 $id = $this->simplifyId($id);
488 544
489 545 foreach ($this->widgets as $widget) {
@@ -587,9 +643,9 @@
587 643 $tot_rooms_units += $r['units'];
588 644 }
589 645 $all_rooms_ids[$r['id']] = $r['name'];
590 646 $all_rooms_units[$r['id']] = $r['units'];
591 - $rparams = json_decode($r['params'], true);
647 + $rparams = json_decode((string) $r['params'], true);
592 648 $all_rooms_features[$r['id']] = is_array($rparams) && array_key_exists('features', $rparams) && is_array($rparams['features']) ? $rparams['features'] : [];
593 649 }
594 650 }
595 651
@@ -613,9 +669,9 @@
613 669 if (empty($key)) {
614 670 return false;
615 671 }
616 672
617 - if (!count(static::$helper)) {
673 + if (!static::$helper) {
618 674 $this->loadRoomsData();
619 675 }
620 676
621 677 if (isset(static::$helper[$key])) {
@@ -820,8 +876,34 @@
820 876 // update configuration record
821 877 VBOFactory::getConfig()->set('multitasking_map', json_encode($map));
822 878
823 879 return true;
880 + }
881 +
882 + /**
883 + * Sets the position for an admin widget in the multitask panel.
884 + *
885 + * @param array $pos_list Associative list of widget positions.
886 + *
887 + * @return array The updated widgets position list.
888 + *
889 + * @since 1.16.10 (J) - 1.6.10 (WP)
890 + */
891 + public function setMultitaskingWidgetPos($pos_list)
892 + {
893 + if (!is_array($pos_list)) {
894 + return false;
895 + }
896 +
897 + // turn all position values into integers
898 + $pos_list = array_map(function($pos) {
899 + return (int) $pos;
900 + }, $pos_list);
901 +
902 + // update configuration record
903 + VBOFactory::getConfig()->set('multitasking_wpos', $pos_list);
904 +
905 + return $pos_list;
824 906 }
825 907
826 908 /**
827 909 * Admin widgets used to be named as the entire file name,