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