PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/zendframework/zend-form/src/Annotation/ElementAnnotationsListener.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 445 lines | 232 code | 49 blank | 164 comment | 31 complexity | 1c17a65d0a27e9f15ef269bf7a3c65ef 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\Annotation;
  10. use Zend\EventManager\EventManagerInterface;
  11. use Zend\Stdlib\ArrayObject;
  12. /**
  13. * Default listeners for element annotations
  14. *
  15. * Defines and attaches a set of default listeners for element annotations
  16. * (which are defined on object properties). These include:
  17. *
  18. * - AllowEmpty
  19. * - Attributes
  20. * - ErrorMessage
  21. * - Filter
  22. * - Flags
  23. * - Input
  24. * - Hydrator
  25. * - Object and Instance (the latter is preferred starting in 2.4)
  26. * - Required
  27. * - Type
  28. * - Validator
  29. *
  30. * See the individual annotation classes for more details. The handlers registered
  31. * work with the annotation values, as well as the element and input specification
  32. * passed in the event object.
  33. */
  34. class ElementAnnotationsListener extends AbstractAnnotationsListener
  35. {
  36. /**
  37. * {@inheritDoc}
  38. */
  39. public function attach(EventManagerInterface $events)
  40. {
  41. $this->listeners[] = $events->attach('configureElement', array($this, 'handleAllowEmptyAnnotation'));
  42. $this->listeners[] = $events->attach('configureElement', array($this, 'handleAttributesAnnotation'));
  43. $this->listeners[] = $events->attach('configureElement', array($this, 'handleComposedObjectAnnotation'));
  44. $this->listeners[] = $events->attach('configureElement', array($this, 'handleContinueIfEmptyAnnotation'));
  45. $this->listeners[] = $events->attach('configureElement', array($this, 'handleErrorMessageAnnotation'));
  46. $this->listeners[] = $events->attach('configureElement', array($this, 'handleFilterAnnotation'));
  47. $this->listeners[] = $events->attach('configureElement', array($this, 'handleFlagsAnnotation'));
  48. $this->listeners[] = $events->attach('configureElement', array($this, 'handleHydratorAnnotation'));
  49. $this->listeners[] = $events->attach('configureElement', array($this, 'handleInputAnnotation'));
  50. $this->listeners[] = $events->attach('configureElement', array($this, 'handleObjectAnnotation'));
  51. $this->listeners[] = $events->attach('configureElement', array($this, 'handleOptionsAnnotation'));
  52. $this->listeners[] = $events->attach('configureElement', array($this, 'handleRequiredAnnotation'));
  53. $this->listeners[] = $events->attach('configureElement', array($this, 'handleTypeAnnotation'));
  54. $this->listeners[] = $events->attach('configureElement', array($this, 'handleValidatorAnnotation'));
  55. $this->listeners[] = $events->attach('discoverName', array($this, 'handleNameAnnotation'));
  56. $this->listeners[] = $events->attach('discoverName', array($this, 'discoverFallbackName'));
  57. $this->listeners[] = $events->attach('checkForExclude', array($this, 'handleExcludeAnnotation'));
  58. }
  59. /**
  60. * Handle the AllowEmpty annotation
  61. *
  62. * Sets the allow_empty flag on the input specification array.
  63. *
  64. * @param \Zend\EventManager\EventInterface $e
  65. * @return void
  66. */
  67. public function handleAllowEmptyAnnotation($e)
  68. {
  69. $annotation = $e->getParam('annotation');
  70. if (!$annotation instanceof AllowEmpty) {
  71. return;
  72. }
  73. $inputSpec = $e->getParam('inputSpec');
  74. $inputSpec['allow_empty'] = true;
  75. }
  76. /**
  77. * Handle the Attributes annotation
  78. *
  79. * Sets the attributes array of the element specification.
  80. *
  81. * @param \Zend\EventManager\EventInterface $e
  82. * @return void
  83. */
  84. public function handleAttributesAnnotation($e)
  85. {
  86. $annotation = $e->getParam('annotation');
  87. if (!$annotation instanceof Attributes) {
  88. return;
  89. }
  90. $elementSpec = $e->getParam('elementSpec');
  91. if (isset($elementSpec['spec']['attributes'])) {
  92. $elementSpec['spec']['attributes'] = array_merge(
  93. $elementSpec['spec']['attributes'],
  94. $annotation->getAttributes()
  95. );
  96. return;
  97. }
  98. $elementSpec['spec']['attributes'] = $annotation->getAttributes();
  99. }
  100. /**
  101. * Allow creating fieldsets from composed entity properties
  102. *
  103. * @param \Zend\EventManager\EventInterface $e
  104. * @return void
  105. */
  106. public function handleComposedObjectAnnotation($e)
  107. {
  108. $annotation = $e->getParam('annotation');
  109. if (!$annotation instanceof ComposedObject) {
  110. return;
  111. }
  112. $class = $annotation->getComposedObject();
  113. $annotationManager = $e->getTarget();
  114. $specification = $annotationManager->getFormSpecification($class);
  115. $name = $e->getParam('name');
  116. $elementSpec = $e->getParam('elementSpec');
  117. if ($annotation->isCollection()) {
  118. // Compose specification as a fieldset into parent form/fieldset
  119. if (!isset($specification['type'])) {
  120. //use input filter provider fieldset so we can compose the input filter into the fieldset
  121. //it is assumed that if someone uses a custom fieldset, they will take care of the input
  122. //filtering themselves or consume the input_filter_spec option.
  123. $specification['type'] = 'Zend\Form\InputFilterProviderFieldset';
  124. }
  125. $inputFilter = $specification['input_filter'];
  126. if (!isset($inputFilter['type'])) {
  127. $inputFilter['type'] = 'Zend\InputFilter\InputFilter';
  128. }
  129. unset($specification['input_filter']);
  130. $elementSpec['spec']['type'] = 'Zend\Form\Element\Collection';
  131. $elementSpec['spec']['name'] = $name;
  132. $elementSpec['spec']['options'] = new ArrayObject($this->mergeOptions($elementSpec, $annotation));
  133. $elementSpec['spec']['options']['target_element'] = $specification;
  134. $elementSpec['spec']['options']['target_element']['options']['input_filter_spec'] = $inputFilter;
  135. if (isset($specification['hydrator'])) {
  136. $elementSpec['spec']['hydrator'] = $specification['hydrator'];
  137. }
  138. } else {
  139. // Compose input filter into parent input filter
  140. $inputFilter = $specification['input_filter'];
  141. if (!isset($inputFilter['type'])) {
  142. $inputFilter['type'] = 'Zend\InputFilter\InputFilter';
  143. }
  144. $e->setParam('inputSpec', $inputFilter);
  145. unset($specification['input_filter']);
  146. // Compose specification as a fieldset into parent form/fieldset
  147. if (!isset($specification['type'])) {
  148. $specification['type'] = 'Zend\Form\Fieldset';
  149. }
  150. if (isset($elementSpec['spec']['options'])) {
  151. $specification['options'] = isset($specification['options']) ? $specification['options'] : array();
  152. $specification['options'] = array_merge($elementSpec['spec']['options'], $specification['options']);
  153. }
  154. // Add element spec:
  155. $elementSpec['spec'] = $specification;
  156. $elementSpec['spec']['name'] = $name;
  157. $elementSpec['spec']['options'] = new ArrayObject($this->mergeOptions($elementSpec, $annotation));
  158. }
  159. }
  160. /**
  161. * Handle the ContinueIfEmpty annotation
  162. *
  163. * Sets the continue_if_empty flag on the input specification array.
  164. *
  165. * @param \Zend\EventManager\EventInterface $e
  166. * @return void
  167. */
  168. public function handleContinueIfEmptyAnnotation($e)
  169. {
  170. $annotation = $e->getParam('annotation');
  171. if (!$annotation instanceof ContinueIfEmpty) {
  172. return;
  173. }
  174. $inputSpec = $e->getParam('inputSpec');
  175. $inputSpec['continue_if_empty'] = true;
  176. }
  177. /**
  178. * Handle the ErrorMessage annotation
  179. *
  180. * Sets the error_message of the input specification.
  181. *
  182. * @param \Zend\EventManager\EventInterface $e
  183. * @return void
  184. */
  185. public function handleErrorMessageAnnotation($e)
  186. {
  187. $annotation = $e->getParam('annotation');
  188. if (!$annotation instanceof ErrorMessage) {
  189. return;
  190. }
  191. $inputSpec = $e->getParam('inputSpec');
  192. $inputSpec['error_message'] = $annotation->getMessage();
  193. }
  194. /**
  195. * Determine if the element has been marked to exclude from the definition
  196. *
  197. * @param \Zend\EventManager\EventInterface $e
  198. * @return bool
  199. */
  200. public function handleExcludeAnnotation($e)
  201. {
  202. $annotations = $e->getParam('annotations');
  203. if ($annotations->hasAnnotation('Zend\Form\Annotation\Exclude')) {
  204. return true;
  205. }
  206. return false;
  207. }
  208. /**
  209. * Handle the Filter annotation
  210. *
  211. * Adds a filter to the filter chain specification for the input.
  212. *
  213. * @param \Zend\EventManager\EventInterface $e
  214. * @return void
  215. */
  216. public function handleFilterAnnotation($e)
  217. {
  218. $annotation = $e->getParam('annotation');
  219. if (!$annotation instanceof Filter) {
  220. return;
  221. }
  222. $inputSpec = $e->getParam('inputSpec');
  223. if (!isset($inputSpec['filters'])) {
  224. $inputSpec['filters'] = array();
  225. }
  226. $inputSpec['filters'][] = $annotation->getFilter();
  227. }
  228. /**
  229. * Handle the Flags annotation
  230. *
  231. * Sets the element flags in the specification (used typically for setting
  232. * priority).
  233. *
  234. * @param \Zend\EventManager\EventInterface $e
  235. * @return void
  236. */
  237. public function handleFlagsAnnotation($e)
  238. {
  239. $annotation = $e->getParam('annotation');
  240. if (!$annotation instanceof Flags) {
  241. return;
  242. }
  243. $elementSpec = $e->getParam('elementSpec');
  244. $elementSpec['flags'] = $annotation->getFlags();
  245. }
  246. /**
  247. * Handle the Hydrator annotation
  248. *
  249. * Sets the hydrator class to use in the fieldset specification.
  250. *
  251. * @param \Zend\EventManager\EventInterface $e
  252. * @return void
  253. */
  254. public function handleHydratorAnnotation($e)
  255. {
  256. $annotation = $e->getParam('annotation');
  257. if (!$annotation instanceof Hydrator) {
  258. return;
  259. }
  260. $elementSpec = $e->getParam('elementSpec');
  261. $elementSpec['spec']['hydrator'] = $annotation->getHydrator();
  262. }
  263. /**
  264. * Handle the Input annotation
  265. *
  266. * Sets the filter specification for the current element to the specified
  267. * input class name.
  268. *
  269. * @param \Zend\EventManager\EventInterface $e
  270. * @return void
  271. */
  272. public function handleInputAnnotation($e)
  273. {
  274. $annotation = $e->getParam('annotation');
  275. if (!$annotation instanceof Input) {
  276. return;
  277. }
  278. $inputSpec = $e->getParam('inputSpec');
  279. $inputSpec['type'] = $annotation->getInput();
  280. }
  281. /**
  282. * Handle the Object and Instance annotations
  283. *
  284. * Sets the object to bind to the form or fieldset
  285. *
  286. * @param \Zend\EventManager\EventInterface $e
  287. * @return void
  288. */
  289. public function handleObjectAnnotation($e)
  290. {
  291. $annotation = $e->getParam('annotation');
  292. // Only need to typehint on Instance, as Object extends it
  293. if (! $annotation instanceof Instance) {
  294. return;
  295. }
  296. $elementSpec = $e->getParam('elementSpec');
  297. $elementSpec['spec']['object'] = $annotation->getObject();
  298. }
  299. /**
  300. * Handle the Options annotation
  301. *
  302. * Sets the element options in the specification.
  303. *
  304. * @param \Zend\EventManager\EventInterface $e
  305. * @return void
  306. */
  307. public function handleOptionsAnnotation($e)
  308. {
  309. $annotation = $e->getParam('annotation');
  310. if (!$annotation instanceof Options) {
  311. return;
  312. }
  313. $elementSpec = $e->getParam('elementSpec');
  314. $elementSpec['spec']['options'] = $this->mergeOptions($elementSpec, $annotation);
  315. }
  316. /**
  317. * Handle the Required annotation
  318. *
  319. * Sets the required flag on the input based on the annotation value.
  320. *
  321. * @param \Zend\EventManager\EventInterface $e
  322. * @return void
  323. */
  324. public function handleRequiredAnnotation($e)
  325. {
  326. $annotation = $e->getParam('annotation');
  327. if (!$annotation instanceof Required) {
  328. return;
  329. }
  330. $required = (bool) $annotation->getRequired();
  331. $inputSpec = $e->getParam('inputSpec');
  332. $inputSpec['required'] = $required;
  333. if ($required) {
  334. $elementSpec = $e->getParam('elementSpec');
  335. if (!isset($elementSpec['spec']['attributes'])) {
  336. $elementSpec['spec']['attributes'] = array();
  337. }
  338. $elementSpec['spec']['attributes']['required'] = 'required';
  339. }
  340. }
  341. /**
  342. * Handle the Type annotation
  343. *
  344. * Sets the element class type to use in the element specification.
  345. *
  346. * @param \Zend\EventManager\EventInterface $e
  347. * @return void
  348. */
  349. public function handleTypeAnnotation($e)
  350. {
  351. $annotation = $e->getParam('annotation');
  352. if (!$annotation instanceof Type) {
  353. return;
  354. }
  355. $elementSpec = $e->getParam('elementSpec');
  356. $elementSpec['spec']['type'] = $annotation->getType();
  357. }
  358. /**
  359. * Handle the Validator annotation
  360. *
  361. * Adds a validator to the validator chain of the input specification.
  362. *
  363. * @param \Zend\EventManager\EventInterface $e
  364. * @return void
  365. */
  366. public function handleValidatorAnnotation($e)
  367. {
  368. $annotation = $e->getParam('annotation');
  369. if (!$annotation instanceof Validator) {
  370. return;
  371. }
  372. $inputSpec = $e->getParam('inputSpec');
  373. if (!isset($inputSpec['validators'])) {
  374. $inputSpec['validators'] = array();
  375. }
  376. $inputSpec['validators'][] = $annotation->getValidator();
  377. }
  378. /**
  379. * @param array|\ArrayAccess $elementSpec
  380. * @param ComposedObject|Options $annotation
  381. *
  382. * @return array
  383. */
  384. private function mergeOptions($elementSpec, $annotation)
  385. {
  386. if (isset($elementSpec['spec']['options'])) {
  387. if (is_array($elementSpec['spec']['options'])) {
  388. return array_merge($elementSpec['spec']['options'], $annotation->getOptions());
  389. }
  390. if ($elementSpec['spec']['options'] instanceof ArrayObject) {
  391. return array_merge($elementSpec['spec']['options']->getArrayCopy(), $annotation->getOptions());
  392. }
  393. }
  394. return $annotation->getOptions();
  395. }
  396. }