PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / adapter / application.php
vikappointments / site / helpers / libraries / adapter Last commit date
bc 3 days ago platform 3 days ago version 3 days ago application.php 3 days ago bc.php 3 days ago index.html 3 days ago
application.php
1308 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 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 // this should be already loaded from autoload.php
15 VAPLoader::import('libraries.adapter.version.listener');
16
17 /**
18 * Helper class used to adapt the application to the requirements
19 * of the installed platform version.
20 *
21 * @see VersionListener Used to evaluate the current platform version.
22 *
23 * @since 1.0
24 * @since 1.7 Renamed from UIApplication.
25 */
26 #[\AllowDynamicProperties]
27 abstract class VAPApplication
28 {
29 /**
30 * The instance to handle the singleton.
31 *
32 * @var self
33 */
34 protected static $instance = null;
35
36 /**
37 * Used to keep a single instance of the object.
38 *
39 * @return self The class singleton.
40 */
41 public static function getInstance()
42 {
43 if (static::$instance === null)
44 {
45 // get current platform
46 $platform = VersionListener::getPlatform();
47
48 if (!$platform)
49 {
50 throw new Exception('Platform not supported', 404);
51 }
52
53 // try to include the application platform
54 if (!VAPLoader::import('libraries.adapter.platform.' . $platform))
55 {
56 throw new Exception(sprintf('Application [%s] not found', $platform), 404);
57 }
58
59 // define class name
60 $class = 'VAPApplication' . ucfirst($platform);
61
62 // check if the class exists and inherits VAPApplication abstraction
63 if (class_exists($class) && is_subclass_of($class, 'VAPApplication'))
64 {
65 static::$instance = new $class();
66 }
67 }
68
69 return static::$instance;
70 }
71
72 /**
73 * Backward compatibility for admin list <table> class.
74 *
75 * @return string The class selector to use.
76 */
77 abstract public function getAdminTableClass();
78
79 /**
80 * Backward compatibility for admin list <table> head opening.
81 *
82 * @return string The <thead> tag to use.
83 */
84 abstract public function openTableHead();
85
86 /**
87 * Backward compatibility for admin list <table> head closing.
88 *
89 * @return string The </thead> tag to use.
90 */
91 abstract public function closeTableHead();
92
93 /**
94 * Backward compatibility for admin list <th> class.
95 *
96 * @param string $align The additional class to use for horizontal alignment.
97 * Accepted rules should be: left, center or right.
98 *
99 * @return string The class selector to use.
100 */
101 abstract public function getAdminThClass($align = 'center');
102
103 /**
104 * Backward compatibility for admin list checkAll JS event.
105 *
106 * @param integer The total count of rows in the table.
107 *
108 * @return string The check all checkbox input to use.
109 */
110 abstract public function getAdminToggle($count);
111
112 /**
113 * Backward compatibility for admin list isChecked JS event.
114 *
115 * @return string The JS function to use.
116 */
117 abstract public function checkboxOnClick();
118
119 /**
120 * Helper method to send e-mails.
121 *
122 * @param string $from_address The e-mail address of the sender.
123 * @param string $from_name The name of the sender.
124 * @param string $to The e-mail address of the receiver.
125 * @param string $reply_address The reply to e-mail address.
126 * @param string $subject The subject of the e-mail.
127 * @param string $hmess The body of the e-mail (HTML is supported).
128 * @param array $attachments The list of the attachments to include.
129 * @param boolean $is_html True to support HTML body, otherwise false for plain text.
130 * @param string $encoding The encoding to use.
131 *
132 * @return boolean True if the e-mail was sent successfully, otherwise false.
133 */
134 abstract public function sendMail($from_address, $from_name, $to, $reply_address, $subject, $hmess, $attachments = null, $is_html = true, $encoding = 'base64');
135
136 /**
137 * Backward compatibility for add script.
138 *
139 * @param string $file Path to file.
140 * @param array $options Array of options. Example: array('version' => 'auto', 'conditional' => 'lt IE 9').
141 * @param array $attribs Array of attributes. Example: array('id' => 'scriptid', 'async' => 'async', 'data-test' => 1).
142 *
143 * @return void
144 */
145 abstract public function addScript($file = '', $options = array(), $attribs = array());
146
147 /**
148 * Backward compatibility for add stylesheet.
149 *
150 * @param string $file Path to file.
151 * @param array $options Array of options. Example: array('version' => 'auto', 'conditional' => 'lt IE 9').
152 * @param array $attribs Array of attributes. Example: array('id' => 'scriptid', 'async' => 'async', 'data-test' => 1).
153 *
154 * @return void
155 *
156 * @since 1.7
157 */
158 abstract public function addStylesheet($file = '', $options = array(), $attribs = array());
159
160 /**
161 * Backward compatibility for framework loading.
162 *
163 * @param string $fw The framework to load.
164 *
165 * @return void
166 */
167 abstract public function loadFramework($fw = '');
168
169 /**
170 * Backward compatibility for punycode conversion.
171 *
172 * @param string $mail The e-mail to convert in punycode.
173 *
174 * @return string The punycode conversion of the e-mail.
175 *
176 * @since 1.4
177 */
178 public function emailToPunycode($email = '')
179 {
180 // do nothing by default
181 return $email;
182 }
183
184 /**
185 * Helper method to build a input radio object.
186 *
187 * @param string $id The id of the input.
188 * @param string $label The text of the label.
189 * @param boolean $checked True if the input is checked.
190 * @param string $htmlAttr The additional html attributes to include.
191 *
192 * @return object The object to represent radio inputs.
193 *
194 * @since 1.2
195 */
196 public function initRadioElement($id = '', $label = '', $checked = false, $htmlAttr = '')
197 {
198 $elem = new stdClass();
199 $elem->id = $id;
200 $elem->label = $label;
201 $elem->checked = $checked;
202 $elem->htmlAttr = $htmlAttr;
203
204 return $elem;
205 }
206
207 /**
208 * Helper method to build a select <option> object.
209 *
210 * @param string $value The value of the option.
211 * @param string $label The text of the option.
212 * @param boolean $selected True if the option is selected.
213 * @param boolean $isoptgrp True if the option is a <optgroup> tag.
214 * @param boolean $disabled True if the option is disabled.
215 * @param string $htmlAttr The additional html attributes to include.
216 *
217 * @return object The object to represent select options.
218 *
219 * @since 1.2
220 */
221 public function initOptionElement($value, $label, $selected = false, $isoptgrp = false, $disabled = false, $htmlAttr = '')
222 {
223 $elem = new stdClass();
224 $elem->value = $value;
225 $elem->label = $label;
226 $elem->selected = $selected;
227 $elem->isoptgrp = $isoptgrp;
228 $elem->disabled = $disabled;
229 $elem->htmlAttr = $htmlAttr;
230
231 return $elem;
232 }
233
234 /**
235 * Helper method to build a select <optgroup> object.
236 *
237 * @param string $label The text of the optgroup.
238 *
239 * @return object The object to represent select optgroups.
240 *
241 * @uses initOptionElement() Create an optgroup starting from an option.
242 *
243 * @since 1.2
244 */
245 public function getDropdownGroup($label)
246 {
247 return $this->initOptionElement('', $label, 0, true);
248 }
249
250 /**
251 * Helper method to build a tiny YES/NO radio button.
252 *
253 * @param string $name The name of the input.
254 * @param object $elem_1 The first input object.
255 * @param object $elem_2 The second input object.
256 * @param boolean wrapped True if the input is wrapped in a control class, otherwise false..
257 *
258 * @return string The html to display.
259 *
260 * @since 1.2
261 */
262 public function radioYesNo($name, $elem_1, $elem_2, $wrapped = true, $layout = null)
263 {
264 $elements = array($elem_1, $elem_2);
265 $options = array('wrapped' => $wrapped);
266
267 //
268
269 if (!$layout)
270 {
271 // if not specified, get default layout from config
272 $layout = VAPFactory::getConfig()->get('uiradio', 'ios');
273 }
274
275 // load radio widget
276 VAPLoader::import('libraries.widget.radio.' . $layout);
277
278 $radio_class = 'UIRadio' . ucwords($layout);
279
280 //
281
282 $radio = new $radio_class($name, $elements, $options);
283
284 return $radio->display();
285 }
286
287 /**
288 * Helper method to build a normal HTML select.
289 *
290 * @param string $name The name of the select.
291 * @param array $elems The list containing all the option objects.
292 * @param string $id The ID attribute of the select.
293 * @param string $class The class attribute of the select.
294 * @param string htmlAttr The additional html attributes to include.
295 *
296 * @return string The html to display.
297 *
298 * @since 1.2
299 */
300 public function dropdown($name, $elems, $id = '', $class = '', $htmlAttr = '')
301 {
302 $first = true;
303 $select = '<select name="'.$name.'" id="'.$id.'" class="vik-dropdown '.$class.'" '.$htmlAttr.'>';
304
305 foreach ($elems as $elem)
306 {
307 if (!$elem->isoptgrp)
308 {
309 $selected = $elem->selected ? ' selected="selected"' : '';
310 $disabled = $elem->disabled ? ' disabled' : '';
311
312 $select .= '<option value="' . $elem->value . '"' . $selected . $disabled . ' ' . $elem->htmlAttr . '>' . $elem->label . '</option>';
313 }
314 else
315 {
316 if (!$first)
317 {
318 $select .= '</optgroup>';
319 }
320
321 $select .= '<optgroup label="' . $elem->label . '">';
322 $first = false;
323 }
324 }
325
326 if (!$first)
327 {
328 $select .= '</optgroup>';
329 }
330
331 $select .= '</select>';
332
333 return $select;
334 }
335
336 /**
337 * Backward compatibility for card/row opening.
338 *
339 * @param string $class The class attribute for the fieldset.
340 * @param string $id The ID attribute for the fieldset.
341 *
342 * @return string The html to display.
343 *
344 * @since 1.7
345 */
346 abstract public function openCard($class = '', $id = '');
347
348 /**
349 * Backward compatibility for card/row closing.
350 *
351 * @return string The html to display.
352 *
353 * @since 1.7
354 */
355 abstract public function closeCard();
356
357 /**
358 * Backward compatibility for fieldset opening.
359 *
360 * @param string $legend The title of the fieldset.
361 * @param string $class The class attribute for the fieldset.
362 * @param string $id The ID attribute for the fieldset.
363 *
364 * @return string The html to display.
365 *
366 * @since 1.3
367 */
368 abstract public function openFieldset($legend, $class = '', $id = '');
369
370 /**
371 * Backward compatibility for fieldset closing.
372 *
373 * @return string The html to display.
374 *
375 * @since 1.3
376 */
377 abstract public function closeFieldset();
378
379 /**
380 * Backward compatibility for empty fieldset opening.
381 *
382 * @param string $class An additional class to use for the fieldset.
383 * @param string $id The ID attribute for the fieldset.
384 *
385 * @return string The html to display.
386 *
387 * @since 1.3
388 */
389 abstract public function openEmptyFieldset($class = '', $id = '');
390
391 /**
392 * Backward compatibility for empty fieldset opening.
393 *
394 * @return string The html to display.
395 *
396 * @since 1.3
397 */
398 abstract public function closeEmptyFieldset();
399
400 /**
401 * Backward compatibility for control opening.
402 *
403 * @param string $label The label of the control field.
404 * @param string $class The class of the control field.
405 * @param mixed $attr The additional attributes to add (string or array).
406 *
407 * @return string The html to display.
408 *
409 * @since 1.3
410 */
411 abstract public function openControl($label, $class = '', $attr = '');
412
413 /**
414 * Backward compatibility for control closing.
415 *
416 * @return string The html to display.
417 *
418 * @since 1.3
419 */
420 abstract public function closeControl();
421
422 /**
423 * Returns the specified editor.
424 *
425 * @param mixed $editor The editor to load.
426 * The default one if not specified.
427 *
428 * @return JEditor The editor instance.
429 *
430 * @since 1.7
431 */
432 abstract public function getEditor($editor = null);
433
434 /**
435 * Returns the codemirror editor.
436 *
437 * @param string $name The name of the textarea.
438 * @param string $value The value of the textarea.
439 * @param array $params An array of options (@since 1.7).
440 *
441 * @return string The html to display.
442 *
443 * @since 1.4
444 */
445 abstract public function getCodeMirror($name, $value, array $params = array());
446
447 /**
448 * Prepares the editor scripts for being used.
449 *
450 * @param string $name The name of the editor.
451 *
452 * @return void
453 *
454 * @since 1.6.3
455 */
456 public function prepareEditor($name)
457 {
458 // do nothing by default
459 }
460
461 /**
462 * Backward compatibility for Bootstrap tabset opening.
463 *
464 * @param string $group The group of the tabset.
465 * @param string $attr The attributes to use.
466 *
467 * @return string The html to display.
468 *
469 * @since 1.4
470 */
471 abstract public function bootStartTabSet($group, $attr = array());
472
473 /**
474 * Backward compatibility for Bootstrap tabset closing.
475 *
476 * @return string The html to display.
477 *
478 * @since 1.4
479 */
480 abstract public function bootEndTabSet();
481
482 /**
483 * Backward compatibility for Bootstrap add tab.
484 *
485 * @param string $group The tabset parent group.
486 * @param string $id The id of the tab.
487 * @param string $label The title of the tab.
488 * @param array $options A list of options.
489 *
490 * @return string The html to display.
491 *
492 * @since 1.4
493 */
494 abstract public function bootAddTab($group, $id, $label, array $options = array());
495
496 /**
497 * Backward compatibility for Bootstrap end tab.
498 *
499 * @return string The html to display.
500 *
501 * @since 1.4
502 */
503 abstract public function bootEndTab();
504
505 /**
506 * Backward compatibility for Bootstrap open modal JS event.
507 *
508 * @param string $onclose The javascript function to call on close event.
509 *
510 * @return string The javascript function.
511 *
512 * @since 1.5
513 */
514 abstract public function bootOpenModalJS($onclose = '');
515
516 /**
517 * Backward compatibility for Bootstrap dismiss modal JS event.
518 *
519 * @param string $selector The selector to identify the modal box.
520 *
521 * @return string The javascript function.
522 *
523 * @since 1.5
524 */
525 abstract public function bootDismissModalJS($selector = null);
526
527 /**
528 * Backward compatibility to fit the layout of the left main menu.
529 *
530 * @param JDocument $document The base document.
531 *
532 * @since 1.5
533 */
534 public function fixContentPadding($document = null)
535 {
536
537 }
538
539 /**
540 * Add javascript support for Bootstrap popovers.
541 *
542 * @param string $selector Selector for the popover.
543 * @param array $options An array of options for the popover.
544 * Options for the popover can be:
545 * animation boolean apply a css fade transition to the popover
546 * html boolean Insert HTML into the popover. If false, jQuery's text method will be used to insert
547 * content into the dom.
548 * placement string|function how to position the popover - top | bottom | left | right
549 * selector string If a selector is provided, popover objects will be delegated to the specified targets.
550 * trigger string how popover is triggered - hover | focus | manual
551 * title string|function default title value if `title` tag isn't present
552 * content string|function default content value if `data-content` attribute isn't present
553 * delay number|object delay showing and hiding the popover (ms) - does not apply to manual trigger type
554 * If a number is supplied, delay is applied to both hide/show
555 * Object structure is: delay: { show: 500, hide: 100 }
556 * container string|boolean Appends the popover to a specific element: { container: 'body' }
557 *
558 * @since 1.6
559 */
560 abstract public function attachPopover($selector = '.vapPopover', array $options = array());
561
562 /**
563 * Create a standard tag and attach a popover event.
564 * NOTE. FontAwesome framework MUST be loaded in order to work.
565 *
566 * @param array $options An array of options for the popover.
567 *
568 * @see VAPApplication::attachPopover() for further details about options keys.
569 *
570 * @since 1.6
571 */
572 abstract public function createPopover(array $options = array());
573
574 /**
575 * Create a text span and attach a popover event.
576 *
577 * @param array $options An array of options for the popover.
578 *
579 * @see VAPApplication::attachPopover() for further details about options keys.
580 *
581 * @since 1.6
582 */
583 abstract public function textPopover(array $options = array());
584
585 /**
586 * Return the date format specs.
587 *
588 * @param string $format The format to use.
589 * @param array &$attributes Some attributes to use.
590 *
591 * @return string The adapted date format.
592 *
593 * @since 1.6
594 */
595 abstract public function jdateFormat($format = null, array &$attributes = array());
596
597 /**
598 * Provides support to handle the calendar across different frameworks.
599 *
600 * @param mixed $value The date or the timestamp to fill.
601 * @param string $name The input name.
602 * @param string $id The input id attribute.
603 * @param string $format The date format.
604 * @param array $attributes Some attributes to use.
605 *
606 * @return string The calendar field.
607 *
608 * @since 1.6
609 */
610 abstract public function calendar($value, $name, $id = null, $format = null, array $attributes = array());
611
612 /**
613 * Returns a masked e-mail address. The e-mail are masked using
614 * a technique to encode the bytes in hexadecimal representation.
615 * The chunk of the masked e-mail will be also encoded to be HTML readable.
616 *
617 * @param string $email The e-mail to mask.
618 * @param boolean $reverse True to reverse the e-mail address.
619 * Only if the e-mail is not contained into an attribute.
620 *
621 * @return string The masked e-mail address.
622 *
623 * @since 1.6
624 */
625 public function maskMail($email, $reverse = false)
626 {
627 if ($reverse)
628 {
629 // reverse the e-mail address
630 $email = strrev($email);
631 }
632
633 // converts the e-mail address from bin to hex
634 $email = bin2hex($email);
635 // append ;&#x sequence after every chunk of the masked e-mail
636 $email = chunk_split($email, 2, ";&#x");
637 // prepend &#x sequence before the address and trim the ending sequence
638 $email = "&#x" . substr($email, 0, -3);
639
640 return $email;
641 }
642
643 /**
644 * Returns a safemail tag to avoid the bots spoof a plain address.
645 *
646 * @param string $email The e-mail address to mask.
647 * @param boolean $mail_to True if the address should be wrapped
648 * within a "mailto" link.
649 *
650 * @return string The HTML tag containing the masked address.
651 *
652 * @uses maskMail()
653 *
654 * @since 1.6
655 */
656 public function safeMailTag($email, $mail_to = false)
657 {
658 // include the CSS declaration to reverse the text contained in the <safemail> tags
659 JFactory::getDocument()->addStyleDeclaration('safemail {direction: rtl;unicode-bidi: bidi-override;}');
660
661 // mask the reversed e-mail address
662 $masked = $this->maskMail($email, true);
663
664 // include the address into a custom <safemail> tag
665 $tag = "<safemail>$masked</safemail>";
666
667 if ($mail_to)
668 {
669 // mask the address for mailto command (do not use reverse)
670 $mailto = $this->maskMail($email);
671
672 // wrap the safemail tag within a mailto link
673 $tag = "<a href=\"mailto:$mailto\" class=\"mailto\">$tag</a>";
674 }
675
676 return $tag;
677 }
678
679 /**
680 * Method used to obtain a media form field.
681 *
682 * @return string The media in HTML.
683 *
684 * @since 1.6
685 */
686 abstract public function getMediaField($name, $value = null, array $data = array());
687
688 /**
689 * Method used to handle the reCAPTCHA events.
690 *
691 * @param string $event The reCAPTCHA event to trigger.
692 * Here's the list of the accepted events:
693 * - display Returns the HTML used to
694 * display the reCAPTCHA input.
695 * - check Validates the POST data to make sure
696 * the reCAPTCHA input was checked.
697 * @param array $options A configuration array.
698 *
699 * @return mixed The event response.
700 *
701 * @since 1.6
702 * @deprecated 1.8 Use captcha() instead.
703 */
704 abstract public function reCaptcha($event = 'display', array $options = array());
705
706 /**
707 * Method used to handle the CAPTCHA events.
708 *
709 * @param string $event The CAPTCHA event to trigger.
710 * Here's the list of the accepted events:
711 * - display Returns the HTML used to
712 * display the CAPTCHA input.
713 * - check Validates the POST data to make sure
714 * the CAPTCHA input was checked.
715 * @param array $options A configuration array.
716 *
717 * @return mixed The event response.
718 *
719 * @since 1.7.10
720 */
721 abstract public function captcha($event = 'display', array $options = []);
722
723 /**
724 * Checks if the com_user captcha is configured.
725 * In case the parameter is set to global, the default one
726 * will be retrieved.
727 *
728 * @param string $plugin The plugin name to check. Leave empty
729 * to use any type of captcha.
730 *
731 * @return boolean True if configured, otherwise false.
732 *
733 * @since 1.6
734 * @deprecated 1.8 Use getUserCaptcha() instead.
735 */
736 abstract public function isCaptcha($plugin = null);
737
738 /**
739 * Returns the configured captcha plugin for com_users component.
740 * In case the parameter is set to global, the default one will be retrieved.
741 *
742 * @return string|null The configured captcha, NULL otherwise.
743 *
744 * @since 1.7.10
745 */
746 abstract public function getUserCaptcha();
747
748 /**
749 * Checks if the global captcha is configured.
750 *
751 * @param string $plugin The plugin name to check. Leave empty
752 * to use any type of captcha.
753 *
754 * @return boolean True if configured, otherwise false.
755 *
756 * @since 1.6
757 * @deprecated 1.8 Use getGlobalCaptcha() instead.
758 */
759 abstract public function isGlobalCaptcha($plugin = null);
760
761 /**
762 * Returns the configured captcha plugin for global use.
763 *
764 * @return string|null The configured captcha, NULL otherwise.
765 *
766 * @since 1.7.10
767 */
768 abstract public function getGlobalCaptcha();
769
770 /**
771 * Rewrites an internal URI that needs to be used outside of the website.
772 * This means that the routed URI MUST start with the base path of the site.
773 *
774 * @param mixed $query The query string or an associative array of data.
775 * @param boolean $xhtml Replace & by &amp; for XML compliance.
776 * @param mixed $itemid The itemid to use. If null, the current one will be used.
777 *
778 * @return string The complete routed URI.
779 *
780 * @since 1.6
781 */
782 abstract public function routeForExternalUse($query = '', $xhtml = true, $itemid = null);
783
784 /**
785 * Routes an admin URL for being used outside from the website (complete URI).
786 *
787 * @param mixed $query The query string or an associative array of data.
788 * @param boolean $xhtml Replace & by &amp; for XML compliance.
789 *
790 * @return string The complete routed URI.
791 *
792 * @since 1.6.3
793 */
794 abstract public function adminUrl($query = '', $xhtml = true);
795
796 /**
797 * Prepares a plain/routed URL to be used for an AJAX request.
798 *
799 * @param mixed $query The query string or a routed URL.
800 * @param boolean $xhtml Replace & by &amp; for XML compliance.
801 *
802 * @return string The AJAX end-point URI.
803 *
804 * @since 1.7
805 */
806 abstract public function ajaxUrl($query = '', $xhtml = false);
807
808 /**
809 * Includes the CSRF-proof token within the specified query string/URL.
810 *
811 * @param mixed $query The query string or a routed URL.
812 * @param boolean $xhtml Replace & by &amp; for XML compliance.
813 *
814 * @return string The resulting path.
815 *
816 * @since 1.7
817 */
818 abstract public function addUrlCSRF($query = '', $xhtml = false);
819
820 /**
821 * Converts the given absolute path into a reachable URL.
822 *
823 * @param string $path The absolute path.
824 * @param boolean $relative True to receive a relative path.
825 *
826 * @return mixed The resulting URL on success, null otherwise.
827 *
828 * @since 1.7.1
829 */
830 public function getUrlFromPath($path, $relative = false)
831 {
832 // get platform base path
833 $base = $this->getAbsolutePath();
834
835 if (strpos($path, $base) !== 0)
836 {
837 // The path doesn't start with the base path of the site...
838 // Probably the path cannot be reached via URL.
839 return null;
840 }
841
842 // remove initial path
843 $path = str_replace($base, '', $path);
844 // remove initial directory separator
845 $path = preg_replace("/^[\/\\\\]/", '', $path);
846
847 if (DIRECTORY_SEPARATOR === '\\')
848 {
849 // replace Windows DS
850 $path = preg_replace("[\\\\]", '/', $path);
851 }
852
853 if ($relative)
854 {
855 return $path;
856 }
857
858 // rebuild URL
859 return JUri::root() . $path;
860 }
861
862 /**
863 * Returns the platform base path.
864 *
865 * @return string
866 *
867 * @since 1.7.1
868 */
869 abstract public function getAbsolutePath();
870
871 /**
872 * Returns an helper class suffix used to adjust the layout of the component
873 * depending on the theme used by the template (e.g. light or dark).
874 *
875 * @param mixed $suffix The rules to affect (array or string).
876 * Null to use all the existing rules.
877 * Here's the list of supported rules:
878 * - background used when it is needed to change the background color;
879 * - color used when it is needed to change the foreground color.
880 *
881 * @return string The string containing the classes to use.
882 *
883 * @since 1.6
884 */
885 public function getThemeClass($suffix = null)
886 {
887 // a list of allowed suffix
888 $lookup = array(
889 'background',
890 'color',
891 );
892
893 if (is_null($suffix))
894 {
895 // use all supported suffix
896 $suffix = $lookup;
897 }
898 else if (!is_array($suffix))
899 {
900 // use only the specified suffix
901 $suffix = array($suffix);
902 }
903
904 // get theme setting (light or dark)
905 $theme = VAPFactory::getConfig()->get('sitetheme', '');
906 $class = array();
907
908 if ($theme)
909 {
910 // iterate the specified list
911 foreach ($suffix as $tmp)
912 {
913 // if supported, push the class suffix within the list
914 if (in_array($tmp, $lookup))
915 {
916 $class[] = $theme . '-theme-' . $tmp;
917 }
918 }
919 }
920
921 // join the classes with a blank space
922 return implode(' ', $class);
923 }
924
925
926 /**
927 * Helper method to pre-load the assets needed for the Employee Area.
928 *
929 * @return void
930 *
931 * @since 1.6
932 */
933 public function loadEmployeeAreaAssets()
934 {
935 $document = JFactory::getDocument();
936 // css
937 $document->AddStyleSheet(VAPASSETS_URI . 'css/vap-emparea.css');
938 VikAppointments::load_font_awesome();
939
940 // js
941 VikAppointments::load_css_js();
942 VikAppointments::load_fancybox();
943 VikAppointments::load_complex_select();
944 VikAppointments::load_utils();
945 VikAppointments::load_currency_js();
946 $this->addScript(VAPASSETS_URI . 'js/jquery-ui.sortable.min.js');
947 $this->addScript(VAPASSETS_URI . 'js/vap-emparea.js');
948
949 /**
950 * Load administration language, since almost all the used texts are already defined.
951 *
952 * @since 1.7
953 */
954 VikAppointments::loadLanguage(JFactory::getLanguage()->getTag(), JPATH_ADMINISTRATOR);
955
956 /**
957 * Load administrator helpers.
958 *
959 * @since 1.7
960 */
961 JHtml::addIncludePath(VAPADMIN . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'html');
962
963 $document->addScriptDeclaration(
964 <<<JS
965 const EmployeeArea = new EmployeeAreaManager('#empareaForm');
966
967 jQuery(function() {
968 jQuery('.vap-list-pagination .hasTooltip').removeClass('hasTooltip').removeAttr('title').attr('data-original-title', '');
969 });
970 JS
971 );
972 }
973
974 /**
975 * Returns a list of users that are currently logged-in.
976 *
977 * @param mixed $limit The query limit, if specified.
978 * @param integer $offset The query offset, if specified.
979 *
980 * @return array A list of users.
981 *
982 * @since 1.6.3
983 */
984 abstract public function getLoggedUsers($limit = null, $offset = 0);
985
986 /**
987 * Prepares the specified content before being displayed.
988 *
989 * @param mixed &$content The table content instance.
990 * @param boolean &full True to return the full description.
991 * False to return the short description, if any.
992 *
993 * @return void
994 *
995 * @since 1.6.3
996 */
997 abstract public function onContentPrepare(&$content, $full = true);
998
999 /**
1000 * Returns a list of supported payment gateways.
1001 *
1002 * @return array A list of paths.
1003 *
1004 * @since 1.6.3
1005 */
1006 abstract public function getPaymentDrivers();
1007
1008 /**
1009 * Returns the configuration form of a payment.
1010 *
1011 * @param string $payment The name of the payment.
1012 *
1013 * @return mixed The configuration array/object.
1014 *
1015 * @since 1.6.3
1016 */
1017 abstract public function getPaymentConfig($payment);
1018
1019 /**
1020 * Provides a new payment instance for the specified arguments.
1021 *
1022 * @param string $payment The name of the payment that should be instantiated.
1023 * @param mixed $order The details of the order that has to be paid.
1024 * @param mixed $config The payment configuration array or a JSON string.
1025 *
1026 * @return mixed The payment instance.
1027 *
1028 * @throws RuntimeException
1029 *
1030 * @since 1.6.3
1031 */
1032 abstract public function getPaymentInstance($payment, $order = array(), $config = array());
1033
1034 /**
1035 * Checks whether the reservation can be completed.
1036 *
1037 * @return boolean
1038 *
1039 * @throws RuntimeException
1040 *
1041 * @since 1.6.3
1042 */
1043 abstract public function checkAvailability();
1044
1045 /**
1046 * Returns the component manufacturer name or link.
1047 * Children that inherits this method must pass the default values to
1048 * use to build the manufacturer name. This can be done by pushing within the
1049 * $options array the 'manufacturer' key, which should contain the following keys:
1050 * 'link', 'short' and 'long'.
1051 *
1052 * @param array $options An array of options:
1053 * - link (boolean) True to return a link, false to return the
1054 * name only (false by default);
1055 * - short (boolean) True to display the short manufacturer name,
1056 * false otherwise (false by default);
1057 * - long (boolean) True to display the long manufacturer name,
1058 * false otherwise (true by default);
1059 * - separator (string) A separator string to insert between the
1060 * names fetched ('-' by default).
1061 *
1062 * @return string The manufacturer name or link.
1063 *
1064 * @since 1.6.3
1065 */
1066 public function getManufacturer(array $options = array())
1067 {
1068 $defaults = array(
1069 'link' => false,
1070 'short' => false,
1071 'long' => true,
1072 'separator' => '-',
1073 );
1074
1075 // merge specified options within default values
1076 $options = array_merge($defaults, $options);
1077
1078 $parts = array();
1079
1080 // look for short name
1081 if ($options['short'] && isset($options['manufacturer']['short']))
1082 {
1083 $parts[] = $options['manufacturer']['short'];
1084 }
1085
1086 // look for long name
1087 if ($options['long'] && isset($options['manufacturer']['long']))
1088 {
1089 $parts[] = $options['manufacturer']['long'];
1090 }
1091
1092 // make sure the separator is not a blank space
1093 if (trim($options['separator']))
1094 {
1095 // add an empty space at the beginning and at the end
1096 $options['separator'] = ' ' . $options['separator'] . ' ';
1097 }
1098 else
1099 {
1100 // use an empty space otherwise
1101 $options['separator'] = ' ';
1102 }
1103
1104 if ($parts)
1105 {
1106 // implode the manufacturer chunks by using the specified separator
1107 $str = implode($options['separator'], $parts);
1108 }
1109 else if (isset($options['manufacturer']['link']))
1110 {
1111 // use the specified link as fallback
1112 $str = $options['manufacturer']['link'];
1113 }
1114 else
1115 {
1116 // return empty string as we don't have anything to display
1117 return '';
1118 }
1119
1120 // check if we should wrap the name within a link
1121 if ($options['link'])
1122 {
1123 // check if we have a custom link
1124 if (!is_string($options['link']))
1125 {
1126 // the link is not a string, use a default value
1127 if (isset($options['manufacturer']['link']))
1128 {
1129 $options['link'] = $options['manufacturer']['link'];
1130 }
1131 else
1132 {
1133 // do not use a link as we don't have a valid URI
1134 return $str;
1135 }
1136 }
1137
1138 // build HTML link tag
1139 $str = sprintf(
1140 '<a href="%s" target="_blank">%s</a>',
1141 $options['link'],
1142 $str
1143 );
1144 }
1145
1146 return $str;
1147 }
1148
1149 /**
1150 * Returns a list of site installed languages.
1151 *
1152 * @return array key/value pair with the language file and real name.
1153 *
1154 * @since 1.7
1155 */
1156 public function getKnownLanguages()
1157 {
1158 return JLanguage::getKnownLanguages();
1159 }
1160
1161 /**
1162 * Displays an inline alert message using the platform styles.
1163 *
1164 * @param string $text The text to display within the alert.
1165 * @param string $type The alert type.
1166 * @param boolean $dismissible True if the alert can be dismissed.
1167 * @param array $attributes An array of input attributes.
1168 *
1169 * @return string The HTML of the alert.
1170 *
1171 * @since 1.7
1172 */
1173 public function alert($text, $type = null, $dismissible = false, array $attributes = array())
1174 {
1175 // do not proceed in case the text is not empty
1176 if (empty($text))
1177 {
1178 return '';
1179 }
1180
1181 $app = JFactory::getApplication();
1182
1183 // fetch alert type
1184 $supportedTypes = array(
1185 'success',
1186 'error',
1187 'warning',
1188 'info',
1189 );
1190
1191 // make sure the type is supported
1192 if (!in_array($type, $supportedTypes))
1193 {
1194 // use warning by default
1195 $type = 'warning';
1196 }
1197
1198 $expdate = $id = null;
1199
1200 // check if the message is dismissible
1201 if ($dismissible)
1202 {
1203 // creates a unique key
1204 $id = md5($text);
1205
1206 // check if the cookie is currently dismissed
1207 if ($app->input->cookie->get('alert_dismiss_' . $id))
1208 {
1209 // do not display alert message
1210 return '';
1211 }
1212
1213 // check if a date string was passed
1214 if (is_string($dismissible))
1215 {
1216 try
1217 {
1218 // use date string as expiration
1219 $expdate = JFactory::getDate($dismissible);
1220 }
1221 catch (Exception $e)
1222 {
1223 // malformed string, keep hidden for 1 day
1224 $expdate = JFactory::getDate('+1 day');
1225 }
1226
1227 // format date for JS
1228 $expdate = $expdate->format('Y-m-d') . 'T' . $expdate->format('H:i:s');
1229 }
1230 }
1231
1232 // build display data
1233 $data = array(
1234 'text' => $text,
1235 'type' => $type,
1236 'dismiss' => (bool) $dismissible,
1237 'expdate' => $expdate,
1238 'id' => $id,
1239 'attrs' => $attributes,
1240 );
1241
1242 // display alert depending on current platform
1243 return $this->displayAlert($data);
1244 }
1245
1246 /**
1247 * Displays the platform alert.
1248 *
1249 * @param array $options The alert display data.
1250 *
1251 * @return string The HTML of the alert.
1252 *
1253 * @see alert()
1254 *
1255 * @since 1.7
1256 */
1257 abstract protected function displayAlert(array $data);
1258
1259 /**
1260 * Returns a list of supported SMS providers.
1261 *
1262 * @return array A list of paths.
1263 *
1264 * @since 1.7
1265 */
1266 abstract public function getSmsDrivers();
1267
1268 /**
1269 * Returns the configuration form of a SMS provider.
1270 *
1271 * @param string $driver The name of the driver.
1272 *
1273 * @return mixed The configuration array/object.
1274 *
1275 * @since 1.7
1276 */
1277 abstract public function getSmsConfig($driver);
1278
1279 /**
1280 * Provides a new SMS driver instance for the specified arguments.
1281 *
1282 * @param string $driver The name of the provider that should be instantiated.
1283 * If not specified, the default one will be used.
1284 * @param mixed $config The SMS configuration array or a JSON string.
1285 * @param mixed $order The details of the order that has to be notified.
1286 *
1287 * @return mixed The driver instance.
1288 *
1289 * @throws RuntimeException
1290 *
1291 * @since 1.7
1292 */
1293 abstract public function getSmsInstance($driver = null, $config = null, $order = array());
1294
1295 /**
1296 * Helper method used to set up the application according
1297 * to the current platform requirements.
1298 *
1299 * @return void
1300 *
1301 * @since 1.7
1302 */
1303 public function setup()
1304 {
1305 // inherits to implement setup procedures
1306 }
1307 }
1308