Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/dom-crawler/Field/ChoiceFormField.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 5fb285c0d0e3 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 /* | |
4 * This file is part of the Symfony package. | |
5 * | |
6 * (c) Fabien Potencier <fabien@symfony.com> | |
7 * | |
8 * For the full copyright and license information, please view the LICENSE | |
9 * file that was distributed with this source code. | |
10 */ | |
11 | |
12 namespace Symfony\Component\DomCrawler\Field; | |
13 | |
14 /** | |
15 * ChoiceFormField represents a choice form field. | |
16 * | |
17 * It is constructed from a HTML select tag, or a HTML checkbox, or radio inputs. | |
18 * | |
19 * @author Fabien Potencier <fabien@symfony.com> | |
20 */ | |
21 class ChoiceFormField extends FormField | |
22 { | |
23 /** | |
24 * @var string | |
25 */ | |
26 private $type; | |
27 /** | |
28 * @var bool | |
29 */ | |
30 private $multiple; | |
31 /** | |
32 * @var array | |
33 */ | |
34 private $options; | |
35 /** | |
36 * @var bool | |
37 */ | |
38 private $validationDisabled = false; | |
39 | |
40 /** | |
41 * Returns true if the field should be included in the submitted values. | |
42 * | |
43 * @return bool true if the field should be included in the submitted values, false otherwise | |
44 */ | |
45 public function hasValue() | |
46 { | |
47 // don't send a value for unchecked checkboxes | |
48 if (in_array($this->type, array('checkbox', 'radio')) && null === $this->value) { | |
49 return false; | |
50 } | |
51 | |
52 return true; | |
53 } | |
54 | |
55 /** | |
56 * Check if the current selected option is disabled. | |
57 * | |
58 * @return bool | |
59 */ | |
60 public function isDisabled() | |
61 { | |
62 if (parent::isDisabled() && 'select' === $this->type) { | |
63 return true; | |
64 } | |
65 | |
66 foreach ($this->options as $option) { | |
67 if ($option['value'] == $this->value && $option['disabled']) { | |
68 return true; | |
69 } | |
70 } | |
71 | |
72 return false; | |
73 } | |
74 | |
75 /** | |
76 * Sets the value of the field. | |
77 * | |
78 * @param string $value The value of the field | |
79 */ | |
80 public function select($value) | |
81 { | |
82 $this->setValue($value); | |
83 } | |
84 | |
85 /** | |
86 * Ticks a checkbox. | |
87 * | |
88 * @throws \LogicException When the type provided is not correct | |
89 */ | |
90 public function tick() | |
91 { | |
92 if ('checkbox' !== $this->type) { | |
93 throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); | |
94 } | |
95 | |
96 $this->setValue(true); | |
97 } | |
98 | |
99 /** | |
100 * Ticks a checkbox. | |
101 * | |
102 * @throws \LogicException When the type provided is not correct | |
103 */ | |
104 public function untick() | |
105 { | |
106 if ('checkbox' !== $this->type) { | |
107 throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); | |
108 } | |
109 | |
110 $this->setValue(false); | |
111 } | |
112 | |
113 /** | |
114 * Sets the value of the field. | |
115 * | |
116 * @param string $value The value of the field | |
117 * | |
118 * @throws \InvalidArgumentException When value type provided is not correct | |
119 */ | |
120 public function setValue($value) | |
121 { | |
122 if ('checkbox' === $this->type && false === $value) { | |
123 // uncheck | |
124 $this->value = null; | |
125 } elseif ('checkbox' === $this->type && true === $value) { | |
126 // check | |
127 $this->value = $this->options[0]['value']; | |
128 } else { | |
129 if (is_array($value)) { | |
130 if (!$this->multiple) { | |
131 throw new \InvalidArgumentException(sprintf('The value for "%s" cannot be an array.', $this->name)); | |
132 } | |
133 | |
134 foreach ($value as $v) { | |
135 if (!$this->containsOption($v, $this->options)) { | |
136 throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $v, implode(', ', $this->availableOptionValues()))); | |
137 } | |
138 } | |
139 } elseif (!$this->containsOption($value, $this->options)) { | |
140 throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $value, implode(', ', $this->availableOptionValues()))); | |
141 } | |
142 | |
143 if ($this->multiple) { | |
144 $value = (array) $value; | |
145 } | |
146 | |
147 if (is_array($value)) { | |
148 $this->value = $value; | |
149 } else { | |
150 parent::setValue($value); | |
151 } | |
152 } | |
153 } | |
154 | |
155 /** | |
156 * Adds a choice to the current ones. | |
157 * | |
158 * @param \DOMElement $node | |
159 * | |
160 * @throws \LogicException When choice provided is not multiple nor radio | |
161 * | |
162 * @internal | |
163 */ | |
164 public function addChoice(\DOMElement $node) | |
165 { | |
166 if (!$this->multiple && 'radio' !== $this->type) { | |
167 throw new \LogicException(sprintf('Unable to add a choice for "%s" as it is not multiple or is not a radio button.', $this->name)); | |
168 } | |
169 | |
170 $option = $this->buildOptionValue($node); | |
171 $this->options[] = $option; | |
172 | |
173 if ($node->hasAttribute('checked')) { | |
174 $this->value = $option['value']; | |
175 } | |
176 } | |
177 | |
178 /** | |
179 * Returns the type of the choice field (radio, select, or checkbox). | |
180 * | |
181 * @return string The type | |
182 */ | |
183 public function getType() | |
184 { | |
185 return $this->type; | |
186 } | |
187 | |
188 /** | |
189 * Returns true if the field accepts multiple values. | |
190 * | |
191 * @return bool true if the field accepts multiple values, false otherwise | |
192 */ | |
193 public function isMultiple() | |
194 { | |
195 return $this->multiple; | |
196 } | |
197 | |
198 /** | |
199 * Initializes the form field. | |
200 * | |
201 * @throws \LogicException When node type is incorrect | |
202 */ | |
203 protected function initialize() | |
204 { | |
205 if ('input' !== $this->node->nodeName && 'select' !== $this->node->nodeName) { | |
206 throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName)); | |
207 } | |
208 | |
209 if ('input' === $this->node->nodeName && 'checkbox' !== strtolower($this->node->getAttribute('type')) && 'radio' !== strtolower($this->node->getAttribute('type'))) { | |
210 throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is %s).', $this->node->getAttribute('type'))); | |
211 } | |
212 | |
213 $this->value = null; | |
214 $this->options = array(); | |
215 $this->multiple = false; | |
216 | |
217 if ('input' == $this->node->nodeName) { | |
218 $this->type = strtolower($this->node->getAttribute('type')); | |
219 $optionValue = $this->buildOptionValue($this->node); | |
220 $this->options[] = $optionValue; | |
221 | |
222 if ($this->node->hasAttribute('checked')) { | |
223 $this->value = $optionValue['value']; | |
224 } | |
225 } else { | |
226 $this->type = 'select'; | |
227 if ($this->node->hasAttribute('multiple')) { | |
228 $this->multiple = true; | |
229 $this->value = array(); | |
230 $this->name = str_replace('[]', '', $this->name); | |
231 } | |
232 | |
233 $found = false; | |
234 foreach ($this->xpath->query('descendant::option', $this->node) as $option) { | |
235 $optionValue = $this->buildOptionValue($option); | |
236 $this->options[] = $optionValue; | |
237 | |
238 if ($option->hasAttribute('selected')) { | |
239 $found = true; | |
240 if ($this->multiple) { | |
241 $this->value[] = $optionValue['value']; | |
242 } else { | |
243 $this->value = $optionValue['value']; | |
244 } | |
245 } | |
246 } | |
247 | |
248 // if no option is selected and if it is a simple select box, take the first option as the value | |
249 if (!$found && !$this->multiple && !empty($this->options)) { | |
250 $this->value = $this->options[0]['value']; | |
251 } | |
252 } | |
253 } | |
254 | |
255 /** | |
256 * Returns option value with associated disabled flag. | |
257 * | |
258 * @param \DOMElement $node | |
259 * | |
260 * @return array | |
261 */ | |
262 private function buildOptionValue(\DOMElement $node) | |
263 { | |
264 $option = array(); | |
265 | |
266 $defaultDefaultValue = 'select' === $this->node->nodeName ? '' : 'on'; | |
267 $defaultValue = (isset($node->nodeValue) && !empty($node->nodeValue)) ? $node->nodeValue : $defaultDefaultValue; | |
268 $option['value'] = $node->hasAttribute('value') ? $node->getAttribute('value') : $defaultValue; | |
269 $option['disabled'] = $node->hasAttribute('disabled'); | |
270 | |
271 return $option; | |
272 } | |
273 | |
274 /** | |
275 * Checks whether given value is in the existing options. | |
276 * | |
277 * @param string $optionValue | |
278 * @param array $options | |
279 * | |
280 * @return bool | |
281 */ | |
282 public function containsOption($optionValue, $options) | |
283 { | |
284 if ($this->validationDisabled) { | |
285 return true; | |
286 } | |
287 | |
288 foreach ($options as $option) { | |
289 if ($option['value'] == $optionValue) { | |
290 return true; | |
291 } | |
292 } | |
293 | |
294 return false; | |
295 } | |
296 | |
297 /** | |
298 * Returns list of available field options. | |
299 * | |
300 * @return array | |
301 */ | |
302 public function availableOptionValues() | |
303 { | |
304 $values = array(); | |
305 | |
306 foreach ($this->options as $option) { | |
307 $values[] = $option['value']; | |
308 } | |
309 | |
310 return $values; | |
311 } | |
312 | |
313 /** | |
314 * Disables the internal validation of the field. | |
315 * | |
316 * @return self | |
317 */ | |
318 public function disableValidation() | |
319 { | |
320 $this->validationDisabled = true; | |
321 | |
322 return $this; | |
323 } | |
324 } |