composer package updates
[openemr.git] / vendor / zendframework / zend-form / src / Element / Select.php
blob5f404b781d3a942a63ab16cbb87fa5af7fbd25bf
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Form\Element;
12 use Traversable;
13 use Zend\Form\Element;
14 use Zend\Form\ElementInterface;
15 use Zend\Form\Exception\InvalidArgumentException;
16 use Zend\InputFilter\InputProviderInterface;
17 use Zend\Validator\Explode as ExplodeValidator;
18 use Zend\Validator\InArray as InArrayValidator;
20 class Select extends Element implements InputProviderInterface
22 /**
23 * Seed attributes
25 * @var array
27 protected $attributes = [
28 'type' => 'select',
31 /**
32 * @var \Zend\Validator\ValidatorInterface
34 protected $validator;
36 /**
37 * @var bool
39 protected $disableInArrayValidator = false;
41 /**
42 * Create an empty option (option with label but no value). If set to null, no option is created
44 * @var bool
46 protected $emptyOption = null;
48 /**
49 * @var array
51 protected $valueOptions = [];
53 /**
54 * @var bool
56 protected $useHiddenElement = false;
58 /**
59 * @var string
61 protected $unselectedValue = '';
63 /**
64 * @return array
66 public function getValueOptions()
68 return $this->valueOptions;
71 /**
72 * @param array $options
73 * @return Select
75 public function setValueOptions(array $options)
77 $this->valueOptions = $options;
79 // Update InArrayValidator validator haystack
80 if (null !== $this->validator) {
81 if ($this->validator instanceof InArrayValidator) {
82 $validator = $this->validator;
84 if ($this->validator instanceof ExplodeValidator
85 && $this->validator->getValidator() instanceof InArrayValidator
86 ) {
87 $validator = $this->validator->getValidator();
89 if (! empty($validator)) {
90 $validator->setHaystack($this->getValueOptionsValues());
94 return $this;
97 /**
98 * @param string $key
99 * @return self
101 public function unsetValueOption($key)
103 if (isset($this->valueOptions[$key])) {
104 unset($this->valueOptions[$key]);
107 return $this;
111 * Set options for an element. Accepted options are:
112 * - label: label to associate with the element
113 * - label_attributes: attributes to use when the label is rendered
114 * - value_options: list of values and labels for the select options
115 * - empty_option: should an empty option be prepended to the options ?
117 * @param array|Traversable $options
118 * @return Select|ElementInterface
119 * @throws InvalidArgumentException
121 public function setOptions($options)
123 parent::setOptions($options);
125 if (isset($this->options['value_options'])) {
126 $this->setValueOptions($this->options['value_options']);
128 // Alias for 'value_options'
129 if (isset($this->options['options'])) {
130 $this->setValueOptions($this->options['options']);
133 if (isset($this->options['empty_option'])) {
134 $this->setEmptyOption($this->options['empty_option']);
137 if (isset($this->options['disable_inarray_validator'])) {
138 $this->setDisableInArrayValidator($this->options['disable_inarray_validator']);
141 if (isset($options['use_hidden_element'])) {
142 $this->setUseHiddenElement($options['use_hidden_element']);
145 if (isset($options['unselected_value'])) {
146 $this->setUnselectedValue($options['unselected_value']);
149 return $this;
153 * Set a single element attribute
155 * @param string $key
156 * @param mixed $value
157 * @return Select|ElementInterface
159 public function setAttribute($key, $value)
161 // Do not include the options in the list of attributes
162 // TODO: Deprecate this
163 if ($key === 'options') {
164 $this->setValueOptions($value);
165 return $this;
167 return parent::setAttribute($key, $value);
171 * Set the flag to allow for disabling the automatic addition of an InArray validator.
173 * @param bool $disableOption
174 * @return Select
176 public function setDisableInArrayValidator($disableOption)
178 $this->disableInArrayValidator = (bool) $disableOption;
179 return $this;
183 * Get the disable in array validator flag.
185 * @return bool
187 public function disableInArrayValidator()
189 return $this->disableInArrayValidator;
193 * Set the string for an empty option (can be empty string). If set to null, no option will be added
195 * @param string|null $emptyOption
196 * @return Select
198 public function setEmptyOption($emptyOption)
200 $this->emptyOption = $emptyOption;
201 return $this;
205 * Return the string for the empty option (null if none)
207 * @return string|null
209 public function getEmptyOption()
211 return $this->emptyOption;
215 * Get validator
217 * @return \Zend\Validator\ValidatorInterface
219 protected function getValidator()
221 if (null === $this->validator && ! $this->disableInArrayValidator()) {
222 $validator = new InArrayValidator([
223 'haystack' => $this->getValueOptionsValues(),
224 'strict' => false
227 if ($this->isMultiple()) {
228 $validator = new ExplodeValidator([
229 'validator' => $validator,
230 'valueDelimiter' => null, // skip explode if only one value
234 $this->validator = $validator;
236 return $this->validator;
240 * Do we render hidden element?
242 * @param bool $useHiddenElement
243 * @return Select
245 public function setUseHiddenElement($useHiddenElement)
247 $this->useHiddenElement = (bool) $useHiddenElement;
248 return $this;
252 * Do we render hidden element?
254 * @return bool
256 public function useHiddenElement()
258 return $this->useHiddenElement;
262 * Set the value if the select is not selected
264 * @param string $unselectedValue
265 * @return Select
267 public function setUnselectedValue($unselectedValue)
269 $this->unselectedValue = (string) $unselectedValue;
270 return $this;
274 * Get the value when the select is not selected
276 * @return string
278 public function getUnselectedValue()
280 return $this->unselectedValue;
284 * Provide default input rules for this element
286 * @return array
288 public function getInputSpecification()
290 $spec = [
291 'name' => $this->getName(),
292 'required' => true,
295 if ($this->useHiddenElement() && $this->isMultiple()) {
296 $unselectedValue = $this->getUnselectedValue();
298 $spec['allow_empty'] = true;
299 $spec['continue_if_empty'] = true;
300 $spec['filters'] = [[
301 'name' => 'Callback',
302 'options' => [
303 'callback' => function ($value) use ($unselectedValue) {
304 if ($value === $unselectedValue) {
305 $value = [];
307 return $value;
313 if ($validator = $this->getValidator()) {
314 $spec['validators'] = [
315 $validator,
319 return $spec;
323 * Get only the values from the options attribute
325 * @return array
327 protected function getValueOptionsValues()
329 $values = [];
330 $options = $this->getValueOptions();
331 foreach ($options as $key => $optionSpec) {
332 if (is_array($optionSpec) && array_key_exists('options', $optionSpec)) {
333 foreach ($optionSpec['options'] as $nestedKey => $nestedOptionSpec) {
334 $values[] = $this->getOptionValue($nestedKey, $nestedOptionSpec);
336 continue;
339 $values[] = $this->getOptionValue($key, $optionSpec);
341 return $values;
344 protected function getOptionValue($key, $optionSpec)
346 return is_array($optionSpec) ? $optionSpec['value'] : $key;
350 * Element has the multiple attribute
352 * @return bool
354 public function isMultiple()
356 return isset($this->attributes['multiple'])
357 && ($this->attributes['multiple'] === true || $this->attributes['multiple'] === 'multiple');