PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/File/Size.php

https://bitbucket.org/sasezaki/mirror-zf1-standard-trunk-libraray-validate-dir
PHP | 404 lines | 209 code | 42 blank | 153 comment | 36 complexity | 79e91b85e1c5675c23134c62d588e689 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Validate
  17. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id$
  20. */
  21. /**
  22. * @see Zend_Validate_Abstract
  23. */
  24. require_once 'Zend/Validate/Abstract.php';
  25. /**
  26. * Validator for the maximum size of a file up to a max of 2GB
  27. *
  28. * @category Zend
  29. * @package Zend_Validate
  30. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. */
  33. class Zend_Validate_File_Size extends Zend_Validate_Abstract
  34. {
  35. /**#@+
  36. * @const string Error constants
  37. */
  38. const TOO_BIG = 'fileSizeTooBig';
  39. const TOO_SMALL = 'fileSizeTooSmall';
  40. const NOT_FOUND = 'fileSizeNotFound';
  41. /**#@-*/
  42. /**
  43. * @var array Error message templates
  44. */
  45. protected $_messageTemplates = array(
  46. self::TOO_BIG => "Maximum allowed size for file '%value%' is '%max%' but '%size%' detected",
  47. self::TOO_SMALL => "Minimum expected size for file '%value%' is '%min%' but '%size%' detected",
  48. self::NOT_FOUND => "File '%value%' is not readable or does not exist",
  49. );
  50. /**
  51. * @var array Error message template variables
  52. */
  53. protected $_messageVariables = array(
  54. 'min' => '_min',
  55. 'max' => '_max',
  56. 'size' => '_size',
  57. );
  58. /**
  59. * Minimum filesize
  60. * @var integer
  61. */
  62. protected $_min;
  63. /**
  64. * Maximum filesize
  65. *
  66. * If null, there is no maximum filesize
  67. *
  68. * @var integer|null
  69. */
  70. protected $_max;
  71. /**
  72. * Detected size
  73. *
  74. * @var integer
  75. */
  76. protected $_size;
  77. /**
  78. * Use bytestring ?
  79. *
  80. * @var boolean
  81. */
  82. protected $_useByteString = true;
  83. /**
  84. * Sets validator options
  85. *
  86. * If $options is a integer, it will be used as maximum filesize
  87. * As Array is accepts the following keys:
  88. * 'min': Minimum filesize
  89. * 'max': Maximum filesize
  90. * 'bytestring': Use bytestring or real size for messages
  91. *
  92. * @param integer|array $options Options for the adapter
  93. */
  94. public function __construct($options)
  95. {
  96. if ($options instanceof Zend_Config) {
  97. $options = $options->toArray();
  98. } elseif (is_string($options) || is_numeric($options)) {
  99. $options = array('max' => $options);
  100. } elseif (!is_array($options)) {
  101. require_once 'Zend/Validate/Exception.php';
  102. throw new Zend_Validate_Exception ('Invalid options to validator provided');
  103. }
  104. if (1 < func_num_args()) {
  105. $argv = func_get_args();
  106. array_shift($argv);
  107. $options['max'] = array_shift($argv);
  108. if (!empty($argv)) {
  109. $options['bytestring'] = array_shift($argv);
  110. }
  111. }
  112. if (isset($options['bytestring'])) {
  113. $this->setUseByteString($options['bytestring']);
  114. }
  115. if (isset($options['min'])) {
  116. $this->setMin($options['min']);
  117. }
  118. if (isset($options['max'])) {
  119. $this->setMax($options['max']);
  120. }
  121. }
  122. /**
  123. * Returns the minimum filesize
  124. *
  125. * @param boolean $byteString Use bytestring ?
  126. * @return integer
  127. */
  128. public function setUseByteString($byteString = true)
  129. {
  130. $this->_useByteString = (bool) $byteString;
  131. return $this;
  132. }
  133. /**
  134. * Will bytestring be used?
  135. *
  136. * @return boolean
  137. */
  138. public function useByteString()
  139. {
  140. return $this->_useByteString;
  141. }
  142. /**
  143. * Returns the minimum filesize
  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 getMin($raw = false)
  149. {
  150. $min = $this->_min;
  151. if (!$raw && $this->useByteString()) {
  152. $min = $this->_toByteString($min);
  153. }
  154. return $min;
  155. }
  156. /**
  157. * Sets the minimum filesize
  158. *
  159. * @param integer $min The minimum filesize
  160. * @throws Zend_Validate_Exception When min is greater than max
  161. * @return Zend_Validate_File_Size Provides a fluent interface
  162. */
  163. public function setMin($min)
  164. {
  165. if (!is_string($min) and !is_numeric($min)) {
  166. require_once 'Zend/Validate/Exception.php';
  167. throw new Zend_Validate_Exception ('Invalid options to validator provided');
  168. }
  169. $min = (integer) $this->_fromByteString($min);
  170. $max = $this->getMax(true);
  171. if (($max !== null) && ($min > $max)) {
  172. require_once 'Zend/Validate/Exception.php';
  173. throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum filesize, but $min >"
  174. . " $max");
  175. }
  176. $this->_min = $min;
  177. return $this;
  178. }
  179. /**
  180. * Returns the maximum filesize
  181. *
  182. * @param bool $raw Whether or not to force return of the raw value (defaults off)
  183. * @return integer|string
  184. */
  185. public function getMax($raw = false)
  186. {
  187. $max = $this->_max;
  188. if (!$raw && $this->useByteString()) {
  189. $max = $this->_toByteString($max);
  190. }
  191. return $max;
  192. }
  193. /**
  194. * Sets the maximum filesize
  195. *
  196. * @param integer $max The maximum filesize
  197. * @throws Zend_Validate_Exception When max is smaller than min
  198. * @return Zend_Validate_StringLength Provides a fluent interface
  199. */
  200. public function setMax($max)
  201. {
  202. if (!is_string($max) && !is_numeric($max)) {
  203. require_once 'Zend/Validate/Exception.php';
  204. throw new Zend_Validate_Exception ('Invalid options to validator provided');
  205. }
  206. $max = (integer) $this->_fromByteString($max);
  207. $min = $this->getMin(true);
  208. if (($min !== null) && ($max < $min)) {
  209. require_once 'Zend/Validate/Exception.php';
  210. throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum filesize, but "
  211. . "$max < $min");
  212. }
  213. $this->_max = $max;
  214. return $this;
  215. }
  216. /**
  217. * Retrieve current detected file size
  218. *
  219. * @return int
  220. */
  221. protected function _getSize()
  222. {
  223. return $this->_size;
  224. }
  225. /**
  226. * Set current size
  227. *
  228. * @param int $size
  229. * @return Zend_Validate_File_Size
  230. */
  231. protected function _setSize($size)
  232. {
  233. $this->_size = $size;
  234. return $this;
  235. }
  236. /**
  237. * Defined by Zend_Validate_Interface
  238. *
  239. * Returns true if and only if the filesize of $value is at least min and
  240. * not bigger than max (when max is not null).
  241. *
  242. * @param string $value Real file to check for size
  243. * @param array $file File data from Zend_File_Transfer
  244. * @return boolean
  245. */
  246. public function isValid($value, $file = null)
  247. {
  248. // Is file readable ?
  249. require_once 'Zend/Loader.php';
  250. if (!Zend_Loader::isReadable($value)) {
  251. return $this->_throw($file, self::NOT_FOUND);
  252. }
  253. // limited to 4GB files
  254. $size = sprintf("%u", @filesize($value));
  255. $this->_size = $size;
  256. // Check to see if it's smaller than min size
  257. $min = $this->getMin(true);
  258. $max = $this->getMax(true);
  259. if (($min !== null) && ($size < $min)) {
  260. if ($this->useByteString()) {
  261. $this->_min = $this->_toByteString($min);
  262. $this->_size = $this->_toByteString($size);
  263. $this->_throw($file, self::TOO_SMALL);
  264. $this->_min = $min;
  265. $this->_size = $size;
  266. } else {
  267. $this->_throw($file, self::TOO_SMALL);
  268. }
  269. }
  270. // Check to see if it's larger than max size
  271. if (($max !== null) && ($max < $size)) {
  272. if ($this->useByteString()) {
  273. $this->_max = $this->_toByteString($max);
  274. $this->_size = $this->_toByteString($size);
  275. $this->_throw($file, self::TOO_BIG);
  276. $this->_max = $max;
  277. $this->_size = $size;
  278. } else {
  279. $this->_throw($file, self::TOO_BIG);
  280. }
  281. }
  282. if (count($this->_messages) > 0) {
  283. return false;
  284. }
  285. return true;
  286. }
  287. /**
  288. * Returns the formatted size
  289. *
  290. * @param integer $size
  291. * @return string
  292. */
  293. protected function _toByteString($size)
  294. {
  295. $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
  296. for ($i=0; $size >= 1024 && $i < 9; $i++) {
  297. $size /= 1024;
  298. }
  299. return round($size, 2) . $sizes[$i];
  300. }
  301. /**
  302. * Returns the unformatted size
  303. *
  304. * @param string $size
  305. * @return integer
  306. */
  307. protected function _fromByteString($size)
  308. {
  309. if (is_numeric($size)) {
  310. return (integer) $size;
  311. }
  312. $type = trim(substr($size, -2, 1));
  313. $value = substr($size, 0, -1);
  314. if (!is_numeric($value)) {
  315. $value = substr($value, 0, -1);
  316. }
  317. switch (strtoupper($type)) {
  318. case 'Y':
  319. $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
  320. break;
  321. case 'Z':
  322. $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
  323. break;
  324. case 'E':
  325. $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024);
  326. break;
  327. case 'P':
  328. $value *= (1024 * 1024 * 1024 * 1024 * 1024);
  329. break;
  330. case 'T':
  331. $value *= (1024 * 1024 * 1024 * 1024);
  332. break;
  333. case 'G':
  334. $value *= (1024 * 1024 * 1024);
  335. break;
  336. case 'M':
  337. $value *= (1024 * 1024);
  338. break;
  339. case 'K':
  340. $value *= 1024;
  341. break;
  342. default:
  343. break;
  344. }
  345. return $value;
  346. }
  347. /**
  348. * Throws an error of the given type
  349. *
  350. * @param string $file
  351. * @param string $errorType
  352. * @return false
  353. */
  354. protected function _throw($file, $errorType)
  355. {
  356. if ($file !== null) {
  357. $this->_value = $file['name'];
  358. }
  359. $this->_error($errorType);
  360. return false;
  361. }
  362. }