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