1<?php 2 3namespace dokuwiki\Form; 4 5class OptGroup extends Element 6{ 7 protected $options = []; 8 protected $values = []; 9 10 /** 11 * @param string $label The label text for this element (will be autoescaped) 12 * @param array $options The available options 13 */ 14 public function __construct($label, $options) 15 { 16 parent::__construct('optGroup', ['label' => $label]); 17 $this->options($options); 18 } 19 20 /** 21 * Store the given values so they can be used during rendering 22 * 23 * This is intended to be only called from within DropdownElement::val() 24 * 25 * @param string[] $values the values to set 26 * @return string[] the values that have been set (options exist) 27 * @see DropdownElement::val() 28 */ 29 public function storeValues($values) 30 { 31 $this->values = []; 32 foreach ($values as $value) { 33 if (isset($this->options[$value])) { 34 $this->values[] = $value; 35 } 36 } 37 38 return $this->values; 39 } 40 41 /** 42 * Get or set the options of the optgroup 43 * 44 * Options can be given as associative array (value => label) or as an 45 * indexd array (label = value) or as an array of arrays. In the latter 46 * case an element has to look as follows: 47 * option-value => array ( 48 * 'label' => option-label, 49 * 'attrs' => array ( 50 * attr-key => attr-value, ... 51 * ) 52 * ) 53 * 54 * @param null|array $options 55 * @return $this|array 56 */ 57 public function options($options = null) 58 { 59 if ($options === null) return $this->options; 60 if (!is_array($options)) throw new \InvalidArgumentException('Options have to be an array'); 61 $this->options = []; 62 foreach ($options as $key => $val) { 63 if (is_array($val)) { 64 if (!array_key_exists('label', $val)) { 65 throw new \InvalidArgumentException( 66 'If option is given as array, it has to have a "label"-key!' 67 ); 68 } 69 if ( 70 array_key_exists('attrs', $val) && 71 is_array($val['attrs']) && 72 array_key_exists('selected', $val['attrs']) 73 ) { 74 throw new \InvalidArgumentException( 75 'Please use function "DropdownElement::val()" to set the selected option' 76 ); 77 } 78 $this->options[$key] = $val; 79 } elseif (is_int($key)) { 80 $this->options[$val] = ['label' => (string)$val]; 81 } else { 82 $this->options[$key] = ['label' => (string)$val]; 83 } 84 } 85 return $this; 86 } 87 88 /** 89 * The HTML representation of this element 90 * 91 * @return string 92 */ 93 public function toHTML() 94 { 95 if ($this->attributes['label'] === null) { 96 return $this->renderOptions(); 97 } 98 $html = '<optgroup ' . buildAttributes($this->attrs()) . '>'; 99 $html .= $this->renderOptions(); 100 $html .= '</optgroup>'; 101 return $html; 102 } 103 104 /** 105 * @return string 106 */ 107 protected function renderOptions() 108 { 109 $html = ''; 110 foreach ($this->options as $key => $val) { 111 $selected = in_array((string)$key, $this->values) ? ' selected="selected"' : ''; 112 $attrs = ''; 113 if (!empty($val['attrs']) && is_array($val['attrs'])) { 114 $attrs = buildAttributes($val['attrs']); 115 } 116 $html .= '<option' . $selected . ' value="' . hsc($key) . '" ' . $attrs . '>'; 117 $html .= hsc($val['label']); 118 $html .= '</option>'; 119 } 120 return $html; 121 } 122} 123