PageRenderTime 28ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/zendframework/zend-form/src/View/Helper/FormSelect.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 326 lines | 188 code | 44 blank | 94 comment | 31 complexity | 47c5a33dccf411e610e51430c9d821d7 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  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. */
  9. namespace Zend\Form\View\Helper;
  10. use Zend\Form\Element\Hidden;
  11. use Zend\Form\ElementInterface;
  12. use Zend\Form\Element\Select as SelectElement;
  13. use Zend\Form\Exception;
  14. use Zend\Stdlib\ArrayUtils;
  15. class FormSelect extends AbstractHelper
  16. {
  17. /**
  18. * Attributes valid for the current tag
  19. *
  20. * Will vary based on whether a select, option, or optgroup is being rendered
  21. *
  22. * @var array
  23. */
  24. protected $validTagAttributes;
  25. /**
  26. * Attributes valid for select
  27. *
  28. * @var array
  29. */
  30. protected $validSelectAttributes = array(
  31. 'name' => true,
  32. 'autocomplete' => true,
  33. 'autofocus' => true,
  34. 'disabled' => true,
  35. 'form' => true,
  36. 'multiple' => true,
  37. 'required' => true,
  38. 'size' => true
  39. );
  40. /**
  41. * Attributes valid for options
  42. *
  43. * @var array
  44. */
  45. protected $validOptionAttributes = array(
  46. 'disabled' => true,
  47. 'selected' => true,
  48. 'label' => true,
  49. 'value' => true,
  50. );
  51. /**
  52. * Attributes valid for option groups
  53. *
  54. * @var array
  55. */
  56. protected $validOptgroupAttributes = array(
  57. 'disabled' => true,
  58. 'label' => true,
  59. );
  60. protected $translatableAttributes = array(
  61. 'label' => true,
  62. );
  63. /**
  64. * @var FormHidden|null
  65. */
  66. protected $formHiddenHelper;
  67. /**
  68. * Invoke helper as functor
  69. *
  70. * Proxies to {@link render()}.
  71. *
  72. * @param ElementInterface|null $element
  73. * @return string|FormSelect
  74. */
  75. public function __invoke(ElementInterface $element = null)
  76. {
  77. if (!$element) {
  78. return $this;
  79. }
  80. return $this->render($element);
  81. }
  82. /**
  83. * Render a form <select> element from the provided $element
  84. *
  85. * @param ElementInterface $element
  86. * @throws Exception\InvalidArgumentException
  87. * @throws Exception\DomainException
  88. * @return string
  89. */
  90. public function render(ElementInterface $element)
  91. {
  92. if (!$element instanceof SelectElement) {
  93. throw new Exception\InvalidArgumentException(sprintf(
  94. '%s requires that the element is of type Zend\Form\Element\Select',
  95. __METHOD__
  96. ));
  97. }
  98. $name = $element->getName();
  99. if (empty($name) && $name !== 0) {
  100. throw new Exception\DomainException(sprintf(
  101. '%s requires that the element has an assigned name; none discovered',
  102. __METHOD__
  103. ));
  104. }
  105. $options = $element->getValueOptions();
  106. if (($emptyOption = $element->getEmptyOption()) !== null) {
  107. $options = array('' => $emptyOption) + $options;
  108. }
  109. $attributes = $element->getAttributes();
  110. $value = $this->validateMultiValue($element->getValue(), $attributes);
  111. $attributes['name'] = $name;
  112. if (array_key_exists('multiple', $attributes) && $attributes['multiple']) {
  113. $attributes['name'] .= '[]';
  114. }
  115. $this->validTagAttributes = $this->validSelectAttributes;
  116. $rendered = sprintf(
  117. '<select %s>%s</select>',
  118. $this->createAttributesString($attributes),
  119. $this->renderOptions($options, $value)
  120. );
  121. // Render hidden element
  122. $useHiddenElement = method_exists($element, 'useHiddenElement')
  123. && method_exists($element, 'getUnselectedValue')
  124. && $element->useHiddenElement();
  125. if ($useHiddenElement) {
  126. $rendered = $this->renderHiddenElement($element) . $rendered;
  127. }
  128. return $rendered;
  129. }
  130. /**
  131. * Render an array of options
  132. *
  133. * Individual options should be of the form:
  134. *
  135. * <code>
  136. * array(
  137. * 'value' => 'value',
  138. * 'label' => 'label',
  139. * 'disabled' => $booleanFlag,
  140. * 'selected' => $booleanFlag,
  141. * )
  142. * </code>
  143. *
  144. * @param array $options
  145. * @param array $selectedOptions Option values that should be marked as selected
  146. * @return string
  147. */
  148. public function renderOptions(array $options, array $selectedOptions = array())
  149. {
  150. $template = '<option %s>%s</option>';
  151. $optionStrings = array();
  152. $escapeHtml = $this->getEscapeHtmlHelper();
  153. foreach ($options as $key => $optionSpec) {
  154. $value = '';
  155. $label = '';
  156. $selected = false;
  157. $disabled = false;
  158. if (is_scalar($optionSpec)) {
  159. $optionSpec = array(
  160. 'label' => $optionSpec,
  161. 'value' => $key
  162. );
  163. }
  164. if (isset($optionSpec['options']) && is_array($optionSpec['options'])) {
  165. $optionStrings[] = $this->renderOptgroup($optionSpec, $selectedOptions);
  166. continue;
  167. }
  168. if (isset($optionSpec['value'])) {
  169. $value = $optionSpec['value'];
  170. }
  171. if (isset($optionSpec['label'])) {
  172. $label = $optionSpec['label'];
  173. }
  174. if (isset($optionSpec['selected'])) {
  175. $selected = $optionSpec['selected'];
  176. }
  177. if (isset($optionSpec['disabled'])) {
  178. $disabled = $optionSpec['disabled'];
  179. }
  180. if (ArrayUtils::inArray($value, $selectedOptions)) {
  181. $selected = true;
  182. }
  183. if (null !== ($translator = $this->getTranslator())) {
  184. $label = $translator->translate(
  185. $label,
  186. $this->getTranslatorTextDomain()
  187. );
  188. }
  189. $attributes = compact('value', 'selected', 'disabled');
  190. if (isset($optionSpec['attributes']) && is_array($optionSpec['attributes'])) {
  191. $attributes = array_merge($attributes, $optionSpec['attributes']);
  192. }
  193. $this->validTagAttributes = $this->validOptionAttributes;
  194. $optionStrings[] = sprintf(
  195. $template,
  196. $this->createAttributesString($attributes),
  197. $escapeHtml($label)
  198. );
  199. }
  200. return implode("\n", $optionStrings);
  201. }
  202. /**
  203. * Render an optgroup
  204. *
  205. * See {@link renderOptions()} for the options specification. Basically,
  206. * an optgroup is simply an option that has an additional "options" key
  207. * with an array following the specification for renderOptions().
  208. *
  209. * @param array $optgroup
  210. * @param array $selectedOptions
  211. * @return string
  212. */
  213. public function renderOptgroup(array $optgroup, array $selectedOptions = array())
  214. {
  215. $template = '<optgroup%s>%s</optgroup>';
  216. $options = array();
  217. if (isset($optgroup['options']) && is_array($optgroup['options'])) {
  218. $options = $optgroup['options'];
  219. unset($optgroup['options']);
  220. }
  221. $this->validTagAttributes = $this->validOptgroupAttributes;
  222. $attributes = $this->createAttributesString($optgroup);
  223. if (!empty($attributes)) {
  224. $attributes = ' ' . $attributes;
  225. }
  226. return sprintf(
  227. $template,
  228. $attributes,
  229. $this->renderOptions($options, $selectedOptions)
  230. );
  231. }
  232. /**
  233. * Ensure that the value is set appropriately
  234. *
  235. * If the element's value attribute is an array, but there is no multiple
  236. * attribute, or that attribute does not evaluate to true, then we have
  237. * a domain issue -- you cannot have multiple options selected unless the
  238. * multiple attribute is present and enabled.
  239. *
  240. * @param mixed $value
  241. * @param array $attributes
  242. * @return array
  243. * @throws Exception\DomainException
  244. */
  245. protected function validateMultiValue($value, array $attributes)
  246. {
  247. if (null === $value) {
  248. return array();
  249. }
  250. if (!is_array($value)) {
  251. return (array) $value;
  252. }
  253. if (!isset($attributes['multiple']) || !$attributes['multiple']) {
  254. throw new Exception\DomainException(sprintf(
  255. '%s does not allow specifying multiple selected values when the element does not have a multiple attribute set to a boolean true',
  256. __CLASS__
  257. ));
  258. }
  259. return $value;
  260. }
  261. protected function renderHiddenElement(ElementInterface $element)
  262. {
  263. $hiddenElement = new Hidden($element->getName());
  264. $hiddenElement->setValue($element->getUnselectedValue());
  265. return $this->getFormHiddenHelper()->__invoke($hiddenElement);
  266. }
  267. /**
  268. * @return FormHidden
  269. */
  270. protected function getFormHiddenHelper()
  271. {
  272. if (!$this->formHiddenHelper) {
  273. if (method_exists($this->view, 'plugin')) {
  274. $this->formHiddenHelper = $this->view->plugin('formhidden');
  275. }
  276. if (!$this->formHiddenHelper instanceof FormHidden) {
  277. $this->formHiddenHelper = new FormHidden();
  278. }
  279. }
  280. return $this->formHiddenHelper;
  281. }
  282. }