PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.6
VikBooking Hotel Booking Engine & PMS v1.6.6
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 / libraries / adapter / html / html.php

html.php in VikBooking Hotel Booking Engine & PMS 1.6.6, at libraries/adapter/html/html.php

631 lines 16.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikWP - Libraries
4 * @subpackage adapter.html
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2023 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 /**
15 * Utility class for all HTML drawing classes.
16 *
17 * @since 10.0
18 */
19 abstract class JHtml
20 {
21 /**
22 * A list of callback functions.
23 *
24 * @var Callable[]
25 */
26 protected static $callbacks = array();
27
28 /**
29 * A list of loaded classes.
30 *
31 * @var array
32 */
33 protected static $loaded = array();
34
35 /**
36 * An array to hold included paths.
37 *
38 * @var array
39 * @since 10.1.29
40 */
41 protected static $includePaths = array();
42
43 /**
44 * The base folder containing the classes to load.
45 *
46 * @var string
47 */
48 public static $base = '';
49
50 /**
51 * Option values related to the generation of HTML output.
52 * Recognized options are:
53 *
54 * @property integer fmtDepth The current indent depth.
55 * @property string fmtEol The end of line string, default is linefeed.
56 * @property string fmtIndent The string to use for indentation, default is tab.
57 *
58 * @var array
59 * @since 10.1.16
60 */
61 public static $formatOptions = array(
62 'format.depth' => 0,
63 'format.eol' => "\n",
64 'format.indent' => "\t",
65 );
66
67 /**
68 * Helper method to call a function using a specific notation:
69 * [prefix].[filename].[function]
70 *
71 * For example: JView.helper.doSomething will call JViewHelper::doSomething().
72 * In case the prefix is missing, it will be used the default one: JHtml.
73 * In case also the file is missing, the system will try to call a
74 * function contained in the current class.
75 *
76 * @uses isRegistered()
77 * @uses extract()
78 * @uses loadFile()
79 * @uses register()
80 * @uses call()
81 */
82 public static function _($key)
83 {
84 // check if the key already owns a callback
85 if (!static::isRegistered($key))
86 {
87 // extract the data from the key
88 list($key, $prefix, $file, $func) = static::extract($key);
89
90 // the classname begins with the specified prefix (JHtml if not given)
91 $classname = ucwords($prefix);
92
93 // check if the file is set
94 if ($file)
95 {
96 // prepend the filename to the classname and load the file
97 $classname .= ucwords($file);
98
99 static::loadFile($file);
100 }
101
102 // once the file is loaded, we need to register the callback
103 static::register($key, array($classname, $func));
104 }
105
106 // obtain the list of specified arguments
107 $args = func_get_args();
108 // remove the $key from the arguments list
109 array_shift($args);
110
111 // dispatch the callback
112 return static::call($key, $args);
113 }
114
115 /**
116 * Proxy for underscore method.
117 * Needed to bypass the issue reported here:
118 * @link https://meta.trac.wordpress.org/ticket/3601
119 *
120 * @since 10.1.32 Renamed from `u`.
121 */
122 public static function fetch($key)
123 {
124 return call_user_func_array(array('JHtml', '_'), func_get_args());
125 }
126
127 /**
128 * Checks if there is a callback registered to the specified key.
129 *
130 * @param string $key The key to check for.
131 *
132 * @return boolean True if there is a callback, otherwise false.
133 */
134 public static function isRegistered($key)
135 {
136 return isset(static::$callbacks[$key]);
137 }
138
139 /**
140 * Method used to extract the prefix, the file and the function to call
141 * from a specified key (in dot notation).
142 *
143 * @param string $key The key describing the method to launch.
144 *
145 * @return array The array containing the prefix, the file and the function.
146 */
147 public static function extract($key)
148 {
149 // strip unexpected characters
150 $key = preg_replace("/[^a-z0-9_.]+/i", '', $key);
151
152 // check to see whether we need to load a helper file
153 $parts = explode('.', $key);
154
155 $prefix = count($parts) === 3 ? array_shift($parts) : 'JHtml';
156 $file = count($parts) === 2 ? array_shift($parts) : '';
157 $func = array_shift($parts);
158
159 return array(strtolower($prefix . '.' . $file . '.' . $func), $prefix, $file, $func);
160 }
161
162 /**
163 * Add a directory where JHtml should search for helpers.
164 * You may either pass a string or an array of directories.
165 *
166 * @param string $path A path to search.
167 *
168 * @return array An array with directory elements.
169 *
170 * @since 10.1.29
171 */
172 public static function addIncludePath($path = '')
173 {
174 // loop through the path directories
175 foreach ((array) $path as $dir)
176 {
177 if (!empty($dir) && !in_array($dir, static::$includePaths))
178 {
179 array_unshift(static::$includePaths, JPath::clean($dir));
180 }
181 }
182
183 return static::$includePaths;
184 }
185
186 /**
187 * Tries to load the given filename.
188 *
189 * @param string $file The file to load.
190 *
191 * @return void
192 */
193 public static function loadFile($file)
194 {
195 // search on default paths
196 $base = empty(static::$base) ? dirname(__FILE__) . DIRECTORY_SEPARATOR . 'classes' : $base;
197
198 // merge base path with include paths
199 $paths = array_merge(array($base), static::addIncludePath());
200
201 $found = false;
202
203 /**
204 * Since different plugins might include files with
205 * the same name, it is needed to scan and load all
206 * the files with the matching name.
207 *
208 * @since 10.1.30
209 */
210 foreach ($paths as $path)
211 {
212 // create path
213 $path = JPath::clean($path . DIRECTORY_SEPARATOR . $file . '.php');
214
215 // check whether we already loaded this file
216 if (!isset(static::$loaded[$path]))
217 {
218 // make sure the file exists
219 if (is_file($path))
220 {
221 // cache path as loaded
222 static::$loaded[$path] = 1;
223
224 // require the file
225 $found = (bool) require_once $path;
226 }
227 }
228 else
229 {
230 // already loaded
231 $found = true;
232 }
233 }
234
235 if (!$found)
236 {
237 // file not found, raise error
238 throw new Exception("JHtml [" . $file . "] helper class not found.", 404);
239 }
240 }
241
242 /**
243 * Registers a callback for the given key.
244 *
245 * @param string The key used to trigger the callback.
246 * @param Callable|array The callback function to run.
247 */
248 public static function register($key, $callback)
249 {
250 if (!is_callable($callback))
251 {
252 if (!is_array($callback))
253 {
254 $callback = array($callback);
255 }
256
257 throw new Exception('The callback [' . implode('::', $callback) . '()] is not callable.', 500);
258 }
259
260 static::$callbacks[$key] = $callback;
261 }
262
263 /**
264 * Executes the callback assigned to the specified key.
265 *
266 * @param string $key The callback key.
267 * @param array $args A list of arguments to pass.
268 *
269 * @param mixed The value returned by the callback.
270 *
271 * @uses isRegistered()
272 */
273 public static function call($key, array &$args = array())
274 {
275 if (!static::isRegistered($key))
276 {
277 return null;
278 }
279
280 return call_user_func_array(static::$callbacks[$key], $args);
281 }
282
283 /**
284 * Includes the specified script URI in the document <head>.
285 *
286 * @param string $uri The script URI.
287 * @param array $options Array of options. Example: array('version' => 'auto', 'conditional' => 'lt IE 9').
288 * @param array $attribs Array of attributes. Example: array('id' => 'scriptid', 'async' => 'async', 'data-test' => 1).
289 *
290 * @return void
291 */
292 public static function script($uri, $options = array(), $attribs = array())
293 {
294 $document = JFactory::getDocument();
295
296 // in case we don't have an array of options, create it
297 if (!is_array($options))
298 {
299 $options = array();
300 }
301
302 // in case we don't have an array of attributes, create it
303 if (!is_array($attribs))
304 {
305 $attribs = array();
306 }
307
308 // check if the script should be loaded as dependency
309 if (preg_match("/jquery-ui[0-9.\-]*\.min\.js$/", $uri))
310 {
311 $attribs['id'] = 'jquery-ui-datepicker';
312 // load datepicker jQuery UI add-on
313 $document->addScript(null, $options, $attribs);
314
315 $attribs['id'] = 'jquery-ui-dialog';
316 // load dialog jQuery UI add-on
317 $document->addScript(null, $options, $attribs);
318
319 if (JFactory::getApplication()->isSite())
320 {
321 $attribs['id'] = 'jquery-ui-tooltip';
322 // load tooltip jQuery UI add-on (site only)
323 $document->addScript(null, $options, $attribs);
324 }
325 }
326 else if (preg_match("/jquery[0-9.\-]*\.min\.js$/", $uri))
327 {
328 // do nothing, jQuery core is always loaded
329 }
330 else if (preg_match("/jquery-ui\.sortable\.min\.js$/", $uri))
331 {
332 $attribs['id'] = 'jquery-ui-sortable';
333 // load jQuery Sortable add-on
334 $document->addScript(null, $options, $attribs);
335 }
336 else if (preg_match("/jquery-ui\.slider\.min\.js$/", $uri))
337 {
338 $attribs['id'] = 'jquery-ui-slider';
339 // load jQuery Slider add-on
340 $document->addScript(null, $options, $attribs);
341 }
342 else
343 {
344 if (empty($attribs['id']) && preg_match("/maps\.googleapis\.com/", $uri))
345 {
346 $attribs['id'] = 'gmaps';
347 }
348
349 if (empty($attribs['id']))
350 {
351 /**
352 * Implemented lookup to avoid generating the same ID
353 * for files with the same name but placed in different
354 * positions for the plugin (e.g. site/admin).
355 *
356 * @since 10.1.30
357 */
358 static $lookup = array();
359
360 // extract last folder and file name from URI
361 if (preg_match("/([^\/\\\\]+)[\/\\\\]([^\/\\\\]+)\.js$/i", $uri, $match))
362 {
363 // make ID as unique as possible and strip unsupported chars
364 $attribs['id'] = preg_replace("/[^a-z0-9_-]/i", '', $match[1] . '-' . $match[2]);
365 }
366 else
367 {
368 // use uniq ID otherwise
369 $attribs['id'] = uniqid();
370 }
371
372 $cont = 1;
373
374 // iterate as long as the ID has been already registered
375 // and belongs to a different source URI
376 do
377 {
378 // create temporary ID
379 $tmp = $attribs['id'];
380
381 if ($cont > 1)
382 {
383 // append counter from 2 on
384 $tmp .= '-' . $cont;
385 }
386
387 // increase counter
388 $cont++;
389
390 } while (isset($lookup[$tmp]) && $lookup[$tmp] != $uri);
391
392 // re-assign ID
393 $attribs['id'] = $tmp;
394
395 // register ID within the cache lookup
396 $lookup[$attribs['id']] = $uri;
397 }
398
399 // load the custom script
400 $document->addScript($uri, $options, $attribs);
401 }
402 }
403
404 /**
405 * Includes the specified stylesheet URI in the document <head>.
406 *
407 * @param string $uri The style URI.
408 * @param array $options Array of options. Example: array('version' => 'auto', 'conditional' => 'lt IE 9').
409 * @param array $attribs Array of attributes. Example: array('id' => 'scriptid', 'async' => 'async', 'data-test' => 1).
410 *
411 * @return void
412 */
413 public static function stylesheet($uri, $options = array(), $attribs = array())
414 {
415 if (empty($attribs['id']))
416 {
417 /**
418 * Implemented lookup to avoid generating the same ID
419 * for files with the same name but placed in different
420 * positions for the plugin (e.g. site/admin).
421 *
422 * @since 10.1.30
423 */
424 static $lookup = array();
425
426 // use file basename as ID if not specified
427 $attribs['id'] = basename($uri);
428
429 // normalize ID attribute
430 $attribs['id'] = preg_replace("/[^a-zA-Z0-9\-_]+/", '-', $attribs['id']);
431
432 $cont = 1;
433
434 // iterate as long as the ID has been already registered
435 // and belongs to a different source URI
436 do
437 {
438 // create temporary ID
439 $tmp = $attribs['id'];
440
441 if ($cont > 1)
442 {
443 // append counter from 2 on
444 $tmp .= '-' . $cont;
445 }
446
447 // increase counter
448 $cont++;
449
450 } while (isset($lookup[$tmp]) && $lookup[$tmp] != $uri);
451
452 // re-assign ID
453 $attribs['id'] = $tmp;
454
455 // register ID within the cache lookup
456 $lookup[$attribs['id']] = $uri;
457 }
458
459 /**
460 * Added support for options and attributes.
461 *
462 * @since 10.1.27
463 */
464 JFactory::getDocument()->addStyleSheet($uri, $options, $attribs);
465 }
466
467 /**
468 * Displays a calendar control field.
469 *
470 * @param mixed $value The date value.
471 * @param string $name The name of the text field.
472 * @param string $id The id of the text field.
473 * @param string $format The date format.
474 * @param mixed $attribs Additional HTML attributes.
475 * The array can have the following keys:
476 * readonly Sets the readonly parameter for the input tag.
477 * disabled Sets the disabled parameter for the input tag.
478 * autofocus Sets the autofocus parameter for the input tag.
479 * autocomplete Sets the autocomplete parameter for the input tag.
480 * filter Sets the filter for the input tag.
481 *
482 * @return string HTML markup for a calendar field.
483 */
484 public static function calendar($value, $name, $id, $format = 'Y-m-d', $attribs = array())
485 {
486 $class = isset($attribs['class']) ? $attribs['class'] : '';
487 $showTime = isset($attribs['showTime']) ? $attribs['showTime'] : false;
488
489 unset($attribs['name']);
490 unset($attribs['id']);
491 unset($attribs['value']);
492 unset($attribs['class']);
493 unset($attribs['showTime']);
494
495 $str = '';
496 foreach ($attribs as $k => $v)
497 {
498 if (!strlen($v) || $v === true)
499 {
500 $v = $k;
501 }
502
503 $str .= $k . '="' . str_replace('"', '&quot;', $v) . '" ';
504 }
505
506 // make sure the format is compatible with the jQuery UI Datepicker
507 $format = str_replace('%', '', $format);
508
509 /**
510 * Add support for timestamp and JDate instances.
511 *
512 * @since 10.1.16
513 */
514 if (preg_match("/^\d+$/", $value))
515 {
516 // fetch timestamp
517 $value = date($format, $value);
518 }
519 else if ($value instanceof JDate)
520 {
521 /**
522 * Format string from JDate.
523 *
524 * @since 10.1.35 Always adjust to local timezone.
525 */
526 $value = $value->format($format, $locale = true);
527 }
528
529 $data = array();
530 $data['value'] = $value;
531 $data['name'] = $name;
532 $data['id'] = $id;
533 $data['class'] = $class;
534 $data['format'] = $format;
535 $data['attr'] = $str;
536 $data['showTime'] = $showTime;
537
538 JFactory::getDocument()->addScriptDeclaration(
539 <<<JS
540 jQuery(document).ready(function() {
541
542 var sel_format = "$format";
543 var df_separator = sel_format[1];
544
545 sel_format = sel_format.replace(new RegExp("\\\\"+df_separator, 'g'), "");
546
547 if (sel_format.match(/^Ymd/)) {
548 sel_format = "yy" + df_separator + "mm" + df_separator + "dd";
549 } else if (sel_format.match(/^mdY/)) {
550 sel_format = "mm" + df_separator + "dd" + df_separator + "yy";
551 } else {
552 sel_format = "dd" + df_separator + "mm" + df_separator + "yy";
553 }
554
555 jQuery('input[name="$name"]:input').datepicker({
556 dateFormat: sel_format,
557 });
558
559 jQuery('input[name="$name"]:input').next('i').click(function() {
560 jQuery('input[name="$name"]:input').focus();
561 });
562 });
563 JS
564 );
565
566 /**
567 * Render calendar layout.
568 * @note: this method should be registered by the plugin
569 * in order to use a custom layout.
570 */
571 return static::fetch('renderCalendar', $data);
572 }
573
574 /**
575 * Returns formatted date according to a given format and time zone.
576 *
577 * @param string $input String in a format accepted by date(), defaults to "now".
578 * @param string $format The date format specification string (see {@link PHP_MANUAL#date}).
579 * @param mixed $tz Time zone to be used for the date. Special cases: boolean true for global
580 * setting, boolean false for server setting.
581 *
582 * @return string A date translated by the given format and time zone.
583 */
584 public static function date($input = 'now', $format = null, $tz = true)
585 {
586 // UTC date converted to user time zone.
587 if ($tz === true)
588 {
589 // get a date object based on UTC
590 $date = JFactory::getDate($input, 'UTC');
591
592 // get global timezone setting
593 $global_tz = JFactory::getApplication()->get('offset', 'UTC');
594
595 // set the correct time zone based on the global configuration
596 $date->setTimezone(new DateTimeZone($global_tz));
597 }
598 // no date conversion (server timezone)
599 else if ($tz === null)
600 {
601 $date = JFactory::getDate($input);
602 }
603 // UTC date converted to given time zone.
604 else
605 {
606 // get a date object based on UTC.
607 $date = JFactory::getDate($input, 'UTC');
608
609 // set the correct time zone based on the specified string
610 $date->setTimezone(new DateTimeZone($tz));
611 }
612
613 // if no format is given use the default one
614 if (!$format)
615 {
616 $format = 'Y-m-d H:i:s';
617 }
618 /**
619 * Check whether the supplied format is a language definition.
620 *
621 * @since 10.1.35
622 */
623 else if (JFactory::getLanguage()->hasKey($format))
624 {
625 $format = JText::translate($format);
626 }
627
628 return $date->format($format, true);
629 }
630 }
631