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