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 | site/helpers/operator.php +248 -41 1.7.2 → 1.8.16 View file →
@@ -24,8 +24,16 @@
24 24 */
25 25 protected static $instance = null;
26 26
27 27 /**
28 + * A cache array holding all the existing operators.
29 + *
30 + * @var array[]
31 + * @since 1.18.0 (J) - 1.8.0 (WP)
32 + */
33 + protected $operators = null;
34 +
35 + /**
28 36 * The various tool permission types.
29 37 *
30 38 * @var array
31 39 *
@@ -61,25 +69,39 @@
61 69 }
62 70
63 71 /**
64 72 * Returns the list of all the operators.
73 + *
74 + * @param array $ids Optional list of IDs to filter.
65 75 *
66 76 * @return array The list of operators
77 + *
78 + * @since 1.18.0 (J) - 1.8.0 (WP) The method now caches all the operators to prevent duplicate queries.
67 79 */
68 - public function getAll()
80 + public function getAll(array $ids = [])
69 81 {
70 82 $dbo = JFactory::getDbo();
71 83
72 - $operators = [];
73 -
74 - $q = "SELECT * FROM `#__vikbooking_operators` ORDER BY `first_name` ASC, `last_name` ASC;";
75 - $dbo->setQuery($q);
76 - $all = $dbo->loadAssocList();
77 - foreach ($all as $o) {
78 - $operators[$o['id']] = $o;
84 + if (is_null($this->operators)) {
85 + $this->operators = [];
86 +
87 + $q = $dbo->getQuery(true)
88 + ->select('*')
89 + ->from($dbo->qn('#__vikbooking_operators'))
90 + ->order($dbo->qn('first_name') . ' ASC')
91 + ->order($dbo->qn('last_name') . ' ASC');
92 +
93 + $dbo->setQuery($q);
94 +
95 + foreach ($dbo->loadAssocList() as $o) {
96 + $this->operators[$o['id']] = $o;
97 + }
79 98 }
80 99
81 - return $operators;
100 + // take only the operators matching the specified query
101 + return array_filter($this->operators, function($o) use ($ids) {
102 + return !$ids || in_array($o['id'], $ids);
103 + });
82 104 }
83 105
84 106 /**
85 107 * Fetches the information and permissions of one operator by ID.
@@ -105,13 +127,71 @@
105 127 return [];
106 128 }
107 129
108 130 $operator['perms'] = !empty($operator['perms']) ? (array) json_decode($operator['perms'], true) : [];
131 + $operator['work_days_week'] = !empty($operator['work_days_week']) ? (array) json_decode($operator['work_days_week'], true) : [];
132 + $operator['work_days_exceptions'] = !empty($operator['work_days_exceptions']) ? (array) json_decode($operator['work_days_exceptions'], true) : [];
109 133
110 134 return $operator;
111 135 }
112 136
113 137 /**
138 + * Fetches the information and permissions of one operator by email.
139 + *
140 + * @param string $email The operator email address.
141 + *
142 + * @return array Operator record or empty array.
143 + *
144 + * @since 1.18.15 (J) - 1.8.15 (WP)
145 + */
146 + public function getByEmail(string $email)
147 + {
148 + $dbo = JFactory::getDbo();
149 +
150 + $dbo->setQuery(
151 + $dbo->getQuery(true)
152 + ->select('*')
153 + ->from($dbo->qn('#__vikbooking_operators'))
154 + ->where($dbo->qn('email') . ' = ' . $dbo->q($email))
155 + );
156 +
157 + $operator = $dbo->loadAssoc();
158 +
159 + return $operator ? $this->getOne($operator['id']) : [];
160 + }
161 +
162 + /**
163 + * Returns a list of operators compatible for rendering them as elements.
164 + *
165 + * @param array $ids Optional list of IDs to filter.
166 + *
167 + * @return array
168 + *
169 + * @since 1.18.0 (J) - 1.8.0 (WP)
170 + */
171 + public function getElements(array $ids = [])
172 + {
173 + $elements = [];
174 +
175 + foreach ($this->getAll($ids) as $operator) {
176 + // check for operator's avatar picture
177 + $operator_pic = $operator['pic'] ?: '';
178 + if ($operator_pic) {
179 + $operator_pic = strpos($operator_pic, 'http') === 0 ? $operator_pic : VBO_SITE_URI . 'resources/uploads/' . $operator_pic;
180 + }
181 +
182 + // push operator element
183 + $elements[] = [
184 + 'id' => $operator['id'],
185 + 'name' => ltrim($operator['first_name'] . ' ' . $operator['last_name']),
186 + 'img_uri' => $operator_pic,
187 + ];
188 + }
189 +
190 + return $elements;
191 + }
192 +
193 + /**
114 194 * Returns the list of all the operators filtered by a specific
115 195 * permission type and with an array of their own permissions.
116 196 *
117 197 * @param string $permtype The type of permission to look for.
@@ -125,10 +205,9 @@
125 205 $operators = $this->getAll();
126 206 }
127 207
128 208 foreach ($operators as $k => $v) {
129 - $perms = !empty($v['perms']) ? json_decode($v['perms'], true) : [];
130 - $perms = !is_array($perms) ? [] : $perms;
209 + $perms = !empty($v['perms']) && is_string($v['perms']) ? (array) json_decode($v['perms'], true) : [];
131 210 $operators[$k]['perms'] = $perms;
132 211 $enabled = false;
133 212 foreach ($perms as $perm) {
134 213 if ($permtype && ($perm['type'] ?? '') == $permtype) {
@@ -223,9 +302,14 @@
223 302 $dbo = JFactory::getDbo();
224 303 $session = JFactory::getSession();
225 304 $cookie = JFactory::getApplication()->input->cookie;
226 305
227 - $q = "SELECT * FROM `#__vikbooking_operators` WHERE `code`=" . $dbo->q($code);
306 + /**
307 + * The operators authentication process is now case sensitive.
308 + *
309 + * @since 1.18 (J) - 1.8 (WP)
310 + */
311 + $q = "SELECT * FROM `#__vikbooking_operators` WHERE BINARY `code` = " . $dbo->q($code);
228 312 $dbo->setQuery($q, 0, 1);
229 313 $operator = $dbo->loadAssoc();
230 314
231 315 // ensure a valid code was provided
@@ -295,8 +379,73 @@
295 379 return false;
296 380 }
297 381
298 382 /**
383 + * Builds the URI to render the provided operator tool.
384 + *
385 + * @param string $tool The operator tool identifier.
386 + * @param int $itemid The optional page/item ID.
387 + *
388 + * @return string The routed operator tool URI.
389 + *
390 + * @since 1.17.6 (WP) - 1.7.6 (WP)
391 + */
392 + public function getToolUri(string $tool, int $itemid = 0)
393 + {
394 + // build URI to current tool
395 + return JRoute::rewrite(
396 + sprintf(
397 + 'index.php?option=com_vikbooking&view=operators&tool=%s&Itemid=%d',
398 + $tool,
399 + ($itemid ?: JFactory::getApplication()->input->getInt('Itemid', 0))
400 + )
401 + );
402 + }
403 +
404 + /**
405 + * Authorizes the currently logged operator to access the given tool.
406 + *
407 + * @param string $tool The operator tool identifier.
408 + *
409 + * @return array List of operator-tool data including:
410 + * - The operator record accessing the tool.
411 + * - The operator-tool permissions registry.
412 + * - The base URI for rendering the tool.
413 + *
414 + * @throws Exception
415 + *
416 + * @since 1.17.6 (WP) - 1.7.6 (WP)
417 + */
418 + public function authOperatorToolData(string $tool)
419 + {
420 + // attempt to get the current operator
421 + $operator = $this->getOperatorAccount();
422 +
423 + if (!$operator) {
424 + throw new Exception('Operator authentication required.', 401);
425 + }
426 +
427 + // get tool data
428 + $tool_data = $this->getToolData($tool);
429 +
430 + if (!$tool_data) {
431 + // tool is unknown
432 + throw new Exception(sprintf('Operator tool not found (%s)', $tool), 404);
433 + }
434 +
435 + if (!$this->checkPermissions($operator, $tool)) {
436 + // no permission to access this tool
437 + throw new Exception(sprintf('Not enough permissions to access the tool (%s)', $tool), 403);
438 + }
439 +
440 + return [
441 + $operator,
442 + new JObject(($operator['perms'] ?: [])),
443 + $this->getToolUri($tool),
444 + ];
445 + }
446 +
447 + /**
299 448 * Returns the data for the given tool identifier.
300 449 *
301 450 * @param string $tool The tool identifier.
302 451 *
@@ -393,29 +542,13 @@
393 542 // return the cached list
394 543 return $this->toolPermissionTypes;
395 544 }
396 545
397 - $dbo = JFactory::getDbo();
398 -
399 - // fetch all rooms
400 - $dbo->setQuery(
401 - $dbo->getQuery(true)
402 - ->select([$dbo->qn('id'), $dbo->qn('name')])
403 - ->from($dbo->qn('#__vikbooking_rooms'))
404 - ->order($dbo->qn('avail') . ' DESC')
405 - ->order($dbo->qn('name') . ' ASC')
406 - );
407 -
408 - $rooms = [];
409 -
410 - foreach ($dbo->loadAssocList() as $room) {
411 - $rooms[$room['id']] = $room['name'];
412 - }
413 -
414 546 // build the default tool permission types
415 547 $this->toolPermissionTypes = [
416 548 'tableaux' => [
417 549 'name' => JText::translate('VBOOPERPERMTABLEAUX'),
550 + 'icon' => '<i class="' . VikBookingIcons::i('stream') . '"></i>',
418 551 'permissions' => [
419 552 'days' => [
420 553 'type' => 'number',
421 554 'label' => JText::translate('VBOPERMTBLXDAYS'),
@@ -425,17 +558,15 @@
425 558 'max' => 365,
426 559 'default' => 14,
427 560 ],
428 561 'rooms' => [
429 - 'type' => 'select',
562 + 'type' => 'listings',
430 563 'label' => JText::translate('VBOPERMTBLXROOMS'),
431 564 'multiple' => true,
432 - 'assets' => true,
433 565 'asset_options' => [
434 - 'placeholder' => JText::translate('VBCOUPONALLVEHICLES'),
435 - 'allowClear' => true,
436 - ],
437 - 'options' => $rooms,
566 + 'placeholder' => JText::translate('VBCOUPONALLVEHICLES'),
567 + 'allowClear' => true,
568 + ],
438 569 ],
439 570 'guestname' => [
440 571 'type' => 'select',
441 572 'label' => JText::translate('VBOCUSTOMERDETAILS'),
@@ -443,8 +574,17 @@
443 574 1 => JText::translate('VBYES'),
444 575 0 => JText::translate('VBNO'),
445 576 ],
446 577 ],
578 + 'guestphone' => [
579 + 'type' => 'select',
580 + 'label' => JText::translate('ORDER_PHONE'),
581 + 'default' => 0,
582 + 'options' => [
583 + 1 => JText::translate('VBYES'),
584 + 0 => JText::translate('VBNO'),
585 + ],
586 + ],
447 587 'roomextras' => [
448 588 'type' => 'select',
449 589 'label' => JText::translate('VBPEDITBUSYEXTRACOSTS'),
450 590 'options' => [
@@ -457,19 +597,86 @@
457 597 'rendering_type' => 'view',
458 598 ],
459 599 'finance' => [
460 600 'name' => JText::translate('VBO_W_FINANCE_TITLE'),
601 + 'icon' => '<i class="' . VikBookingIcons::i('piggy-bank') . '"></i>',
461 602 'permissions' => [
462 603 'rooms' => [
463 - 'type' => 'select',
604 + 'type' => 'listings',
464 605 'label' => JText::translate('VBOPERMTBLXROOMS'),
465 606 'multiple' => true,
466 - 'assets' => true,
467 607 'asset_options' => [
468 - 'placeholder' => JText::translate('VBCOUPONALLVEHICLES'),
469 - 'allowClear' => true,
470 - ],
471 - 'options' => $rooms,
608 + 'placeholder' => JText::translate('VBCOUPONALLVEHICLES'),
609 + 'allowClear' => true,
610 + ],
611 + ],
612 + ],
613 + // this native tool is rendered through a layout thanks to a callback
614 + 'rendering_type' => 'layout',
615 + 'rendering_callback' => function ($tool, $operator, $permissions, $tool_uri) {
616 + VikBooking::getOperatorInstance()->renderNativeToolLayout($tool, $operator, $permissions, $tool_uri);
617 + },
618 + ],
619 + 'guest_messaging' => [
620 + 'name' => JText::translate('VBO_W_GUESTMESSAGES_TITLE'),
621 + 'icon' => '<i class="' . VikBookingIcons::i('comment-dots') . '"></i>',
622 + 'permissions' => [
623 + 'rooms' => [
624 + 'type' => 'listings',
625 + 'label' => JText::translate('VBOPERMTBLXROOMS'),
626 + 'multiple' => true,
627 + 'asset_options' => [
628 + 'placeholder' => JText::translate('VBCOUPONALLVEHICLES'),
629 + 'allowClear' => true,
630 + ],
631 + ],
632 + ],
633 + // this native tool is rendered through a layout thanks to a callback
634 + 'rendering_type' => 'layout',
635 + 'rendering_callback' => function ($tool, $operator, $permissions, $tool_uri) {
636 + VikBooking::getOperatorInstance()->renderNativeToolLayout($tool, $operator, $permissions, $tool_uri);
637 + },
638 + ],
639 + 'task_manager' => [
640 + 'name' => JText::translate('VBO_TASK_MANAGER'),
641 + 'icon' => '<i class="' . VikBookingIcons::i('tasks') . '"></i>',
642 + 'permissions' => [
643 + 'accept_tasks' => [
644 + 'type' => 'select',
645 + 'label' => JText::translate('VBO_ACCEPT_TASKS'),
646 + 'options' => [
647 + 1 => JText::translate('VBYES'),
648 + 0 => JText::translate('VBNO'),
649 + ],
650 + ],
651 + 'create_tasks' => [
652 + 'type' => 'select',
653 + 'label' => JText::translate('VBO_CREATE_TASKS'),
654 + 'help' => JText::translate('VBO_SETT_E4JC_APP'),
655 + 'options' => [
656 + 1 => JText::translate('VBYES'),
657 + 0 => JText::translate('VBNO'),
658 + ],
659 + ],
660 + ],
661 + // this native tool is rendered through a layout thanks to a callback
662 + 'rendering_type' => 'layout',
663 + 'rendering_callback' => function ($tool, $operator, $permissions, $tool_uri) {
664 + VikBooking::getOperatorInstance()->renderNativeToolLayout($tool, $operator, $permissions, $tool_uri);
665 + },
666 + ],
667 + 'work_days' => [
668 + 'name' => JText::translate('VBO_WORK_DAYS'),
669 + 'icon' => '<i class="' . VikBookingIcons::i('toolbox') . '"></i>',
670 + 'permissions' => [
671 + 'work_days_exceptions' => [
672 + 'type' => 'select',
673 + 'label' => JText::translate('VBO_EXCEPTIONS'),
674 + 'help' => implode(' - ', [JText::translate('VBO_WORK_DAYS_OFF'), JText::translate('VBO_WORK_DAYS_ON')]),
675 + 'options' => [
676 + 1 => JText::translate('VBYES'),
677 + 0 => JText::translate('VBNO'),
678 + ],
472 679 ],
473 680 ],
474 681 // this native tool is rendered through a layout thanks to a callback
475 682 'rendering_type' => 'layout',