xref: /dokuwiki/inc/Form/OptGroup.php (revision b0eca9cca0641a42f0f9639884fbf182fcd3c94d)
1<?php
2
3namespace dokuwiki\Form;
4
5
6class OptGroup extends Element {
7    protected $options = array();
8    protected $value;
9
10    /**
11     * @param string $name The name of this form element
12     * @param string $options The available options
13     * @param string $label The label text for this element (will be autoescaped)
14     */
15    public function __construct($name, $options) {
16        parent::__construct('optGroup', array('label' => $name));
17        $this->options($options);
18    }
19
20    /**
21     * Set the element's value
22     *
23     * This is intended to be only called from within @see DropdownElement::val()
24     *
25     * @param string $value
26     * @return bool
27     */
28    public function setValue($value) {
29        $this->value = $value;
30        return isset($this->options[$value]);
31    }
32
33    /**
34     * Get or set the options of the optgroup
35     *
36     * Options can be given as associative array (value => label) or as an
37     * indexd array (label = value) or as an array of arrays. In the latter
38     * case an element has to look as follows:
39     * option-value => array (
40     *                 'label' => option-label,
41     *                 'attrs' => array (
42     *                                    attr-key => attr-value, ...
43     *                                  )
44     *                 )
45     *
46     * @param null|array $options
47     * @return $this|array
48     */
49    public function options($options = null) {
50        if($options === null) return $this->options;
51        if(!is_array($options)) throw new \InvalidArgumentException('Options have to be an array');
52        $this->options = array();
53        foreach($options as $key => $val) {
54            if(is_int($key)) {
55                $this->options[$val] = array('label' => (string) $val);
56            } elseif (!is_array($val)) {
57                $this->options[$key] = array('label' => (string) $val);
58            } else {
59                if (!key_exists('label', $val)) throw new \InvalidArgumentException('If option is given as array, it has to have a "label"-key!');
60                $this->options[$key] = $val;
61            }
62        }
63        return $this;
64    }
65
66
67    /**
68     * The HTML representation of this element
69     *
70     * @return string
71     */
72    public function toHTML() {
73        if ($this->attributes['label'] === null) {
74            return $this->renderOptions();
75        }
76        $html = '<optgroup '. buildAttributes($this->attrs()) . '>';
77        $html .= $this->renderOptions();
78        $html .= '</optgroup>';
79        return $html;
80    }
81
82
83    /**
84     * @return string
85     */
86    protected function renderOptions() {
87        $html = '';
88        foreach($this->options as $key => $val) {
89            $selected = ($key == $this->value) ? ' selected="selected"' : '';
90            $attrs = '';
91            if (is_array($val['attrs'])) {
92                array_walk($val['attrs'],function (&$aval, $akey){$aval = hsc($akey).'="'.hsc($aval).'"';});
93                $attrs = join(' ', $val['attrs']);
94            }
95            $html .= '<option' . $selected . ' value="' . hsc($key) . '" '.$attrs.'>' . hsc($val['label']) . '</option>';
96        }
97        return $html;
98    }
99}
100