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 | libraries/adapter/html/classes/select.php +499 -0 1.6.1 → 1.8.16 View file →
@@ -1,0 +1,499 @@
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 +JLoader::import('adapter.utilities.array');
15 +
16 +/**
17 + * Utility class for creating HTML select lists.
18 + *
19 + * @since 10.1.16
20 + */
21 +abstract class JHtmlSelect
22 +{
23 + /**
24 + * Default values for options. Organized by option group.
25 + *
26 + * @var array
27 + */
28 + protected static $optionDefaults = array(
29 + 'option' => array(
30 + 'option.attr' => null,
31 + 'option.disable' => 'disable',
32 + 'option.id' => null,
33 + 'option.key' => 'value',
34 + 'option.key.toHtml' => true,
35 + 'option.label' => null,
36 + 'option.label.toHtml' => true,
37 + 'option.text' => 'text',
38 + 'option.text.toHtml' => true,
39 + 'option.class' => 'class',
40 + 'option.onclick' => 'onclick',
41 + ),
42 + );
43 +
44 + /**
45 + * Generates a grouped HTML selection list from nested arrays.
46 + *
47 + * @param array $data An array of groups, each of which is an array of options.
48 + * @param string $name The value of the HTML name attribute
49 + * @param array $options Options, an array of key/value pairs. Valid options are:
50 + * Format options.
51 + * Selection options. See {@see JHtmlSelect::options()}.
52 + * group.id: The property in each group to use as the group id
53 + * attribute. Defaults to none.
54 + * group.label: The property in each group to use as the group
55 + * label. Defaults to "text". If set to null, the data array index key is
56 + * used.
57 + * group.items: The property in each group to use as the array of
58 + * items in the group. Defaults to "items". If set to null, group.id and
59 + * group. label are forced to null and the data element is assumed to be a
60 + * list of selections.
61 + * id: Value to use as the select element id attribute. Defaults to
62 + * the same as the name.
63 + * list.attr: Attributes for the select element. Can be a string or
64 + * an array of key/value pairs. Defaults to none.
65 + * list.select: either the value of one selected option or an array
66 + * of selected options. Default: none.
67 + * list.translate: Boolean. If set, text and labels are translated via
68 + * JText::translate().
69 + *
70 + * @return string HTML for the select list
71 + *
72 + * @throws RuntimeException If a group has contents that cannot be processed.
73 + */
74 + public static function groupedlist($data, $name, $options = array())
75 + {
76 + // Set default options and overwrite with anything passed in
77 + $options = array_merge(
78 + JHtml::$formatOptions,
79 + array('format.depth' => 0, 'group.items' => 'items', 'group.label' => 'text', 'group.label.toHtml' => true, 'id' => false),
80 + $options
81 + );
82 +
83 + // Apply option rules
84 + if ($options['group.items'] === null)
85 + {
86 + $options['group.label'] = null;
87 + }
88 +
89 + $attribs = '';
90 +
91 + if (isset($options['list.attr']))
92 + {
93 + if (is_array($options['list.attr']))
94 + {
95 + $attribs = ArrayHelper::toString($options['list.attr']);
96 + }
97 + else
98 + {
99 + $attribs = $options['list.attr'];
100 + }
101 +
102 + if ($attribs !== '')
103 + {
104 + $attribs = ' ' . $attribs;
105 + }
106 + }
107 +
108 + $id = $options['id'] !== false ? $options['id'] : $name;
109 + $id = str_replace(array('[', ']', ' '), '', $id);
110 +
111 + // Disable groups in the options.
112 + $options['groups'] = false;
113 +
114 + $baseIndent = str_repeat($options['format.indent'], $options['format.depth']++);
115 + $html = $baseIndent . '<select' . ($id !== '' ? ' id="' . $id . '"' : '') . ' name="' . $name . '"' . $attribs . '>' . $options['format.eol'];
116 + $groupIndent = str_repeat($options['format.indent'], $options['format.depth']++);
117 +
118 + foreach ($data as $dataKey => $group)
119 + {
120 + $label = $dataKey;
121 + $id = '';
122 + $noGroup = is_int($dataKey);
123 +
124 + if ($options['group.items'] == null)
125 + {
126 + // Sub-list is an associative array
127 + $subList = $group;
128 + }
129 + elseif (is_array($group))
130 + {
131 + // Sub-list is in an element of an array.
132 + $subList = $group[$options['group.items']];
133 +
134 + if (isset($group[$options['group.label']]))
135 + {
136 + $label = $group[$options['group.label']];
137 + $noGroup = false;
138 + }
139 +
140 + if (isset($options['group.id']) && isset($group[$options['group.id']]))
141 + {
142 + $id = $group[$options['group.id']];
143 + $noGroup = false;
144 + }
145 + }
146 + elseif (is_object($group))
147 + {
148 + // Sub-list is in a property of an object
149 + $subList = $group->{$options['group.items']};
150 +
151 + if (isset($group->{$options['group.label']}))
152 + {
153 + $label = $group->{$options['group.label']};
154 + $noGroup = false;
155 + }
156 +
157 + if (isset($options['group.id']) && isset($group->{$options['group.id']}))
158 + {
159 + $id = $group->{$options['group.id']};
160 + $noGroup = false;
161 + }
162 + }
163 + else
164 + {
165 + throw new RuntimeException('Invalid group contents.', 1);
166 + }
167 +
168 + if ($noGroup)
169 + {
170 + $html .= static::options($subList, $options);
171 + }
172 + else
173 + {
174 + $html .= $groupIndent . '<optgroup' . (empty($id) ? '' : ' id="' . $id . '"') . ' label="'
175 + . ($options['group.label.toHtml'] ? htmlspecialchars($label, ENT_COMPAT, 'UTF-8') : $label) . '">' . $options['format.eol']
176 + . static::options($subList, $options) . $groupIndent . '</optgroup>' . $options['format.eol'];
177 + }
178 + }
179 +
180 + $html .= $baseIndent . '</select>' . $options['format.eol'];
181 +
182 + return $html;
183 + }
184 +
185 + /**
186 + * Create an object that represents an option in an option list.
187 + *
188 + * @param string $value The value of the option
189 + * @param string $text The text for the option
190 + * @param mixed $optKey If a string, the returned object property name for
191 + * the value. If an array, options. Valid options are:
192 + * attr: String|array. Additional attributes for this option.
193 + * Defaults to none.
194 + * disable: Boolean. If set, this option is disabled.
195 + * label: String. The value for the option label.
196 + * option.attr: The property in each option array to use for
197 + * additional selection attributes. Defaults to none.
198 + * option.disable: The property that will hold the disabled state.
199 + * Defaults to "disable".
200 + * option.key: The property that will hold the selection value.
201 + * Defaults to "value".
202 + * option.label: The property in each option array to use as the
203 + * selection label attribute. If a "label" option is provided, defaults to
204 + * "label", if no label is given, defaults to null (none).
205 + * option.text: The property that will hold the the displayed text.
206 + * Defaults to "text". If set to null, the option array is assumed to be a
207 + * list of displayable scalars.
208 + * @param string $optText The property that will hold the the displayed text. This
209 + * parameter is ignored if an options array is passed.
210 + * @param boolean $disable Not used.
211 + *
212 + * @return stdClass
213 + */
214 + public static function option($value, $text = '', $optKey = 'value', $optText = 'text', $disable = false)
215 + {
216 + $options = array(
217 + 'attr' => null,
218 + 'disable' => false,
219 + 'option.attr' => null,
220 + 'option.disable' => 'disable',
221 + 'option.key' => 'value',
222 + 'option.label' => null,
223 + 'option.text' => 'text',
224 + );
225 +
226 + if (is_array($optKey))
227 + {
228 + // Merge in caller's options
229 + $options = array_merge($options, $optKey);
230 + }
231 + else
232 + {
233 + // Get options from the parameters
234 + $options['option.key'] = $optKey;
235 + $options['option.text'] = $optText;
236 + $options['disable'] = $disable;
237 + }
238 +
239 + $obj = new stdClass;
240 + $obj->{$options['option.key']} = $value;
241 + $obj->{$options['option.text']} = trim($text) ? $text : $value;
242 +
243 + /*
244 + * If a label is provided, save it. If no label is provided and there is
245 + * a label name, initialise to an empty string.
246 + */
247 + $hasProperty = $options['option.label'] !== null;
248 +
249 + if (isset($options['label']))
250 + {
251 + $labelProperty = $hasProperty ? $options['option.label'] : 'label';
252 + $obj->$labelProperty = $options['label'];
253 + }
254 + elseif ($hasProperty)
255 + {
256 + $obj->{$options['option.label']} = '';
257 + }
258 +
259 + // Set attributes only if there is a property and a value
260 + if ($options['attr'] !== null)
261 + {
262 + $obj->{$options['option.attr']} = $options['attr'];
263 + }
264 +
265 + // Set disable only if it has a property and a value
266 + if ($options['disable'] !== null)
267 + {
268 + $obj->{$options['option.disable']} = $options['disable'];
269 + }
270 +
271 + return $obj;
272 + }
273 +
274 + /**
275 + * Generates the option tags for an HTML select list (with no select tag
276 + * surrounding the options).
277 + *
278 + * @param array $arr An array of objects, arrays, or values.
279 + * @param mixed $optKey If a string, this is the name of the object variable for
280 + * the option value. If null, the index of the array of objects is used. If
281 + * an array, this is a set of options, as key/value pairs. Valid options are:
282 + * -Format options.
283 + * -groups: Boolean. If set, looks for keys with the value
284 + * "&lt;optgroup>" and synthesizes groups from them. Deprecated. Defaults
285 + * true for backwards compatibility.
286 + * -list.select: either the value of one selected option or an array
287 + * of selected options. Default: none.
288 + * -list.translate: Boolean. If set, text and labels are translated via
289 + * JText::translate(). Default is false.
290 + * -option.id: The property in each option array to use as the
291 + * selection id attribute. Defaults to none.
292 + * -option.key: The property in each option array to use as the
293 + * selection value. Defaults to "value". If set to null, the index of the
294 + * option array is used.
295 + * -option.label: The property in each option array to use as the
296 + * selection label attribute. Defaults to null (none).
297 + * -option.text: The property in each option array to use as the
298 + * displayed text. Defaults to "text". If set to null, the option array is
299 + * assumed to be a list of displayable scalars.
300 + * -option.attr: The property in each option array to use for
301 + * additional selection attributes. Defaults to none.
302 + * -option.disable: The property that will hold the disabled state.
303 + * Defaults to "disable".
304 + * -option.key: The property that will hold the selection value.
305 + * Defaults to "value".
306 + * -option.text: The property that will hold the the displayed text.
307 + * Defaults to "text". If set to null, the option array is assumed to be a
308 + * list of displayable scalars.
309 + * @param string $optText The name of the object variable for the option text.
310 + * @param mixed $selected The key that is selected (accepts an array or a string)
311 + * @param boolean $translate Translate the option values.
312 + *
313 + * @return string HTML for the select list.
314 + */
315 + public static function options($arr, $optKey = 'value', $optText = 'text', $selected = null, $translate = false)
316 + {
317 + $options = array_merge(
318 + JHtml::$formatOptions,
319 + static::$optionDefaults['option'],
320 + array('format.depth' => 0, 'groups' => true, 'list.select' => null, 'list.translate' => false)
321 + );
322 +
323 + if (is_array($optKey))
324 + {
325 + // Set default options and overwrite with anything passed in
326 + $options = array_merge($options, $optKey);
327 + }
328 + else
329 + {
330 + // Get options from the parameters
331 + $options['option.key'] = $optKey;
332 + $options['option.text'] = $optText;
333 + $options['list.select'] = $selected;
334 + $options['list.translate'] = $translate;
335 + }
336 +
337 + $html = '';
338 + $baseIndent = str_repeat($options['format.indent'], $options['format.depth']);
339 +
340 + foreach ($arr as $elementKey => &$element)
341 + {
342 + $attr = '';
343 + $extra = '';
344 + $label = '';
345 + $id = '';
346 +
347 + if (is_array($element))
348 + {
349 + $key = $options['option.key'] === null ? $elementKey : $element[$options['option.key']];
350 + $text = $element[$options['option.text']];
351 +
352 + if (isset($element[$options['option.attr']]))
353 + {
354 + $attr = $element[$options['option.attr']];
355 + }
356 +
357 + if (isset($element[$options['option.id']]))
358 + {
359 + $id = $element[$options['option.id']];
360 + }
361 +
362 + if (isset($element[$options['option.label']]))
363 + {
364 + $label = $element[$options['option.label']];
365 + }
366 +
367 + if (isset($element[$options['option.disable']]) && $element[$options['option.disable']])
368 + {
369 + $extra .= ' disabled="disabled"';
370 + }
371 + }
372 + elseif (is_object($element))
373 + {
374 + $key = $options['option.key'] === null ? $elementKey : $element->{$options['option.key']};
375 + $text = $element->{$options['option.text']};
376 +
377 + if (isset($element->{$options['option.attr']}))
378 + {
379 + $attr = $element->{$options['option.attr']};
380 + }
381 +
382 + if (isset($element->{$options['option.id']}))
383 + {
384 + $id = $element->{$options['option.id']};
385 + }
386 +
387 + if (isset($element->{$options['option.label']}))
388 + {
389 + $label = $element->{$options['option.label']};
390 + }
391 +
392 + if (isset($element->{$options['option.disable']}) && $element->{$options['option.disable']})
393 + {
394 + $extra .= ' disabled="disabled"';
395 + }
396 +
397 + if (isset($element->{$options['option.class']}) && $element->{$options['option.class']})
398 + {
399 + $extra .= ' class="' . $element->{$options['option.class']} . '"';
400 + }
401 +
402 + if (isset($element->{$options['option.onclick']}) && $element->{$options['option.onclick']})
403 + {
404 + $extra .= ' onclick="' . $element->{$options['option.onclick']} . '"';
405 + }
406 + }
407 + else
408 + {
409 + // This is a simple associative array
410 + $key = $elementKey;
411 + $text = $element;
412 + }
413 +
414 + /*
415 + * The use of options that contain optgroup HTML elements was
416 + * somewhat hacked for J1.5. J1.6 introduces the grouplist() method
417 + * to handle this better. The old solution is retained through the
418 + * "groups" option, which defaults true in J1.6, but should be
419 + * deprecated at some point in the future.
420 + */
421 +
422 + $key = (string) $key;
423 +
424 + if ($key === '<OPTGROUP>' && $options['groups'])
425 + {
426 + $html .= $baseIndent . '<optgroup label="' . ($options['list.translate'] ? JText::translate($text) : $text) . '">' . $options['format.eol'];
427 + $baseIndent = str_repeat($options['format.indent'], ++$options['format.depth']);
428 + }
429 + elseif ($key === '</OPTGROUP>' && $options['groups'])
430 + {
431 + $baseIndent = str_repeat($options['format.indent'], --$options['format.depth']);
432 + $html .= $baseIndent . '</optgroup>' . $options['format.eol'];
433 + }
434 + else
435 + {
436 + // If no string after hyphen - take hyphen out
437 + $splitText = explode(' - ', $text, 2);
438 + $text = $splitText[0];
439 +
440 + if (isset($splitText[1]) && $splitText[1] !== '' && !preg_match('/^[\s]+$/', $splitText[1]))
441 + {
442 + $text .= ' - ' . $splitText[1];
443 + }
444 +
445 + if (!empty($label) && $options['list.translate'])
446 + {
447 + $label = JText::translate($label);
448 + }
449 +
450 + if ($options['option.label.toHtml'])
451 + {
452 + $label = htmlentities($label);
453 + }
454 +
455 + if (is_array($attr))
456 + {
457 + $attr = ArrayHelper::toString($attr);
458 + }
459 + else
460 + {
461 + $attr = trim($attr);
462 + }
463 +
464 + $extra = ($id ? ' id="' . $id . '"' : '') . ($label ? ' label="' . $label . '"' : '') . ($attr ? ' ' . $attr : '') . $extra;
465 +
466 + if (is_array($options['list.select']))
467 + {
468 + foreach ($options['list.select'] as $val)
469 + {
470 + $key2 = is_object($val) ? $val->{$options['option.key']} : $val;
471 +
472 + if ($key == $key2)
473 + {
474 + $extra .= ' selected="selected"';
475 + break;
476 + }
477 + }
478 + }
479 + elseif ((string) $key === (string) $options['list.select'])
480 + {
481 + $extra .= ' selected="selected"';
482 + }
483 +
484 + if ($options['list.translate'])
485 + {
486 + $text = JText::translate($text);
487 + }
488 +
489 + // Generate the option, encoding as required
490 + $html .= $baseIndent . '<option value="' . ($options['option.key.toHtml'] ? htmlspecialchars($key, ENT_COMPAT, 'UTF-8') : $key) . '"'
491 + . $extra . '>';
492 + $html .= $options['option.text.toHtml'] ? htmlentities(html_entity_decode($text, ENT_COMPAT, 'UTF-8'), ENT_COMPAT, 'UTF-8') : $text;
493 + $html .= '</option>' . $options['format.eol'];
494 + }
495 + }
496 +
497 + return $html;
498 + }
499 +}