PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / trunk
Matomo Analytics – Powerful, Privacy-First Insights for WordPress vtrunk
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / libs / HTML / QuickForm2 / Element / Select.php
matomo / app / libs / HTML / QuickForm2 / Element Last commit date
Button.php 2 years ago Date.php 2 years ago Input.php 2 years ago InputButton.php 2 years ago InputCheckable.php 2 years ago InputCheckbox.php 2 years ago InputFile.php 1 year ago InputHidden.php 2 years ago InputImage.php 2 years ago InputPassword.php 2 years ago InputRadio.php 2 years ago InputReset.php 2 years ago InputSubmit.php 2 years ago InputText.php 2 years ago Select.php 2 years ago Static.php 2 years ago Textarea.php 2 years ago
Select.php
505 lines
1 <?php
2
3 namespace {
4 /**
5 * Classes for <select> elements
6 *
7 * PHP version 5
8 *
9 * LICENSE:
10 *
11 * Copyright (c) 2006-2010, Alexey Borzov <avb@php.net>,
12 * Bertrand Mansion <golgote@mamasam.com>
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * * Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * * The names of the authors may not be used to endorse or promote products
25 * derived from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
28 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
31 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
35 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 * @category HTML
40 * @package HTML_QuickForm2
41 * @author Alexey Borzov <avb@php.net>
42 * @author Bertrand Mansion <golgote@mamasam.com>
43 * @license http://opensource.org/licenses/bsd-license.php New BSD License
44 * @version SVN: $Id: Select.php 300722 2010-06-24 10:15:52Z mansion $
45 * @link http://pear.php.net/package/HTML_QuickForm2
46 */
47 /**
48 * Base class for simple HTML_QuickForm2 elements
49 */
50 // require_once 'HTML/QuickForm2/Element.php';
51 /**
52 * Implements a recursive iterator for options arrays
53 *
54 * @category HTML
55 * @package HTML_QuickForm2
56 * @author Alexey Borzov <avb@php.net>
57 * @author Bertrand Mansion <golgote@mamasam.com>
58 * @version Release: @package_version@
59 */
60 class HTML_QuickForm2_Element_Select_OptionIterator extends \RecursiveArrayIterator implements \RecursiveIterator
61 {
62 public function hasChildren() : bool
63 {
64 return $this->current() instanceof \HTML_QuickForm2_Element_Select_OptionContainer;
65 }
66 public function getChildren() : \HTML_QuickForm2_Element_Select_OptionIterator
67 {
68 return new \HTML_QuickForm2_Element_Select_OptionIterator($this->current()->getOptions());
69 }
70 }
71 /**
72 * Collection of <option>s and <optgroup>s
73 *
74 * This class handles the output of <option> tags. The class is not intended to
75 * be used directly.
76 *
77 * @category HTML
78 * @package HTML_QuickForm2
79 * @author Alexey Borzov <avb@php.net>
80 * @author Bertrand Mansion <golgote@mamasam.com>
81 * @version Release: @package_version@
82 */
83 class HTML_QuickForm2_Element_Select_OptionContainer extends \HTML_Common2 implements \IteratorAggregate, \Countable
84 {
85 /**
86 * List of options and optgroups in this container
87 *
88 * Options are stored as arrays (for performance reasons), optgroups as
89 * instances of Optgroup class.
90 *
91 * @var array
92 */
93 protected $options = array();
94 /**
95 * Reference to parent <select>'s values
96 * @var array
97 */
98 protected $values;
99 /**
100 * Reference to parent <select>'s possible values
101 * @var array
102 */
103 protected $possibleValues;
104 /**
105 * Class constructor
106 *
107 * @param array Reference to values of parent <select> element
108 * @param array Reference to possible values of parent <select> element
109 */
110 public function __construct(&$values, &$possibleValues)
111 {
112 $this->values =& $values;
113 $this->possibleValues =& $possibleValues;
114 }
115 /**
116 * Adds a new option
117 *
118 * Please note that if you pass 'selected' attribute in the $attributes
119 * parameter then this option's value will be added to <select>'s values.
120 *
121 * @param string Option text
122 * @param string 'value' attribute for <option> tag
123 * @param mixed Additional attributes for <option> tag (either as a
124 * string or as an associative array)
125 */
126 public function addOption($text, $value, $attributes = null)
127 {
128 if (null === $attributes) {
129 $attributes = array('value' => (string) $value);
130 } else {
131 $attributes = self::prepareAttributes($attributes);
132 if (isset($attributes['selected'])) {
133 // the 'selected' attribute will be set in __toString()
134 unset($attributes['selected']);
135 if (!\in_array($value, $this->values)) {
136 $this->values[] = $value;
137 }
138 }
139 $attributes['value'] = (string) $value;
140 }
141 if (!isset($attributes['disabled'])) {
142 $this->possibleValues[(string) $value] = \true;
143 }
144 $this->options[] = array('text' => $text, 'attr' => $attributes);
145 }
146 /**
147 * Adds a new optgroup
148 *
149 * @param string 'label' attribute for optgroup tag
150 * @param mixed Additional attributes for <optgroup> tag (either as a
151 * string or as an associative array)
152 * @return HTML_QuickForm2_Element_Select_Optgroup
153 */
154 public function addOptgroup($label, $attributes = null)
155 {
156 $optgroup = new \HTML_QuickForm2_Element_Select_Optgroup($this->values, $this->possibleValues, $label, $attributes);
157 $this->options[] = $optgroup;
158 return $optgroup;
159 }
160 /**
161 * Returns an array of contained options
162 *
163 * @return array
164 */
165 public function getOptions()
166 {
167 return $this->options;
168 }
169 public function __toString()
170 {
171 $indentLvl = $this->getIndentLevel();
172 $indent = $this->getIndent() . self::getOption('indent');
173 $linebreak = self::getOption('linebreak');
174 $html = '';
175 $strValues = \array_map('strval', $this->values);
176 foreach ($this->options as $option) {
177 if (\is_array($option)) {
178 if (\in_array($option['attr']['value'], $strValues, \true)) {
179 $option['attr']['selected'] = 'selected';
180 }
181 $html .= $indent . '<option' . self::getAttributesString($option['attr']) . '>' . $option['text'] . '</option>' . $linebreak;
182 } elseif ($option instanceof \HTML_QuickForm2_Element_Select_OptionContainer) {
183 $option->setIndentLevel($indentLvl + 1);
184 $html .= $option->__toString();
185 }
186 }
187 return $html;
188 }
189 /**
190 * Returns an iterator over contained elements
191 *
192 * @return HTML_QuickForm2_Element_Select_OptionIterator
193 */
194 public function getIterator() : \HTML_QuickForm2_Element_Select_OptionIterator
195 {
196 return new \HTML_QuickForm2_Element_Select_OptionIterator($this->options);
197 }
198 /**
199 * Returns a recursive iterator over contained elements
200 *
201 * @return RecursiveIteratorIterator
202 */
203 public function getRecursiveIterator() : \RecursiveIteratorIterator
204 {
205 return new \RecursiveIteratorIterator(new \HTML_QuickForm2_Element_Select_OptionIterator($this->options), \RecursiveIteratorIterator::SELF_FIRST);
206 }
207 /**
208 * Returns the number of options in the container
209 *
210 * @return int
211 */
212 public function count() : int
213 {
214 return \count($this->options);
215 }
216 }
217 /**
218 * Class representing an <optgroup> tag
219 *
220 * Do not instantiate this class yourself, use
221 * {@link HTML_QuickForm2_Element_Select::addOptgroup()} method
222 *
223 * @category HTML
224 * @package HTML_QuickForm2
225 * @author Alexey Borzov <avb@php.net>
226 * @author Bertrand Mansion <golgote@mamasam.com>
227 * @version Release: @package_version@
228 */
229 class HTML_QuickForm2_Element_Select_Optgroup extends \HTML_QuickForm2_Element_Select_OptionContainer
230 {
231 /**
232 * Class constructor
233 *
234 * @param array Reference to values of parent <select> element
235 * @param array Reference to possible values of parent <select> element
236 * @param string 'label' attribute for optgroup tag
237 * @param mixed Additional attributes for <optgroup> tag (either as a
238 * string or as an associative array)
239 */
240 public function __construct(&$values, &$possibleValues, $label, $attributes = null)
241 {
242 parent::__construct($values, $possibleValues);
243 $this->setAttributes($attributes);
244 $this->attributes['label'] = (string) $label;
245 }
246 public function __toString()
247 {
248 $indent = $this->getIndent();
249 $linebreak = self::getOption('linebreak');
250 return $indent . '<optgroup' . $this->getAttributes(\true) . '>' . $linebreak . parent::__toString() . $indent . '</optgroup>' . $linebreak;
251 }
252 }
253 /**
254 * Class representing a <select> element
255 *
256 * @category HTML
257 * @package HTML_QuickForm2
258 * @author Alexey Borzov <avb@php.net>
259 * @author Bertrand Mansion <golgote@mamasam.com>
260 * @version Release: @package_version@
261 */
262 class HTML_QuickForm2_Element_Select extends \HTML_QuickForm2_Element
263 {
264 protected $persistent = \true;
265 /**
266 * Values for the select element (i.e. values of the selected options)
267 * @var array
268 */
269 protected $values = array();
270 /**
271 * Possible values for select elements
272 *
273 * A value is considered possible if it is present as a value attribute of
274 * some option and that option is not disabled.
275 * @var array
276 */
277 protected $possibleValues = array();
278 /**
279 * Object containing options for the <select> element
280 * @var HTML_QuickForm2_Element_Select_OptionContainer
281 */
282 protected $optionContainer;
283 /**
284 * Enable intrinsic validation by default
285 * @var array
286 */
287 protected $data = array('intrinsic_validation' => \true);
288 /**
289 * Class constructor
290 *
291 * Select element can understand the following keys in $data parameter:
292 * - 'options': data to populate element's options with. Passed to
293 * {@link loadOptions()} method.
294 * - 'intrinsic_validation': setting this to false will disable
295 * that validation, {@link getValue()} will then return all submit
296 * values, not just those corresponding to options present in the
297 * element. May be useful in AJAX scenarios.
298 *
299 * @param string Element name
300 * @param mixed Attributes (either a string or an array)
301 * @param array Additional element data
302 * @throws HTML_QuickForm2_InvalidArgumentException if junk is given in $options
303 */
304 public function __construct($name = null, $attributes = null, array $data = array())
305 {
306 $options = isset($data['options']) ? $data['options'] : array();
307 unset($data['options']);
308 parent::__construct($name, $attributes, $data);
309 $this->loadOptions($options);
310 }
311 public function getType()
312 {
313 return 'select';
314 }
315 public function __toString()
316 {
317 if ($this->frozen) {
318 return $this->getFrozenHtml();
319 } else {
320 if (empty($this->attributes['multiple'])) {
321 $attrString = $this->getAttributes(\true);
322 } else {
323 $this->attributes['name'] .= '[]';
324 $attrString = $this->getAttributes(\true);
325 $this->attributes['name'] = \substr($this->attributes['name'], 0, -2);
326 }
327 $indent = $this->getIndent();
328 return $indent . '<select' . $attrString . '>' . self::getOption('linebreak') . $this->optionContainer->__toString() . $indent . '</select>';
329 }
330 }
331 protected function getFrozenHtml()
332 {
333 if (null === ($value = $this->getValue())) {
334 return '&nbsp;';
335 }
336 $valueHash = \is_array($value) ? \array_flip($value) : array($value => \true);
337 $options = array();
338 foreach ($this->optionContainer->getRecursiveIterator() as $child) {
339 if (\is_array($child) && isset($valueHash[$child['attr']['value']]) && empty($child['attr']['disabled'])) {
340 $options[] = $child['text'];
341 }
342 }
343 $html = \implode('<br />', $options);
344 if ($this->persistent) {
345 $name = $this->attributes['name'] . (empty($this->attributes['multiple']) ? '' : '[]');
346 // Only use id attribute if doing single hidden input
347 $idAttr = 1 == \count($valueHash) ? array('id' => $this->getId()) : array();
348 foreach ($valueHash as $key => $item) {
349 $html .= '<input type="hidden"' . self::getAttributesString(array('name' => $name, 'value' => $key) + $idAttr) . ' />';
350 }
351 }
352 return $html;
353 }
354 /**
355 * Returns the value of the <select> element
356 *
357 * Please note that the returned value may not necessarily be equal to that
358 * passed to {@link setValue()}. It passes "intrinsic validation" confirming
359 * that such value could possibly be submitted by this <select> element.
360 * Specifically, this method will return null if the elements "disabled"
361 * attribute is set, it will not return values if there are no options having
362 * such a "value" attribute or if such options' "disabled" attribute is set.
363 * It will also only return a scalar value for single selects, mimicking
364 * the common browsers' behaviour.
365 *
366 * @return mixed "value" attribute of selected option in case of single
367 * select, array of selected options' "value" attributes in
368 * case of multiple selects, null if no options selected
369 */
370 public function getValue()
371 {
372 if (!empty($this->attributes['disabled']) || 0 == \count($this->values) || $this->data['intrinsic_validation'] && (0 == \count($this->optionContainer) || 0 == \count($this->possibleValues))) {
373 return null;
374 }
375 $values = array();
376 foreach ($this->values as $value) {
377 if (!$this->data['intrinsic_validation'] || !empty($this->possibleValues[$value])) {
378 $values[] = $value;
379 }
380 }
381 if (0 == \count($values)) {
382 return null;
383 } elseif (!empty($this->attributes['multiple'])) {
384 return $this->applyFilters($values);
385 } elseif (1 == \count($values)) {
386 return $this->applyFilters($values[0]);
387 } else {
388 // The <select> is not multiple, but several options are to be
389 // selected. At least IE and Mozilla select the last selected
390 // option in this case, we should do the same
391 foreach ($this->optionContainer->getRecursiveIterator() as $child) {
392 if (\is_array($child) && \in_array($child['attr']['value'], $values)) {
393 $lastValue = $child['attr']['value'];
394 }
395 }
396 return $this->applyFilters($lastValue);
397 }
398 }
399 public function setValue($value)
400 {
401 if (\is_array($value)) {
402 $this->values = \array_values($value);
403 } else {
404 $this->values = array($value);
405 }
406 return $this;
407 }
408 /**
409 * Loads <option>s (and <optgroup>s) for select element
410 *
411 * The method expects a array of options and optgroups:
412 * <pre>
413 * array(
414 * 'option value 1' => 'option text 1',
415 * ...
416 * 'option value N' => 'option text N',
417 * 'optgroup label 1' => array(
418 * 'option value' => 'option text',
419 * ...
420 * ),
421 * ...
422 * )
423 * </pre>
424 * If value is a scalar, then array key is treated as "value" attribute of
425 * <option> and value as this <option>'s text. If value is an array, then
426 * key is treated as a "label" attribute of <optgroup> and value as an
427 * array of <option>s for this <optgroup>.
428 *
429 * If you need to specify additional attributes for <option> and <optgroup>
430 * tags, then you need to use {@link addOption()} and {@link addOptgroup()}
431 * methods instead of this one.
432 *
433 * @param array
434 * @throws HTML_QuickForm2_InvalidArgumentException if junk is given in $options
435 * @return HTML_QuickForm2_Element_Select
436 */
437 public function loadOptions(array $options)
438 {
439 $this->possibleValues = array();
440 $this->optionContainer = new \HTML_QuickForm2_Element_Select_OptionContainer($this->values, $this->possibleValues);
441 $this->loadOptionsFromArray($this->optionContainer, $options);
442 return $this;
443 }
444 /**
445 * Adds options from given array into given container
446 *
447 * @param HTML_QuickForm2_Element_Select_OptionContainer options will be
448 * added to this container
449 * @param array options array
450 */
451 protected function loadOptionsFromArray(\HTML_QuickForm2_Element_Select_OptionContainer $container, $options)
452 {
453 foreach ($options as $key => $value) {
454 if (\is_array($value)) {
455 $optgroup = $container->addOptgroup($key);
456 $this->loadOptionsFromArray($optgroup, $value);
457 } else {
458 $container->addOption($value, $key);
459 }
460 }
461 }
462 /**
463 * Adds a new option
464 *
465 * Please note that if you pass 'selected' attribute in the $attributes
466 * parameter then this option's value will be added to <select>'s values.
467 *
468 * @param string Option text
469 * @param string 'value' attribute for <option> tag
470 * @param mixed Additional attributes for <option> tag (either as a
471 * string or as an associative array)
472 */
473 public function addOption($text, $value, $attributes = null)
474 {
475 return $this->optionContainer->addOption($text, $value, $attributes);
476 }
477 /**
478 * Adds a new optgroup
479 *
480 * @param string 'label' attribute for optgroup tag
481 * @param mixed Additional attributes for <optgroup> tag (either as a
482 * string or as an associative array)
483 * @return HTML_QuickForm2_Element_Select_Optgroup
484 */
485 public function addOptgroup($label, $attributes = null)
486 {
487 return $this->optionContainer->addOptgroup($label, $attributes);
488 }
489 public function updateValue()
490 {
491 if (!$this->getAttribute('multiple')) {
492 parent::updateValue();
493 } else {
494 $name = $this->getName();
495 foreach ($this->getDataSources() as $ds) {
496 if (null !== ($value = $ds->getValue($name)) || $ds instanceof \HTML_QuickForm2_DataSource_Submit) {
497 $this->setValue(null === $value ? array() : $value);
498 return;
499 }
500 }
501 }
502 }
503 }
504 }
505