PageRenderTime 40ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/monica/monica/vendor/zendframework/zendframework/library/Zend/Validator/File/Size.php

https://bitbucket.org/alexandretaz/maniac_divers
PHP | 365 lines | 206 code | 40 blank | 119 comment | 36 complexity | dce7c97e3c0fb882287d4e9a668abffd MD5 | raw file
Possible License(s): BSD-3-Clause
  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-2013 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Validator\File;
  10. use Zend\Stdlib\ErrorHandler;
  11. use Zend\Validator\AbstractValidator;
  12. use Zend\Validator\Exception;
  13. /**
  14. * Validator for the maximum size of a file up to a max of 2GB
  15. */
  16. class Size extends AbstractValidator
  17. {
  18. /**
  19. * @const string Error constants
  20. */
  21. const TOO_BIG = 'fileSizeTooBig';
  22. const TOO_SMALL = 'fileSizeTooSmall';
  23. const NOT_FOUND = 'fileSizeNotFound';
  24. /**
  25. * @var array Error message templates
  26. */
  27. protected $messageTemplates = array(
  28. self::TOO_BIG => "Maximum allowed size for file is '%max%' but '%size%' detected",
  29. self::TOO_SMALL => "Minimum expected size for file is '%min%' but '%size%' detected",
  30. self::NOT_FOUND => "File is not readable or does not exist",
  31. );
  32. /**
  33. * @var array Error message template variables
  34. */
  35. protected $messageVariables = array(
  36. 'min' => array('options' => 'min'),
  37. 'max' => array('options' => 'max'),
  38. 'size' => 'size',
  39. );
  40. /**
  41. * Detected size
  42. *
  43. * @var integer
  44. */
  45. protected $size;
  46. /**
  47. * Options for this validator
  48. *
  49. * @var array
  50. */
  51. protected $options = array(
  52. 'min' => null, // Minimum file size, if null there is no minimum
  53. 'max' => null, // Maximum file size, if null there is no maximum
  54. 'useByteString' => true, // Use byte string?
  55. );
  56. /**
  57. * Sets validator options
  58. *
  59. * If $options is a integer, it will be used as maximum file size
  60. * As Array is accepts the following keys:
  61. * 'min': Minimum file size
  62. * 'max': Maximum file size
  63. * 'useByteString': Use bytestring or real size for messages
  64. *
  65. * @param integer|array|\Traversable $options Options for the adapter
  66. */
  67. public function __construct($options = null)
  68. {
  69. if (is_string($options) || is_numeric($options)) {
  70. $options = array('max' => $options);
  71. }
  72. if (1 < func_num_args()) {
  73. $argv = func_get_args();
  74. array_shift($argv);
  75. $options['max'] = array_shift($argv);
  76. if (!empty($argv)) {
  77. $options['useByteString'] = array_shift($argv);
  78. }
  79. }
  80. parent::__construct($options);
  81. }
  82. /**
  83. * Should messages return bytes as integer or as string in SI notation
  84. *
  85. * @param bool $byteString Use bytestring ?
  86. * @return integer
  87. */
  88. public function useByteString($byteString = true)
  89. {
  90. $this->options['useByteString'] = (bool) $byteString;
  91. return $this;
  92. }
  93. /**
  94. * Will bytestring be used?
  95. *
  96. * @return bool
  97. */
  98. public function getByteString()
  99. {
  100. return $this->options['useByteString'];
  101. }
  102. /**
  103. * Returns the minimum file size
  104. *
  105. * @param bool $raw Whether or not to force return of the raw value (defaults off)
  106. * @return integer|string
  107. */
  108. public function getMin($raw = false)
  109. {
  110. $min = $this->options['min'];
  111. if (!$raw && $this->getByteString()) {
  112. $min = $this->toByteString($min);
  113. }
  114. return $min;
  115. }
  116. /**
  117. * Sets the minimum file size
  118. *
  119. * File size can be an integer or an byte string
  120. * This includes 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'
  121. * For example: 2000, 2MB, 0.2GB
  122. *
  123. * @param integer|string $min The minimum file size
  124. * @return Size Provides a fluent interface
  125. * @throws Exception\InvalidArgumentException When min is greater than max
  126. */
  127. public function setMin($min)
  128. {
  129. if (!is_string($min) and !is_numeric($min)) {
  130. throw new Exception\InvalidArgumentException('Invalid options to validator provided');
  131. }
  132. $min = (integer) $this->fromByteString($min);
  133. $max = $this->getMax(true);
  134. if (($max !== null) && ($min > $max)) {
  135. throw new Exception\InvalidArgumentException(
  136. 'The minimum must be less than or equal to the maximum file'
  137. ." size, but $min > $max");
  138. }
  139. $this->options['min'] = $min;
  140. return $this;
  141. }
  142. /**
  143. * Returns the maximum file size
  144. *
  145. * @param bool $raw Whether or not to force return of the raw value (defaults off)
  146. * @return integer|string
  147. */
  148. public function getMax($raw = false)
  149. {
  150. $max = $this->options['max'];
  151. if (!$raw && $this->getByteString()) {
  152. $max = $this->toByteString($max);
  153. }
  154. return $max;
  155. }
  156. /**
  157. * Sets the maximum file size
  158. *
  159. * File size can be an integer or an byte string
  160. * This includes 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'
  161. * For example: 2000, 2MB, 0.2GB
  162. *
  163. * @param integer|string $max The maximum file size
  164. * @return Size Provides a fluent interface
  165. * @throws Exception\InvalidArgumentException When max is smaller than min
  166. */
  167. public function setMax($max)
  168. {
  169. if (!is_string($max) && !is_numeric($max)) {
  170. throw new Exception\InvalidArgumentException('Invalid options to validator provided');
  171. }
  172. $max = (integer) $this->fromByteString($max);
  173. $min = $this->getMin(true);
  174. if (($min !== null) && ($max < $min)) {
  175. throw new Exception\InvalidArgumentException(
  176. 'The maximum must be greater than or equal to the minimum file'
  177. ." size, but $max < $min");
  178. }
  179. $this->options['max'] = $max;
  180. return $this;
  181. }
  182. /**
  183. * Retrieve current detected file size
  184. *
  185. * @return int
  186. */
  187. protected function getSize()
  188. {
  189. return $this->size;
  190. }
  191. /**
  192. * Set current size
  193. *
  194. * @param int $size
  195. * @return Size
  196. */
  197. protected function setSize($size)
  198. {
  199. $this->size = $size;
  200. return $this;
  201. }
  202. /**
  203. * Returns true if and only if the file size of $value is at least min and
  204. * not bigger than max (when max is not null).
  205. *
  206. * @param string|array $value File to check for size
  207. * @return bool
  208. */
  209. public function isValid($value)
  210. {
  211. if (is_array($value)) {
  212. if (!isset($value['tmp_name']) || !isset($value['name'])) {
  213. throw new Exception\InvalidArgumentException(
  214. 'Value array must be in $_FILES format'
  215. );
  216. }
  217. $file = $value['tmp_name'];
  218. $filename = $value['name'];
  219. } else {
  220. $file = $value;
  221. $filename = basename($file);
  222. }
  223. $this->setValue($filename);
  224. // Is file readable ?
  225. if (false === stream_resolve_include_path($file)) {
  226. $this->error(self::NOT_FOUND);
  227. return false;
  228. }
  229. // limited to 4GB files
  230. ErrorHandler::start();
  231. $size = sprintf("%u", filesize($file));
  232. ErrorHandler::stop();
  233. $this->size = $size;
  234. // Check to see if it's smaller than min size
  235. $min = $this->getMin(true);
  236. $max = $this->getMax(true);
  237. if (($min !== null) && ($size < $min)) {
  238. if ($this->getByteString()) {
  239. $this->options['min'] = $this->toByteString($min);
  240. $this->size = $this->toByteString($size);
  241. $this->error(self::TOO_SMALL);
  242. $this->options['min'] = $min;
  243. $this->size = $size;
  244. } else {
  245. $this->error(self::TOO_SMALL);
  246. }
  247. }
  248. // Check to see if it's larger than max size
  249. if (($max !== null) && ($max < $size)) {
  250. if ($this->getByteString()) {
  251. $this->options['max'] = $this->toByteString($max);
  252. $this->size = $this->toByteString($size);
  253. $this->error(self::TOO_BIG);
  254. $this->options['max'] = $max;
  255. $this->size = $size;
  256. } else {
  257. $this->error(self::TOO_BIG);
  258. }
  259. }
  260. if (count($this->getMessages()) > 0) {
  261. return false;
  262. }
  263. return true;
  264. }
  265. /**
  266. * Returns the formatted size
  267. *
  268. * @param integer $size
  269. * @return string
  270. */
  271. protected function toByteString($size)
  272. {
  273. $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
  274. for ($i=0; $size >= 1024 && $i < 9; $i++) {
  275. $size /= 1024;
  276. }
  277. return round($size, 2) . $sizes[$i];
  278. }
  279. /**
  280. * Returns the unformatted size
  281. *
  282. * @param string $size
  283. * @return integer
  284. */
  285. protected function fromByteString($size)
  286. {
  287. if (is_numeric($size)) {
  288. return (integer) $size;
  289. }
  290. $type = trim(substr($size, -2, 1));
  291. $value = substr($size, 0, -1);
  292. if (!is_numeric($value)) {
  293. $value = substr($value, 0, -1);
  294. }
  295. switch (strtoupper($type)) {
  296. case 'Y':
  297. $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
  298. break;
  299. case 'Z':
  300. $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
  301. break;
  302. case 'E':
  303. $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024);
  304. break;
  305. case 'P':
  306. $value *= (1024 * 1024 * 1024 * 1024 * 1024);
  307. break;
  308. case 'T':
  309. $value *= (1024 * 1024 * 1024 * 1024);
  310. break;
  311. case 'G':
  312. $value *= (1024 * 1024 * 1024);
  313. break;
  314. case 'M':
  315. $value *= (1024 * 1024);
  316. break;
  317. case 'K':
  318. $value *= 1024;
  319. break;
  320. default:
  321. break;
  322. }
  323. return $value;
  324. }
  325. }