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 / html / vikappointments.php
vikappointments / site / helpers / libraries / html Last commit date
assets.php 3 days ago color.php 3 days ago countries.php 3 days ago index.html 3 days ago media.php 3 days ago site.php 3 days ago sitescripts.php 3 days ago status.php 3 days ago vikappointments.php 3 days ago
vikappointments.php
548 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 /**
15 * VikAppointments HTML global helper.
16 *
17 * @since 1.7
18 */
19 abstract class JHtmlVikAppointments
20 {
21 /**
22 * Converts a time expressed in minutes into hours and minutes.
23 * For example, the number '570' represents '9:30'.
24 *
25 * @param integer $ts The time in minutes.
26 * @param boolean $string True to return a formatted time.
27 * Otherwise an object will be returned.
28 * @param string $format The time format. If not specified, the
29 * default one will be used.
30 *
31 * @return mixed A formatted time.
32 */
33 public static function min2time($ts, $string = true, $format = null)
34 {
35 $time = new stdClass;
36
37 // extract hour and min from TS
38 $time->hour = floor($ts / 60);
39 $time->min = floor($ts % 60);
40
41 // fetch time format
42 $format = $format ? $format : VAPFactory::getConfig()->get('timeformat');
43
44 // format time
45 $time->format = date($format, mktime($time->hour, $time->min, 0, 1, 1, 2000));
46
47 if ($string)
48 {
49 // return formatted time
50 return $time->format;
51 }
52
53 // return detailed object
54 return $time;
55 }
56
57 /**
58 * Converts a time object in minutes.
59 * For example, the time '9:30' represents the number '570'.
60 *
61 * @param mixed $time The time object|string.
62 * @param property $property The object property to look for.
63 *
64 * @return integer The time in minutes.
65 */
66 public static function time2min($time, $property = 'value')
67 {
68 if (!is_scalar($time))
69 {
70 // extract time from object
71 $time = (object) $time;
72 $time = $time->{$property};
73 }
74
75 // extract hours and minutes from time
76 $hm = explode(':', $time);
77
78 return (int) $hm[0] * 60 + (int) $hm[1];
79 }
80
81 /**
82 * Returns an array of week days.
83 *
84 * @param boolean $short True to use the short text.
85 *
86 * @return array A list of days.
87 */
88 public static function days($short = false)
89 {
90 $options = array();
91
92 // create date
93 $date = JFactory::getDate();
94
95 // iterate week days
96 for ($day = 0; $day < 7; $day++)
97 {
98 // use JDate to extract the day name
99 $dayName = $date->dayToString($day, $short);
100 // push day within the list
101 $options[] = JHtml::fetch('select.option', $day, $dayName);
102 }
103
104 return $options;
105 }
106
107 /**
108 * Returns an array of years.
109 *
110 * @param integer $start The initial year.
111 * @param integer $end The ending year.
112 *
113 * @return array A list of years.
114 */
115 public static function years($start, $end)
116 {
117 $options = array();
118
119 if ($start <= 0)
120 {
121 $year = (int) date('Y');
122
123 $start = $year + $start;
124 $end = $year + $end;
125 }
126
127 // iterate years days
128 for ($start; $start <= $end; $start++)
129 {
130 // push year within the list
131 $options[] = JHtml::fetch('select.option', $start, $start);
132 }
133
134 return $options;
135 }
136
137 /**
138 * Returns an array of months.
139 *
140 * @param boolean $short True to use the short text.
141 *
142 * @return array A list of months.
143 */
144 public static function months($short = false)
145 {
146 $options = array();
147
148 // create date
149 $date = JFactory::getDate();
150
151 // iterate months
152 for ($month = 1; $month <= 12; $month++)
153 {
154 // use JDate to extract the month name
155 $monthName = $date->monthToString($month, $short);
156 // push month within the list
157 $options[] = JHtml::fetch('select.option', $month, $monthName);
158 }
159
160 return $options;
161 }
162
163 /**
164 * Returns a list of day hours.
165 *
166 * @return array A list of hours.
167 */
168 public static function hours()
169 {
170 $hours = array();
171
172 $format = VAPFactory::getConfig()->get('timeformat');
173 $format = preg_replace("/:i/", '', $format);
174
175 for ($h = 0; $h < 24; $h++)
176 {
177 $hf = self::min2time($h * 60, $string = true, $format);
178
179 $hours[] = JHtml::fetch('select.option', $h, $hf);
180 }
181
182 return $hours;
183 }
184
185 /**
186 * Returns a list of hour minutes.
187 *
188 * @param mixed $step The number of steps to use.
189 * If not specified, the number of steps will be retrieved from
190 * the configuration of the program.
191 *
192 * @return array A list of minutes.
193 */
194 public static function minutes($step = null)
195 {
196 $minutes = array();
197
198 if (!$step)
199 {
200 // retrieve step from configuration
201 $step = VAPFactory::getConfig()->getUint('minuteintervals');
202 }
203
204 // prevent infinite loop
205 $step = max(array($step, 1));
206
207 for ($m = 0; $m < 60; $m += $step)
208 {
209 $minutes[] = JHtml::fetch('select.option', $m, ($m < 10 ? '0' : '') . $m);
210 }
211
212 return $minutes;
213 }
214
215 /**
216 * Returns a list of times.
217 *
218 * @param array $options A configuration array. Here's a list of supports options:
219 * - step int The number of steps to use. If not specified,
220 * it will be retrieved from the configuration.
221 * - from mixed The initial time (in minutes). Use true to load
222 * the system opening time. Use false for 00:00.
223 * - to mixed The ending time (in minutes). Use true to load
224 * the system closing time. Use false for 00:00.
225 * - format string The time format to use. Leave empty to use
226 * the global one.
227 * - value string Use 'string' to use a 24h time as value.
228 * Use 'int' to represent the time in minutes.
229 *
230 * @return array A list of times.
231 */
232 public static function times($options = array())
233 {
234 $config = VAPFactory::getConfig();
235
236 if (isset($options['step']))
237 {
238 // prevent infinite loop
239 $options['step'] = max(array($options['step'], 1));
240 }
241 else
242 {
243 // retrieve step from configuration
244 $options['step'] = $config->getUint('minuteintervals');
245 }
246
247 if (isset($options['from']))
248 {
249 if ($options['from'] === true)
250 {
251 // get opening time from config
252 $from = VikAppointments::getOpeningTime();
253
254 // convert opening time in minutes
255 $options['from'] = $from['hour'] * 60 + $from['min'];
256 }
257 else
258 {
259 // validate bounds
260 $options['from'] = min(array(abs($options['from']), 1440));
261 }
262 }
263 else
264 {
265 // start from midnight
266 $options['from'] = 0;
267 }
268
269 if (isset($options['to']))
270 {
271 if ($options['to'] === true)
272 {
273 // get closing time to config
274 $to = VikAppointments::getClosingTime();
275
276 // convert closing time in minutes
277 $options['to'] = $to['hour'] * 60 + $to['min'];
278 }
279 else
280 {
281 // validate bounds
282 $options['to'] = min(array(abs($options['to']), 1440));
283 }
284 }
285 else
286 {
287 // end at midnight
288 $options['to'] = 1440;
289 }
290
291 if ($options['from'] > $options['to'])
292 {
293 // from time higher then end time, invert them
294 $tmp = $options['from'];
295 $options['from'] = $options['to'];
296 $options['to'] = $tmp;
297 }
298
299 if (empty($options['format']))
300 {
301 // use global one
302 $options['format'] = null;
303 }
304
305 $times = array();
306
307 for ($hm = $options['from']; $hm <= $options['to']; $hm += $options['step'])
308 {
309 // get time object
310 $time = static::min2time($hm, $string = false, $options['format']);
311
312 if (empty($options['value']) || $options['value'] == 'string')
313 {
314 // use 24h format as value
315 $value = $time->hour . ':' . $time->min;
316 }
317 else
318 {
319 // use minutes representation
320 $value = $hm;
321 }
322
323 // add time
324 $times[] = JHtml::fetch('select.option', $value, $time->format);
325 }
326
327 return $times;
328 }
329
330 /**
331 * Displays the rating of a review by printing
332 * the matched starts as image or through FontAwesome.
333 *
334 * FontAwesome is NOT loaded here.
335 *
336 * @param float $rating The rating amount (0-5).
337 * @param mixed $image True to use the images, false to use FA (v4).
338 * In case of a string, it will match FA version.
339 * @param boolean $missing True to display the missing stars, false to hide them.
340 *
341 * @return string The resulting HTML.
342 */
343 public static function rating($rating, $image = true, $missing = true)
344 {
345 $html = '';
346
347 if (!$image)
348 {
349 // in case of missing FontAwesome version, use the default one
350 $image = '5';
351 }
352
353 // display filled stars
354 for ($i = 1; $i <= $rating; $i++)
355 {
356 if ($image === true)
357 {
358 $html .= '<img src="' . VAPASSETS_URI . 'css/images/rating-star.png" class="vap-rating-star" />';
359 }
360 else
361 {
362 // look for a specific FontAwesome version
363 if (version_compare((string) $image, '5', '>='))
364 {
365 // use FA 5
366 $class = 'fas fa-star';
367 }
368 else
369 {
370 // use FA 4
371 $class = 'fa fa-star';
372 }
373
374 $html .= '<i class="' . $class . '"></i>';
375 }
376 }
377
378 // display half star
379 if (round($rating) != $rating)
380 {
381 if ($image === true)
382 {
383 $html .= '<img src="' . VAPASSETS_URI . 'css/images/rating-star-middle.png" class="vap-rating-star" />';
384 }
385 else
386 {
387 // look for a specific FontAwesome version
388 if (version_compare((string) $image, '5', '>='))
389 {
390 // use FA 5
391 $class = 'fas fa-star-half-alt';
392 }
393 else
394 {
395 // use FA 4
396 $class = 'fa fa-star-half-o';
397 }
398
399 $html .= '<i class="' . $class . '"></i>';
400 }
401 }
402
403 // display missing stars
404 if ($missing)
405 {
406 for ($i = round($rating) + 1; $i <= 5; $i++)
407 {
408 if ($image === true)
409 {
410 $html .= '<img src="' . VAPASSETS_URI . 'css/images/rating-star-no.png" class="vap-rating-star" />';
411 }
412 else
413 {
414 // look for a specific FontAwesome version
415 if (version_compare((string) $image, '5', '>='))
416 {
417 // use FA 5
418 $class = 'far fa-star';
419 }
420 else
421 {
422 // use FA 4
423 $class = 'fa fa-star-o';
424 }
425
426 $html .= '<i class="' . $class . '"></i>';
427 }
428 }
429 }
430
431 return $html;
432 }
433
434 /**
435 * Returns the HTML used to display a tag.
436 *
437 * @param mixed $tag Either a ID or a tag name or the object/array itself.
438 * @param string $layout The type of layout to use.
439 * @param array $attrs A list of tag attributes.
440 *
441 * @return string The HTML of the tag.
442 */
443 public static function tag($tag, $layout = 'badge', array $attrs = array())
444 {
445 if (is_scalar($tag))
446 {
447 $model = JModelVAP::getInstance('tag');
448
449 if (preg_match("/^\d+$/", $tag))
450 {
451 // load tag by ID, to take advantage of the cache
452 $tag = $model->readTags((int) $tag);
453 }
454 else
455 {
456 // load tag by name
457 $tag = $model->getItem(array('name' => $tag));
458 }
459
460 if (!$tag)
461 {
462 // tag not found
463 return '';
464 }
465 }
466 else
467 {
468 // cast to object
469 $tag = (object) $tag;
470 }
471
472 // instantiate layout file
473 $layout = new JLayoutFile('tag.' . $layout);
474
475 // build layout data
476 $data = array(
477 'tag' => $tag,
478 'attrs' => $attrs,
479 );
480
481 // display layout
482 return $layout->render($data);
483 }
484
485 /**
486 * Calculates the maximum upload file size and returns string with unit or the size in bytes.
487 *
488 * @param bool $unitOutput This parameter determines whether the return value
489 * should be a string with a unit.
490 *
491 * @return float|string The maximum upload size of files with the appropriate unit or in bytes.
492 *
493 * @since 1.7.3
494 */
495 public static function maxuploadsize($unitOutput = true)
496 {
497 static $max_size = false;
498
499 if ($max_size === false)
500 {
501 $max_size = self::parseSize(ini_get('post_max_size'));
502 $upload_max = self::parseSize(ini_get('upload_max_filesize'));
503
504 // check what is the highest value between post and upload max sizes
505 if ($upload_max > 0 && ($upload_max < $max_size || $max_size == 0))
506 {
507 $max_size = $upload_max;
508 }
509 }
510
511 if (!$unitOutput)
512 {
513 // return numerical max size
514 return $max_size;
515 }
516
517 // format max size
518 return JHtml::fetch('number.bytes', $max_size, 'auto', 0);
519 }
520
521 /**
522 * Returns the size in bytes without the unit for the comparison.
523 *
524 * @param string $size The size which is received from the PHP settings.
525 *
526 * @return float The size in bytes without the unit.
527 *
528 * @since 1.7.3
529 */
530 private static function parseSize($size)
531 {
532 // extract the size unit
533 $unit = preg_replace('/[^bkmgtpezy]/i', '', $size);
534 // take only the size numbers
535 $size = preg_replace('/[^0-9\.]/', '', $size);
536
537 $return = round($size);
538
539 if ($unit)
540 {
541 // calculate the correct size according to the specified unit
542 $return = round($size * pow(1024, stripos('bkmgtpezy', $unit[0])));
543 }
544
545 return $return;
546 }
547 }
548