PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/InputFilter/Factory.php

https://github.com/pborreli/zf2
PHP | 297 lines | 213 code | 27 blank | 57 comment | 32 complexity | e87c9ad98511d2783e60a0820418c898 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-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_InputFilter
  9. */
  10. namespace Zend\InputFilter;
  11. use Traversable;
  12. use Zend\Filter\FilterChain;
  13. use Zend\Stdlib\ArrayUtils;
  14. use Zend\Validator\ValidatorChain;
  15. use Zend\Validator\ValidatorInterface;
  16. /**
  17. * @category Zend
  18. * @package Zend_InputFilter
  19. */
  20. class Factory
  21. {
  22. protected $defaultFilterChain;
  23. protected $defaultValidatorChain;
  24. /**
  25. * Set default filter chain to use
  26. *
  27. * @param FilterChain $filterChain
  28. * @return Factory
  29. */
  30. public function setDefaultFilterChain(FilterChain $filterChain)
  31. {
  32. $this->defaultFilterChain = $filterChain;
  33. return $this;
  34. }
  35. /**
  36. * Get default filter chain, if any
  37. *
  38. * @return null|FilterChain
  39. */
  40. public function getDefaultFilterChain()
  41. {
  42. return $this->defaultFilterChain;
  43. }
  44. /**
  45. * Clear the default filter chain (i.e., don't inject one into new inputs)
  46. *
  47. * @return void
  48. */
  49. public function clearDefaultFilterChain()
  50. {
  51. $this->defaultFilterChain = null;
  52. }
  53. /**
  54. * Set default validator chain to use
  55. *
  56. * @param ValidatorChain $validatorChain
  57. * @return Factory
  58. */
  59. public function setDefaultValidatorChain(ValidatorChain $validatorChain)
  60. {
  61. $this->defaultValidatorChain = $validatorChain;
  62. return $this;
  63. }
  64. /**
  65. * Get default validator chain, if any
  66. *
  67. * @return null|ValidatorChain
  68. */
  69. public function getDefaultValidatorChain()
  70. {
  71. return $this->defaultValidatorChain;
  72. }
  73. /**
  74. * Clear the default validator chain (i.e., don't inject one into new inputs)
  75. *
  76. * @return void
  77. */
  78. public function clearDefaultValidatorChain()
  79. {
  80. $this->defaultValidatorChain = null;
  81. }
  82. /**
  83. * Factory for input objects
  84. *
  85. * @param array|Traversable $inputSpecification
  86. * @return InputInterface|InputFilterInterface
  87. */
  88. public function createInput($inputSpecification)
  89. {
  90. if (!is_array($inputSpecification) && !$inputSpecification instanceof Traversable) {
  91. throw new Exception\InvalidArgumentException(sprintf(
  92. '%s expects an array or Traversable; received "%s"',
  93. __METHOD__,
  94. (is_object($inputSpecification) ? get_class($inputSpecification) : gettype($inputSpecification))
  95. ));
  96. }
  97. if ($inputSpecification instanceof Traversable) {
  98. $inputSpecification = ArrayUtils::iteratorToArray($inputSpecification);
  99. }
  100. $class = 'Zend\InputFilter\Input';
  101. if (isset($inputSpecification['type'])) {
  102. $class = $inputSpecification['type'];
  103. if (!class_exists($class)) {
  104. throw new Exception\RuntimeException(sprintf(
  105. 'Input factory expects the "type" to be a valid class; received "%s"',
  106. $class
  107. ));
  108. }
  109. }
  110. $input = new $class();
  111. if ($input instanceof InputFilterInterface) {
  112. return $this->createInputFilter($inputSpecification);
  113. }
  114. if (!$input instanceof InputInterface) {
  115. throw new Exception\RuntimeException(sprintf(
  116. 'Input factory expects the "type" to be a class implementing %s; received "%s"',
  117. 'Zend\InputFilter\InputInterface',
  118. $class
  119. ));
  120. }
  121. if ($this->defaultFilterChain) {
  122. $input->setFilterChain(clone $this->defaultFilterChain);
  123. }
  124. if ($this->defaultValidatorChain) {
  125. $input->setValidatorChain(clone $this->defaultValidatorChain);
  126. }
  127. foreach ($inputSpecification as $key => $value) {
  128. switch ($key) {
  129. case 'name':
  130. $input->setName($value);
  131. break;
  132. case 'required':
  133. $input->setRequired($value);
  134. if (!isset($inputSpecification['allow_empty'])) {
  135. $input->setAllowEmpty(!$value);
  136. }
  137. break;
  138. case 'allow_empty':
  139. $input->setAllowEmpty($value);
  140. if (!isset($inputSpecification['required'])) {
  141. $input->setRequired(!$value);
  142. }
  143. break;
  144. case 'filters':
  145. if (!is_array($value) && !$value instanceof Traversable) {
  146. throw new Exception\RuntimeException(sprintf(
  147. '%s expects the value associated with "filters" to be an array/Traversable of filters or filter specifications; received "%s"',
  148. __METHOD__,
  149. (is_object($value) ? get_class($value) : gettype($value))
  150. ));
  151. }
  152. $this->populateFilters($input->getFilterChain(), $value);
  153. break;
  154. case 'validators':
  155. if (!is_array($value) && !$value instanceof Traversable) {
  156. throw new Exception\RuntimeException(sprintf(
  157. '%s expects the value associated with "validators" to be an array/Traversable of validators or validator specifications; received "%s"',
  158. __METHOD__,
  159. (is_object($value) ? get_class($value) : gettype($value))
  160. ));
  161. }
  162. $this->populateValidators($input->getValidatorChain(), $value);
  163. break;
  164. default:
  165. // ignore unknown keys
  166. break;
  167. }
  168. }
  169. return $input;
  170. }
  171. /**
  172. * Factory for input filters
  173. *
  174. * @param array|Traversable $inputFilterSpecification
  175. * @return InputFilterInterface
  176. */
  177. public function createInputFilter($inputFilterSpecification)
  178. {
  179. if (!is_array($inputFilterSpecification) && !$inputFilterSpecification instanceof Traversable) {
  180. throw new Exception\InvalidArgumentException(sprintf(
  181. '%s expects an array or Traversable; received "%s"',
  182. __METHOD__,
  183. (is_object($inputFilterSpecification) ? get_class($inputFilterSpecification) : gettype($inputFilterSpecification))
  184. ));
  185. }
  186. if ($inputFilterSpecification instanceof Traversable) {
  187. $inputFilterSpecification = ArrayUtils::iteratorToArray($inputFilterSpecification);
  188. }
  189. $class = 'Zend\InputFilter\InputFilter';
  190. if (isset($inputFilterSpecification['type'])) {
  191. $class = $inputFilterSpecification['type'];
  192. if (!class_exists($class)) {
  193. throw new Exception\RuntimeException(sprintf(
  194. 'Input factory expects the "type" to be a valid class; received "%s"',
  195. $class
  196. ));
  197. }
  198. unset($inputFilterSpecification['type']);
  199. }
  200. $inputFilter = new $class();
  201. if (!$inputFilter instanceof InputFilterInterface) {
  202. throw new Exception\RuntimeException(sprintf(
  203. 'InputFilter factory expects the "type" to be a class implementing %s; received "%s"',
  204. 'Zend\InputFilter\InputFilterInterface',
  205. $class
  206. ));
  207. }
  208. foreach ($inputFilterSpecification as $key => $value) {
  209. $input = $this->createInput($value);
  210. $inputFilter->add($input, $key);
  211. }
  212. return $inputFilter;
  213. }
  214. protected function populateFilters(FilterChain $chain, $filters)
  215. {
  216. foreach ($filters as $filter) {
  217. if (is_object($filter) || is_callable($filter)) {
  218. $chain->attach($filter);
  219. continue;
  220. }
  221. if (is_array($filter)) {
  222. if (!isset($filter['name'])) {
  223. throw new Exception\RuntimeException(
  224. 'Invalid filter specification provided; does not include "name" key'
  225. );
  226. }
  227. $name = $filter['name'];
  228. $options = array();
  229. if (isset($filter['options'])) {
  230. $options = $filter['options'];
  231. }
  232. $chain->attachByName($name, $options);
  233. continue;
  234. }
  235. throw new Exception\RuntimeException(
  236. 'Invalid filter specification provided; was neither a filter instance nor an array specification'
  237. );
  238. }
  239. }
  240. protected function populateValidators(ValidatorChain $chain, $validators)
  241. {
  242. foreach ($validators as $validator) {
  243. if ($validator instanceof ValidatorInterface) {
  244. $chain->addValidator($validator);
  245. continue;
  246. }
  247. if (is_array($validator)) {
  248. if (!isset($validator['name'])) {
  249. throw new Exception\RuntimeException(
  250. 'Invalid validator specification provided; does not include "name" key'
  251. );
  252. }
  253. $name = $validator['name'];
  254. $options = array();
  255. if (isset($validator['options'])) {
  256. $options = $validator['options'];
  257. }
  258. $breakChainOnFailure = false;
  259. if (isset($validator['break_chain_on_failure'])) {
  260. $breakChainOnFailure = $validator['break_chain_on_failure'];
  261. }
  262. $chain->addByName($name, $options, $breakChainOnFailure);
  263. continue;
  264. }
  265. throw new Exception\RuntimeException(
  266. 'Invalid validator specification provided; was neither a validator instance nor an array specification'
  267. );
  268. }
  269. }
  270. }