Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
63 / 63 |
|
100.00% |
12 / 12 |
CRAP | |
100.00% |
1 / 1 |
| AbstractInputSet | |
100.00% |
63 / 63 |
|
100.00% |
12 / 12 |
33 | |
100.00% |
1 / 1 |
| appendInputWithSpan | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
4 | |||
| setDisabled | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
| setReadonly | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
4 | |||
| setInputAttribute | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
| setInputAttributes | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
4 | |||
| setLegend | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
| getLegend | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| setContainer | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
| getContainer | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getFieldsetChildNodes | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
5 | |||
| validate | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
| render | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
| 1 | <?php |
| 2 | declare(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 | */ |
| 15 | namespace Pop\Form\Element; |
| 16 | |
| 17 | use Pop\Dom\Child; |
| 18 | |
| 19 | /** |
| 20 | * Abstract form input set class |
| 21 | * |
| 22 | * @category Pop |
| 23 | * @package Pop\Form |
| 24 | * @author Nick Sagona, III <nick@popphp.org> |
| 25 | * @copyright Copyright (c) 2009-2026 Nick Sagona, III |
| 26 | * @license https://www.popphp.org/license New BSD License |
| 27 | * @version 5.0.0 |
| 28 | */ |
| 29 | abstract class AbstractInputSet extends AbstractElement |
| 30 | { |
| 31 | |
| 32 | /** |
| 33 | * Array of input elements |
| 34 | * @var array |
| 35 | */ |
| 36 | protected array $inputs = []; |
| 37 | |
| 38 | /** |
| 39 | * Fieldset legend |
| 40 | * @var ?string |
| 41 | */ |
| 42 | protected ?string $legend = null; |
| 43 | |
| 44 | /** |
| 45 | * Fieldset container |
| 46 | * @var ?string |
| 47 | */ |
| 48 | protected ?string $container = null; |
| 49 | |
| 50 | /** |
| 51 | * Create an input element, wrap it with its span and append it (and the input) to the set |
| 52 | * |
| 53 | * @param AbstractElement $input |
| 54 | * @param mixed $nodeValue |
| 55 | * @param string $spanClass |
| 56 | * @param ?string $indent |
| 57 | * @param string $containerClass |
| 58 | * @return void |
| 59 | */ |
| 60 | protected function appendInputWithSpan( |
| 61 | AbstractElement $input, mixed $nodeValue, string $spanClass, ?string $indent, string $containerClass |
| 62 | ): void |
| 63 | { |
| 64 | $span = new Child('span'); |
| 65 | if ($indent !== null) { |
| 66 | $span->setIndent($indent); |
| 67 | } |
| 68 | $span->setAttribute('class', $spanClass); |
| 69 | $span->setNodeValue(($nodeValue !== null) ? (string)$nodeValue : null); |
| 70 | |
| 71 | if (!empty($this->container)) { |
| 72 | $container = new Child($this->container); |
| 73 | $container->setAttribute('class', $containerClass); |
| 74 | $container->addChildren([$input, $span]); |
| 75 | $this->addChildren([$container]); |
| 76 | } else { |
| 77 | $this->addChildren([$input, $span]); |
| 78 | } |
| 79 | |
| 80 | $this->inputs[] = $input; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Set whether the form element is disabled |
| 85 | * |
| 86 | * @param bool $disabled |
| 87 | * @return static |
| 88 | */ |
| 89 | public function setDisabled(bool $disabled): static |
| 90 | { |
| 91 | $childNodes = $this->getFieldsetChildNodes(); |
| 92 | if ($disabled) { |
| 93 | foreach ($childNodes as $childNode) { |
| 94 | $childNode->setAttribute('disabled', 'disabled'); |
| 95 | } |
| 96 | } else { |
| 97 | foreach ($childNodes as $childNode) { |
| 98 | $childNode->removeAttribute('disabled'); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | parent::setDisabled($disabled); |
| 103 | return $this; |
| 104 | } |
| 105 | |
| 106 | /** |
| 107 | * Set whether the form element is readonly |
| 108 | * |
| 109 | * @param bool $readonly |
| 110 | * @return static |
| 111 | */ |
| 112 | public function setReadonly(bool $readonly): static |
| 113 | { |
| 114 | $childNodes = $this->getFieldsetChildNodes(); |
| 115 | if ($readonly) { |
| 116 | foreach ($childNodes as $childNode) { |
| 117 | $childNode->setAttribute('readonly', 'readonly'); |
| 118 | $childNode->setAttribute('onclick', 'return false;'); |
| 119 | } |
| 120 | } else { |
| 121 | foreach ($childNodes as $childNode) { |
| 122 | $childNode->removeAttribute('readonly'); |
| 123 | $childNode->removeAttribute('onclick'); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | parent::setReadonly($readonly); |
| 128 | return $this; |
| 129 | } |
| 130 | |
| 131 | /** |
| 132 | * Set an attribute for the input elements |
| 133 | * |
| 134 | * @param string $a |
| 135 | * @param string $v |
| 136 | * @return static |
| 137 | */ |
| 138 | protected function setInputAttribute(string $a, string $v): static |
| 139 | { |
| 140 | foreach ($this->inputs as $input) { |
| 141 | $input->setAttribute($a, $v); |
| 142 | if ($a == 'tabindex') { |
| 143 | $v = (string)((int)$v + 1); |
| 144 | } |
| 145 | } |
| 146 | return $this; |
| 147 | } |
| 148 | |
| 149 | /** |
| 150 | * Set an attribute or attributes for the input elements |
| 151 | * |
| 152 | * @param array $a |
| 153 | * @return static |
| 154 | */ |
| 155 | protected function setInputAttributes(array $a): static |
| 156 | { |
| 157 | if (isset($a['tabindex'])) { |
| 158 | $a['tabindex'] = (string)$a['tabindex']; |
| 159 | } |
| 160 | foreach ($this->inputs as $input) { |
| 161 | $input->setAttributes($a); |
| 162 | if (isset($a['tabindex'])) { |
| 163 | $a['tabindex'] = (string)((int)$a['tabindex'] + 1); |
| 164 | } |
| 165 | } |
| 166 | return $this; |
| 167 | } |
| 168 | |
| 169 | /** |
| 170 | * Method to set fieldset legend |
| 171 | * |
| 172 | * @param string $legend |
| 173 | * @return static |
| 174 | */ |
| 175 | public function setLegend(string $legend): static |
| 176 | { |
| 177 | $this->legend = $legend; |
| 178 | return $this; |
| 179 | } |
| 180 | |
| 181 | /** |
| 182 | * Method to get fieldset legend |
| 183 | * |
| 184 | * @return ?string |
| 185 | */ |
| 186 | public function getLegend(): ?string |
| 187 | { |
| 188 | return $this->legend; |
| 189 | } |
| 190 | |
| 191 | /** |
| 192 | * Method to set fieldset container |
| 193 | * |
| 194 | * @param string $container |
| 195 | * @return static |
| 196 | */ |
| 197 | public function setContainer(string $container): static |
| 198 | { |
| 199 | $this->container = $container; |
| 200 | return $this; |
| 201 | } |
| 202 | |
| 203 | /** |
| 204 | * Method to get fieldset container |
| 205 | * |
| 206 | * @return ?string |
| 207 | */ |
| 208 | public function getContainer(): ?string |
| 209 | { |
| 210 | return $this->container; |
| 211 | } |
| 212 | |
| 213 | /** |
| 214 | * Method to get fieldset child nodes |
| 215 | * |
| 216 | * @return array |
| 217 | */ |
| 218 | public function getFieldsetChildNodes(): array |
| 219 | { |
| 220 | if (!empty($this->container)) { |
| 221 | $childNodes = []; |
| 222 | foreach ($this->childNodes as $childNode) { |
| 223 | if (($childNode->getNodeName() == $this->container) && ($childNode->hasChildNodes())) { |
| 224 | $childNodes = array_merge($childNodes, $childNode->getChildNodes()); |
| 225 | } |
| 226 | } |
| 227 | return $childNodes; |
| 228 | } else { |
| 229 | return $this->childNodes; |
| 230 | } |
| 231 | } |
| 232 | |
| 233 | /** |
| 234 | * Validate the form element object |
| 235 | * |
| 236 | * @param array $formValues |
| 237 | * @return bool |
| 238 | */ |
| 239 | public function validate(array $formValues = []): bool |
| 240 | { |
| 241 | $value = $this->getValue(); |
| 242 | |
| 243 | // Check if the element is required |
| 244 | if (($this->required) && empty($value)) { |
| 245 | $this->errors[] = $this->getRequiredMessage(); |
| 246 | } |
| 247 | |
| 248 | $this->validateValue($value, $formValues); |
| 249 | |
| 250 | return (count($this->errors) == 0); |
| 251 | } |
| 252 | |
| 253 | /** |
| 254 | * Render the child and its child nodes |
| 255 | * |
| 256 | * @param int $depth |
| 257 | * @param ?string $indent |
| 258 | * @param bool $inner |
| 259 | * @return string |
| 260 | */ |
| 261 | public function render(int $depth = 0, ?string $indent = null, bool $inner = false): string |
| 262 | { |
| 263 | if (!empty($this->legend)) { |
| 264 | $this->addChild(new Child('legend', $this->legend)); |
| 265 | } |
| 266 | return parent::render($depth, $indent, $inner); |
| 267 | } |
| 268 | |
| 269 | } |