PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/zendframework/zendframework/library/Zend/Filter/Boolean.php

https://bitbucket.org/pcelta/zf2
PHP | 302 lines | 193 code | 34 blank | 75 comment | 64 complexity | db1f09861e961cde383a1b2b8769fd3e 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_Filter
  9. */
  10. namespace Zend\Filter;
  11. use Traversable;
  12. use Zend\Stdlib\ArrayUtils;
  13. /**
  14. * @category Zend
  15. * @package Zend_Filter
  16. */
  17. class Boolean extends AbstractFilter
  18. {
  19. const TYPE_BOOLEAN = 1;
  20. const TYPE_INTEGER = 2;
  21. const TYPE_FLOAT = 4;
  22. const TYPE_STRING = 8;
  23. const TYPE_ZERO_STRING = 16;
  24. const TYPE_EMPTY_ARRAY = 32;
  25. const TYPE_NULL = 64;
  26. const TYPE_PHP = 127;
  27. const TYPE_FALSE_STRING = 128;
  28. const TYPE_LOCALIZED = 256;
  29. const TYPE_ALL = 511;
  30. /**
  31. * @var array
  32. */
  33. protected $constants = array(
  34. self::TYPE_BOOLEAN => 'boolean',
  35. self::TYPE_INTEGER => 'integer',
  36. self::TYPE_FLOAT => 'float',
  37. self::TYPE_STRING => 'string',
  38. self::TYPE_ZERO_STRING => 'zero',
  39. self::TYPE_EMPTY_ARRAY => 'array',
  40. self::TYPE_NULL => 'null',
  41. self::TYPE_PHP => 'php',
  42. self::TYPE_FALSE_STRING => 'false',
  43. self::TYPE_LOCALIZED => 'localized',
  44. self::TYPE_ALL => 'all',
  45. );
  46. /**
  47. * @var array
  48. */
  49. protected $options = array(
  50. 'type' => self::TYPE_PHP,
  51. 'casting' => true,
  52. 'translations' => array(),
  53. );
  54. /**
  55. * Constructor
  56. *
  57. * @param array|Traversable|int|null $typeOrOptions
  58. * @param bool $casting
  59. * @param array $translations
  60. */
  61. public function __construct($typeOrOptions = null, $casting = true, $translations = array())
  62. {
  63. if ($typeOrOptions !== null) {
  64. if ($typeOrOptions instanceof Traversable) {
  65. $typeOrOptions = ArrayUtils::iteratorToArray($typeOrOptions);
  66. }
  67. if (is_array($typeOrOptions)) {
  68. if (isset($typeOrOptions['type'])
  69. || isset($typeOrOptions['casting'])
  70. || isset($typeOrOptions['translations']))
  71. {
  72. $this->setOptions($typeOrOptions);
  73. } else {
  74. $this->setType($typeOrOptions);
  75. $this->setCasting($casting);
  76. $this->setTranslations($translations);
  77. }
  78. } else {
  79. $this->setType($typeOrOptions);
  80. $this->setCasting($casting);
  81. $this->setTranslations($translations);
  82. }
  83. }
  84. }
  85. /**
  86. * Set boolean types
  87. *
  88. * @param integer|array $type
  89. * @throws Exception\InvalidArgumentException
  90. * @return Boolean
  91. */
  92. public function setType($type = null)
  93. {
  94. if (is_array($type)) {
  95. $detected = 0;
  96. foreach ($type as $value) {
  97. if (is_int($value)) {
  98. $detected += $value;
  99. } elseif (in_array($value, $this->constants)) {
  100. $detected += array_search($value, $this->constants);
  101. }
  102. }
  103. $type = $detected;
  104. } elseif (is_string($type) && in_array($type, $this->constants)) {
  105. $type = array_search($type, $this->constants);
  106. }
  107. if (!is_int($type) || ($type < 0) || ($type > self::TYPE_ALL)) {
  108. throw new Exception\InvalidArgumentException(sprintf(
  109. 'Unknown type value "%s" (%s)',
  110. $type,
  111. gettype($type)
  112. ));
  113. }
  114. $this->options['type'] = $type;
  115. return $this;
  116. }
  117. /**
  118. * Returns defined boolean types
  119. *
  120. * @return int
  121. */
  122. public function getType()
  123. {
  124. return $this->options['type'];
  125. }
  126. /**
  127. * Set the working mode
  128. *
  129. * @param boolean $flag When true this filter works like cast
  130. * When false it recognises only true and false
  131. * and all other values are returned as is
  132. * @return Boolean
  133. */
  134. public function setCasting($flag = true)
  135. {
  136. $this->options['casting'] = (boolean) $flag;
  137. return $this;
  138. }
  139. /**
  140. * Returns the casting option
  141. *
  142. * @return boolean
  143. */
  144. public function getCasting()
  145. {
  146. return $this->options['casting'];
  147. }
  148. /**
  149. * @param array|Traversable $translations
  150. * @throws Exception\InvalidArgumentException
  151. * @return Boolean
  152. */
  153. public function setTranslations($translations)
  154. {
  155. if (!is_array($translations) && !$translations instanceof Traversable) {
  156. throw new Exception\InvalidArgumentException(sprintf(
  157. '"%s" expects an array or Traversable; received "%s"',
  158. __METHOD__,
  159. (is_object($translations) ? get_class($translations) : gettype($translations))
  160. ));
  161. }
  162. foreach ($translations as $message => $flag) {
  163. $this->options['translations'][$message] = (bool) $flag;
  164. }
  165. return $this;
  166. }
  167. /**
  168. * @return array
  169. */
  170. public function getTranslations()
  171. {
  172. return $this->options['translations'];
  173. }
  174. /**
  175. * Defined by Zend\Filter\FilterInterface
  176. *
  177. * Returns a boolean representation of $value
  178. *
  179. * @param string $value
  180. * @return string
  181. */
  182. public function filter($value)
  183. {
  184. $type = $this->getType();
  185. $casting = $this->getCasting();
  186. // LOCALIZED
  187. if ($type >= self::TYPE_LOCALIZED) {
  188. $type -= self::TYPE_LOCALIZED;
  189. if (is_string($value)) {
  190. if (isset($this->options['translations'][$value])) {
  191. return (bool) $this->options['translations'][$value];
  192. }
  193. }
  194. }
  195. // FALSE_STRING ('false')
  196. if ($type >= self::TYPE_FALSE_STRING) {
  197. $type -= self::TYPE_FALSE_STRING;
  198. if (is_string($value) && (strtolower($value) == 'false')) {
  199. return false;
  200. }
  201. if (!$casting && is_string($value) && (strtolower($value) == 'true')) {
  202. return true;
  203. }
  204. }
  205. // NULL (null)
  206. if ($type >= self::TYPE_NULL) {
  207. $type -= self::TYPE_NULL;
  208. if ($value === null) {
  209. return false;
  210. }
  211. }
  212. // EMPTY_ARRAY (array())
  213. if ($type >= self::TYPE_EMPTY_ARRAY) {
  214. $type -= self::TYPE_EMPTY_ARRAY;
  215. if (is_array($value) && ($value == array())) {
  216. return false;
  217. }
  218. }
  219. // ZERO_STRING ('0')
  220. if ($type >= self::TYPE_ZERO_STRING) {
  221. $type -= self::TYPE_ZERO_STRING;
  222. if (is_string($value) && ($value == '0')) {
  223. return false;
  224. }
  225. if (!$casting && (is_string($value)) && ($value == '1')) {
  226. return true;
  227. }
  228. }
  229. // STRING ('')
  230. if ($type >= self::TYPE_STRING) {
  231. $type -= self::TYPE_STRING;
  232. if (is_string($value) && ($value == '')) {
  233. return false;
  234. }
  235. }
  236. // FLOAT (0.0)
  237. if ($type >= self::TYPE_FLOAT) {
  238. $type -= self::TYPE_FLOAT;
  239. if (is_float($value) && ($value == 0.0)) {
  240. return false;
  241. }
  242. if (!$casting && is_float($value) && ($value == 1.0)) {
  243. return true;
  244. }
  245. }
  246. // INTEGER (0)
  247. if ($type >= self::TYPE_INTEGER) {
  248. $type -= self::TYPE_INTEGER;
  249. if (is_int($value) && ($value == 0)) {
  250. return false;
  251. }
  252. if (!$casting && is_int($value) && ($value == 1)) {
  253. return true;
  254. }
  255. }
  256. // BOOLEAN (false)
  257. if ($type >= self::TYPE_BOOLEAN) {
  258. $type -= self::TYPE_BOOLEAN;
  259. if (is_bool($value)) {
  260. return $value;
  261. }
  262. }
  263. if ($casting) {
  264. return true;
  265. }
  266. return $value;
  267. }
  268. }