Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
53 / 53
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
SelectMultiple
100.00% covered (success)
100.00%
53 / 53
100.00% covered (success)
100.00%
3 / 3
24
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
1 / 1
9
 setValue
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
9
 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 multiple 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 SelectMultiple 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  string|array $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
48        $this->setName($name);
49        $this->setAttributes([
50            'name'     => $name . '[]',
51            'id'       => $name,
52            'multiple' => 'multiple'
53        ]);
54
55        if ($indent !== null) {
56            $this->setIndent($indent);
57        }
58
59        $values = self::parseValues($values, $xmlFile);
60
61        // Create the child option elements.
62        foreach ($values as $k => $v) {
63            if (is_array($v)) {
64                $optGroup = new Select\Optgroup();
65                if ($indent !== null) {
66                    $optGroup->setIndent($indent);
67                }
68                $optGroup->setAttribute('label', $k);
69                foreach ($v as $ky => $vl) {
70                    $option = new Select\Option((string)$ky, (string)$vl);
71                    if ($indent !== null) {
72                        $option->setIndent($indent);
73                    }
74                    $optGroup->addChild($option);
75                }
76                $this->addChild($optGroup);
77            } else {
78                $option = new Select\Option((string)$k, (string)$v);
79                if ($indent !== null) {
80                    $option->setIndent($indent);
81                }
82                $this->addChild($option);
83            }
84        }
85
86        if ($selected !== null) {
87            $this->setValue($selected);
88        } else {
89            $this->selected = [];
90        }
91    }
92
93    /**
94     * Set the selected value of the select form element
95     *
96     * @param  mixed $value
97     * @return SelectMultiple
98     */
99    public function setValue(mixed $value = null): SelectMultiple
100    {
101        $this->selected = (!is_array($value)) ? [$value] : $value;
102
103        if ($this->hasChildren()) {
104            foreach ($this->childNodes as $child) {
105                if ($child instanceof Select\Option) {
106                    if (in_array($child->getValue(), $this->selected)) {
107                        $child->select();
108                    } else {
109                        $child->deselect();
110                    }
111                } else if ($child instanceof Select\Optgroup) {
112                    $options = $child->getOptions();
113                    foreach ($options as $option) {
114                        if (in_array($option->getValue(), $this->selected)) {
115                            $option->select();
116                        } else {
117                            $option->deselect();
118                        }
119                    }
120                }
121            }
122        }
123
124        return $this;
125    }
126
127    /**
128     * Reset the value of the form element
129     *
130     * @return SelectMultiple
131     */
132    public function resetValue(): SelectMultiple
133    {
134        $this->selected = [];
135
136        if ($this->hasChildren()) {
137            foreach ($this->childNodes as $child) {
138                if ($child instanceof Select\Option) {
139                    $child->deselect();
140                } else if ($child instanceof Select\Optgroup) {
141                    $options = $child->getOptions();
142                    foreach ($options as $option) {
143                        $option->deselect();
144                    }
145                }
146            }
147        }
148
149        return $this;
150    }
151
152}