Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
62 / 62
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Select
100.00% covered (success)
100.00%
62 / 62
100.00% covered (success)
100.00%
4 / 4
33
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 setValues
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
1 / 1
16
 setValue
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
8
 resetValue
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Form\Element;
16
17/**
18 * Form select element class
19 *
20 * @category   Pop
21 * @package    Pop\Form
22 * @author     Nick Sagona, III <nick@popphp.org>
23 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
24 * @license    https://www.popphp.org/license     New BSD License
25 * @version    5.0.0
26 */
27
28class Select extends AbstractSelect
29{
30
31    /**
32     * Constructor
33     *
34     * Instantiate the select form element object
35     *
36     * @param  string       $name
37     * @param  string|array $values
38     * @param  mixed        $selected
39     * @param  ?string      $xmlFile
40     * @param  ?string      $indent
41     */
42    public function __construct(
43        string $name, string|array $values, mixed $selected = null, ?string $xmlFile = null, ?string $indent = null
44    )
45    {
46        parent::__construct('select');
47        $this->setName($name);
48        $this->setAttributes([
49            'name' => $name,
50            'id'   => $name
51        ]);
52
53        if ($selected !== null) {
54            $this->setValue($selected);
55        }
56        if ($indent !== null) {
57            $this->setIndent($indent);
58        }
59
60        $this->setValues($values, $xmlFile, $indent);
61    }
62
63    /**
64     * Set the options values of the select form element
65     *
66     * @param  string|array $values
67     * @param  ?string      $xmlFile
68     * @param  ?string      $indent
69     * @return Select
70     */
71    public function setValues(string|array $values, ?string $xmlFile = null, ?string $indent = null): Select
72    {
73        $values = self::parseValues($values, $xmlFile);
74
75        // Create the child option elements.
76        foreach ($values as $k => $v) {
77            if (is_array($v)) {
78                if (isset($v['value']) && isset($v['attributes'])) {
79                    $option = new Select\Option((string)$k, (string)$v['value'], ['attributes' => $v['attributes']]);
80                    $this->addChild($option);
81                } else {
82                    $optGroup = new Select\Optgroup();
83                    if ($indent !== null) {
84                        $optGroup->setIndent($indent);
85                    }
86                    $optGroup->setAttribute('label', $k);
87                    foreach ($v as $ky => $vl) {
88                        if (is_array($vl) && isset($vl['value']) && isset($vl['attributes'])) {
89                            $option = new Select\Option((string)$ky, (string)$vl['value'], ['attributes' => $vl['attributes']]);
90                        } else {
91                            $option = new Select\Option((string)$ky, (string)$vl);
92                        }
93                        if ($indent !== null) {
94                            $option->setIndent($indent);
95                        }
96
97                        // Determine if the current option element is selected.
98                        if (($this->selected !== null) && ($ky == $this->selected)) {
99                            $option->select();
100                        }
101                        $optGroup->addChild($option);
102                    }
103                    $this->addChild($optGroup);
104                }
105            } else {
106                $option = new Select\Option((string)$k, (string)$v);
107                if ($indent !== null) {
108                    $option->setIndent($indent);
109                }
110
111                // Determine if the current option element is selected.
112                if (($this->selected !== null) && ($k == $this->selected)) {
113                    $option->select();
114                }
115                $this->addChild($option);
116            }
117        }
118
119        return $this;
120    }
121
122    /**
123     * Set the selected value of the select form element
124     *
125     * @param  mixed $value
126     * @return Select
127     */
128    public function setValue(mixed $value = null): Select
129    {
130        $this->selected = $value;
131
132        if ($this->hasChildren()) {
133            foreach ($this->childNodes as $child) {
134                if ($child instanceof Select\Option) {
135                    if ($child->getValue() == $this->selected) {
136                        $child->select();
137                    } else {
138                        $child->deselect();
139                    }
140                } else if ($child instanceof Select\Optgroup) {
141                    $options = $child->getOptions();
142                    foreach ($options as $option) {
143                        if ($option->getValue() == $this->selected) {
144                            $option->select();
145                        } else {
146                            $option->deselect();
147                        }
148                    }
149                }
150            }
151        }
152
153        return $this;
154    }
155
156    /**
157     * Reset the value of the form element
158     *
159     * @return Select
160     */
161    public function resetValue(): Select
162    {
163        $this->selected = null;
164
165        if ($this->hasChildren()) {
166            foreach ($this->childNodes as $child) {
167                if ($child instanceof Select\Option) {
168                    $child->deselect();
169                } else if ($child instanceof Select\Optgroup) {
170                    $options = $child->getOptions();
171                    foreach ($options as $option) {
172                        $option->deselect();
173                    }
174                }
175            }
176        }
177
178        return $this;
179    }
180
181}