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 +711 -0 1.6.3 → 1.8.16 View file →
@@ -1,0 +1,711 @@
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 + * Operator and tool permission types class handler.
15 + *
16 + * @since 1.11 (J) - 1.1 (WP)
17 + */
18 +final class VikBookingOperator
19 +{
20 + /**
21 + * The singleton instance of the class.
22 + *
23 + * @var VikBookingOperator
24 + */
25 + protected static $instance = null;
26 +
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 + /**
36 + * The various tool permission types.
37 + *
38 + * @var array
39 + *
40 + * @since 1.16.9 (J) - 1.6.9 (WP)
41 + */
42 + protected $toolPermissionTypes = [];
43 +
44 + /**
45 + * Class constructor is protected.
46 + *
47 + * @see getInstance()
48 + */
49 + protected function __construct()
50 + {
51 + // load all the operator tools and related permission types
52 + $this->loadToolPermissionTypes();
53 + }
54 +
55 + /**
56 + * Returns the global VikBookingOperator object, either
57 + * a new instance or the existing instance
58 + * if the class was already instantiated.
59 + *
60 + * @return self A new instance of the class.
61 + */
62 + public static function getInstance()
63 + {
64 + if (is_null(static::$instance)) {
65 + static::$instance = new static();
66 + }
67 +
68 + return static::$instance;
69 + }
70 +
71 + /**
72 + * Returns the list of all the operators.
73 + *
74 + * @param array $ids Optional list of IDs to filter.
75 + *
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.
79 + */
80 + public function getAll(array $ids = [])
81 + {
82 + $dbo = JFactory::getDbo();
83 +
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 + }
98 + }
99 +
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 + });
104 + }
105 +
106 + /**
107 + * Fetches the information and permissions of one operator by ID.
108 + *
109 + * @param int $id The operator ID.
110 + *
111 + * @return array
112 + */
113 + public function getOne($id)
114 + {
115 + $dbo = JFactory::getDbo();
116 +
117 + $dbo->setQuery(
118 + $dbo->getQuery(true)
119 + ->select('*')
120 + ->from($dbo->qn('#__vikbooking_operators'))
121 + ->where($dbo->qn('id') . ' = ' . (int) $id)
122 + );
123 +
124 + $operator = $dbo->loadAssoc();
125 +
126 + if (!$operator) {
127 + return [];
128 + }
129 +
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) : [];
133 +
134 + return $operator;
135 + }
136 +
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 + /**
194 + * Returns the list of all the operators filtered by a specific
195 + * permission type and with an array of their own permissions.
196 + *
197 + * @param string $permtype The type of permission to look for.
198 + * @param array $operators The list of operators.
199 + *
200 + * @return array The list of operators.
201 + */
202 + public function getOperatorsFromPermissions($permtype = '', $operators = [])
203 + {
204 + if (!$operators) {
205 + $operators = $this->getAll();
206 + }
207 +
208 + foreach ($operators as $k => $v) {
209 + $perms = !empty($v['perms']) && is_string($v['perms']) ? (array) json_decode($v['perms'], true) : [];
210 + $operators[$k]['perms'] = $perms;
211 + $enabled = false;
212 + foreach ($perms as $perm) {
213 + if ($permtype && ($perm['type'] ?? '') == $permtype) {
214 + // turn the permissions into an associative array for just the requested tool
215 + $operators[$k]['perms'] = $perm['perms'];
216 + $enabled = true;
217 + break;
218 + }
219 + }
220 + if (!$enabled) {
221 + unset($operators[$k]);
222 + }
223 + }
224 +
225 + return array_values($operators);
226 + }
227 +
228 + /**
229 + * Tells whether the operator is logged in by renewing
230 + * the session cookie if the auth method is through code.
231 + * Returns the information of the logged in operator or false.
232 + *
233 + * @return mixed Array if the operator is logged in, false otherwise.
234 + */
235 + public function getOperatorAccount()
236 + {
237 + $dbo = JFactory::getDbo();
238 + $user = JFactory::getUser();
239 +
240 + /**
241 + * Beware of a possible magic method __get() in JUser.
242 + * Assign the id property to a variable for evaluation.
243 + */
244 + $ujid = $user->id;
245 +
246 + if (!$user->guest && !empty($ujid)) {
247 + $q = "SELECT * FROM `#__vikbooking_operators` WHERE `ujid`=".(int)$user->id." LIMIT 1;";
248 + $dbo->setQuery($q);
249 + $record = $dbo->loadAssoc();
250 + if ($record) {
251 + // user is logged in to the site account
252 + return $record;
253 + }
254 + }
255 +
256 + $session = JFactory::getSession();
257 + $sessval = $session->get('vboOpFngpt', '');
258 + $cookie = JFactory::getApplication()->input->cookie;
259 + $cksess = $cookie->get('vboOpFngpt', '', 'string');
260 +
261 + if (!empty($sessval)) {
262 + // look up for this fingerprint in the session
263 + $q = "SELECT * FROM `#__vikbooking_operators` WHERE `fingpt`=" . $dbo->q($sessval);
264 + $dbo->setQuery($q, 0, 1);
265 + $record = $dbo->loadAssoc();
266 + if ($record) {
267 + // user is logged in through the session
268 + return $record;
269 + }
270 + }
271 +
272 + if (!empty($cksess)) {
273 + // look up for this fingerprint in the cookie
274 + $q = "SELECT * FROM `#__vikbooking_operators` WHERE `fingpt`=" . $dbo->q($cksess);
275 + $dbo->setQuery($q, 0, 1);
276 + $record = $dbo->loadAssoc();
277 + if ($record) {
278 + // user is logged in through the cookie, renew it for 2 weeks before returning the array
279 + VikRequest::setCookie('vboOpFngpt', $cksess, (time() + (86400 * 14)), '/', '', false, true);
280 + return $record;
281 + }
282 + }
283 +
284 + // user is not logged in
285 + return false;
286 + }
287 +
288 + /**
289 + * Login request through the authentication code.
290 + * If code is valid, the session and cookie are set.
291 + *
292 + * @param string $code the authentication code to check
293 + *
294 + * @return boolean true if the code exists, false otherwise
295 + */
296 + public function authOperator($code)
297 + {
298 + if (empty($code)) {
299 + return false;
300 + }
301 +
302 + $dbo = JFactory::getDbo();
303 + $session = JFactory::getSession();
304 + $cookie = JFactory::getApplication()->input->cookie;
305 +
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);
312 + $dbo->setQuery($q, 0, 1);
313 + $operator = $dbo->loadAssoc();
314 +
315 + // ensure a valid code was provided
316 + if ($operator) {
317 + // send cookie
318 + VikRequest::setCookie('vboOpFngpt', $operator['fingpt'], (time() + (86400 * 14)), '/', '', false, true);
319 +
320 + // update session value
321 + $session->set('vboOpFngpt', $operator['fingpt']);
322 +
323 + return true;
324 + }
325 +
326 + // invalid code provided
327 + return false;
328 + }
329 +
330 + /**
331 + * Unsets the session value and sends an expired cookie.
332 + * This action completely logs out an operator that should log back in.
333 + *
334 + * @return void
335 + */
336 + public function logoutOperator()
337 + {
338 + $app = JFactory::getApplication();
339 + $session = JFactory::getSession();
340 + $cookie = $app->input->cookie;
341 +
342 + $session->set('vboOpFngpt', '');
343 + VikRequest::setCookie('vboOpFngpt', $operator['fingpt'], (time() - (86400 * 14)), '/', '', false, true);
344 +
345 + // logout from the site
346 + $app->logout(JFactory::getUser()->id);
347 + }
348 +
349 + /**
350 + * Checks whether the given operator has the permissions to access
351 + * the given view type (permission type). Permissions are converted
352 + * into an array if still JSON encoded, and updated via reference.
353 + *
354 + * @param array $operator the operator record
355 + * @param string $permtype the name of the view to access
356 + *
357 + * @return boolean
358 + */
359 + public function checkPermissions(&$operator, $permtype)
360 + {
361 + if (!is_array($operator) || !$operator || empty($operator['perms'])) {
362 + return false;
363 + }
364 +
365 + if (is_scalar($operator['perms'])) {
366 + $operator['perms'] = json_decode($operator['perms'], true);
367 + $operator['perms'] = is_array($operator['perms']) ? $operator['perms'] : [];
368 + }
369 +
370 + foreach ($operator['perms'] as $k => $perm) {
371 + if (isset($perm['type']) && $perm['type'] == $permtype) {
372 + // has permission for this View, take only these perms
373 + $operator['perms'] = $operator['perms'][$k]['perms'];
374 + return true;
375 + }
376 + }
377 +
378 + // permission not found
379 + return false;
380 + }
381 +
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 + /**
448 + * Returns the data for the given tool identifier.
449 + *
450 + * @param string $tool The tool identifier.
451 + *
452 + * @return array
453 + *
454 + * @since 1.16.9 (J) - 1.6.9 (WP)
455 + */
456 + public function getToolData($tool)
457 + {
458 + return $this->toolPermissionTypes[$tool] ?? [];
459 + }
460 +
461 + /**
462 + * Returns the name for the given tool identifier.
463 + * If a raw language constant is detected, the raw
464 + * tool identifier value is returned (front-end).
465 + *
466 + * @param string $tool The tool identifier.
467 + *
468 + * @return string
469 + *
470 + * @since 1.16.9 (J) - 1.6.9 (WP)
471 + */
472 + public function getToolName($tool)
473 + {
474 + $tool_name = $this->toolPermissionTypes[$tool]['name'] ?? $tool;
475 +
476 + return preg_match("/^VB[A-Z0-9_]+$/", $tool_name) ? ucfirst(str_replace('_', ' ', $tool)) : $tool_name;
477 + }
478 +
479 + /**
480 + * Returns a list of permission types for a specific tool (i.e. "tableaux") or all tools.
481 + * Allows third-party plugins to define their own tool permission types.
482 + *
483 + * @param string $tool the tool identifier.
484 + *
485 + * @return array
486 + *
487 + * @since 1.16.9 (J) - 1.6.9 (WP)
488 + */
489 + public function getToolPermissionTypes($tool = null)
490 + {
491 + $default_tool_perms = $this->loadToolPermissionTypes();
492 +
493 + if (!$tool) {
494 + return $default_tool_perms;
495 + }
496 +
497 + return $default_tool_perms[$tool] ?? [];
498 + }
499 +
500 + /**
501 + * Renders a native operator tool through a callback (i.e. "finance").
502 + * Alternatively, tools could be rendered through a View (i.e. "tableaux").
503 + * Lastly, third-party plugins could load their own operator tools.
504 + *
505 + * @param string $tool the tool identifier.
506 + * @param array $operator the operator record calling the tool.
507 + * @param object $permissinos the operator-tool permissions registry.
508 + * @param string $tool_uri the base URI to the given tool.
509 + *
510 + * @return void
511 + *
512 + * @since 1.16.9 (J) - 1.6.9 (WP)
513 + */
514 + public function renderNativeToolLayout($tool, $operator, $permissions, $tool_uri)
515 + {
516 + // prepare the layout data
517 + $layout_data = [
518 + 'tool' => $tool,
519 + 'operator' => $operator,
520 + 'permissions' => $permissions,
521 + 'tool_uri' => $tool_uri,
522 + ];
523 +
524 + // render the requested tool layout
525 + echo JLayoutHelper::render('tools.' . $tool, $layout_data, null, [
526 + 'component' => 'com_vikbooking',
527 + 'client' => 'site',
528 + ]);
529 + }
530 +
531 + /**
532 + * Loads a list of default permission types for all the available tools.
533 + * Allows third-party plugins to define their own tools and permission types.
534 + *
535 + * @return array
536 + *
537 + * @since 1.16.9 (J) - 1.6.9 (WP)
538 + */
539 + protected function loadToolPermissionTypes()
540 + {
541 + if ($this->toolPermissionTypes) {
542 + // return the cached list
543 + return $this->toolPermissionTypes;
544 + }
545 +
546 + // build the default tool permission types
547 + $this->toolPermissionTypes = [
548 + 'tableaux' => [
549 + 'name' => JText::translate('VBOOPERPERMTABLEAUX'),
550 + 'icon' => '<i class="' . VikBookingIcons::i('stream') . '"></i>',
551 + 'permissions' => [
552 + 'days' => [
553 + 'type' => 'number',
554 + 'label' => JText::translate('VBOPERMTBLXDAYS'),
555 + 'help' => JText::translate('VBO_PERM_NEGATIVE_DAYS'),
556 + 'step' => 1,
557 + 'min' => -365,
558 + 'max' => 365,
559 + 'default' => 14,
560 + ],
561 + 'rooms' => [
562 + 'type' => 'listings',
563 + 'label' => JText::translate('VBOPERMTBLXROOMS'),
564 + 'multiple' => true,
565 + 'asset_options' => [
566 + 'placeholder' => JText::translate('VBCOUPONALLVEHICLES'),
567 + 'allowClear' => true,
568 + ],
569 + ],
570 + 'guestname' => [
571 + 'type' => 'select',
572 + 'label' => JText::translate('VBOCUSTOMERDETAILS'),
573 + 'options' => [
574 + 1 => JText::translate('VBYES'),
575 + 0 => JText::translate('VBNO'),
576 + ],
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 + ],
587 + 'roomextras' => [
588 + 'type' => 'select',
589 + 'label' => JText::translate('VBPEDITBUSYEXTRACOSTS'),
590 + 'options' => [
591 + 1 => JText::translate('VBYES'),
592 + 0 => JText::translate('VBNO'),
593 + ],
594 + ],
595 + ],
596 + // this native tool is rendered through a View
597 + 'rendering_type' => 'view',
598 + ],
599 + 'finance' => [
600 + 'name' => JText::translate('VBO_W_FINANCE_TITLE'),
601 + 'icon' => '<i class="' . VikBookingIcons::i('piggy-bank') . '"></i>',
602 + 'permissions' => [
603 + 'rooms' => [
604 + 'type' => 'listings',
605 + 'label' => JText::translate('VBOPERMTBLXROOMS'),
606 + 'multiple' => true,
607 + 'asset_options' => [
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 + ],
679 + ],
680 + ],
681 + // this native tool is rendered through a layout thanks to a callback
682 + 'rendering_type' => 'layout',
683 + 'rendering_callback' => function ($tool, $operator, $permissions, $tool_uri) {
684 + VikBooking::getOperatorInstance()->renderNativeToolLayout($tool, $operator, $permissions, $tool_uri);
685 + },
686 + ],
687 + ];
688 +
689 + /**
690 + * Trigger event to let other plugins register additional tools and permissions.
691 + * Custom operator tools do NOT need to define a rendering type or callback.
692 + *
693 + * @return array A list of custom tools and related permission types.
694 + */
695 + $custom_tools = VBOFactory::getPlatform()->getDispatcher()->filter('onLoadOperatorToolPermissionTypes');
696 +
697 + foreach ($custom_tools as $tool) {
698 + if (!is_array($tool)) {
699 + continue;
700 + }
701 + foreach ($tool as $tool_name => $tool_perms) {
702 + if (!is_numeric($tool_name) && is_array($tool_perms)) {
703 + // set valid tool, by also allowing to overwrite the default ones
704 + $this->toolPermissionTypes[$tool_name] = $tool_perms;
705 + }
706 + }
707 + }
708 +
709 + return $this->toolPermissionTypes;
710 + }
711 +}