File indexing completed on 2025-01-19 05:21:38
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Validate 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * @see Zend_Validate_Abstract 0024 */ 0025 // require_once 'Zend/Validate/Abstract.php'; 0026 0027 /** 0028 * Validator for the maximum size of a file up to a max of 2GB 0029 * 0030 * @category Zend 0031 * @package Zend_Validate 0032 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0033 * @license http://framework.zend.com/license/new-bsd New BSD License 0034 */ 0035 class Zend_Validate_File_Size extends Zend_Validate_Abstract 0036 { 0037 /**#@+ 0038 * @const string Error constants 0039 */ 0040 const TOO_BIG = 'fileSizeTooBig'; 0041 const TOO_SMALL = 'fileSizeTooSmall'; 0042 const NOT_FOUND = 'fileSizeNotFound'; 0043 /**#@-*/ 0044 0045 /** 0046 * @var array Error message templates 0047 */ 0048 protected $_messageTemplates = array( 0049 self::TOO_BIG => "Maximum allowed size for file '%value%' is '%max%' but '%size%' detected", 0050 self::TOO_SMALL => "Minimum expected size for file '%value%' is '%min%' but '%size%' detected", 0051 self::NOT_FOUND => "File '%value%' is not readable or does not exist", 0052 ); 0053 0054 /** 0055 * @var array Error message template variables 0056 */ 0057 protected $_messageVariables = array( 0058 'min' => '_min', 0059 'max' => '_max', 0060 'size' => '_size', 0061 ); 0062 0063 /** 0064 * Minimum filesize 0065 * @var integer 0066 */ 0067 protected $_min; 0068 0069 /** 0070 * Maximum filesize 0071 * 0072 * If null, there is no maximum filesize 0073 * 0074 * @var integer|null 0075 */ 0076 protected $_max; 0077 0078 /** 0079 * Detected size 0080 * 0081 * @var integer 0082 */ 0083 protected $_size; 0084 0085 /** 0086 * Use bytestring ? 0087 * 0088 * @var boolean 0089 */ 0090 protected $_useByteString = true; 0091 0092 /** 0093 * Sets validator options 0094 * 0095 * If $options is a integer, it will be used as maximum filesize 0096 * As Array is accepts the following keys: 0097 * 'min': Minimum filesize 0098 * 'max': Maximum filesize 0099 * 'bytestring': Use bytestring or real size for messages 0100 * 0101 * @param integer|array $options Options for the adapter 0102 * @throws Zend_Validate_Exception 0103 */ 0104 public function __construct($options) 0105 { 0106 if ($options instanceof Zend_Config) { 0107 $options = $options->toArray(); 0108 } elseif (is_string($options) || is_numeric($options)) { 0109 $options = array('max' => $options); 0110 } elseif (!is_array($options)) { 0111 // require_once 'Zend/Validate/Exception.php'; 0112 throw new Zend_Validate_Exception ('Invalid options to validator provided'); 0113 } 0114 0115 if (1 < func_num_args()) { 0116 $argv = func_get_args(); 0117 array_shift($argv); 0118 $options['max'] = array_shift($argv); 0119 if (!empty($argv)) { 0120 $options['bytestring'] = array_shift($argv); 0121 } 0122 } 0123 0124 if (isset($options['bytestring'])) { 0125 $this->setUseByteString($options['bytestring']); 0126 } 0127 0128 if (isset($options['min'])) { 0129 $this->setMin($options['min']); 0130 } 0131 0132 if (isset($options['max'])) { 0133 $this->setMax($options['max']); 0134 } 0135 } 0136 0137 /** 0138 * Returns the minimum filesize 0139 * 0140 * @param boolean $byteString Use bytestring ? 0141 * @return integer 0142 */ 0143 public function setUseByteString($byteString = true) 0144 { 0145 $this->_useByteString = (bool) $byteString; 0146 return $this; 0147 } 0148 0149 /** 0150 * Will bytestring be used? 0151 * 0152 * @return boolean 0153 */ 0154 public function useByteString() 0155 { 0156 return $this->_useByteString; 0157 } 0158 0159 /** 0160 * Returns the minimum filesize 0161 * 0162 * @param bool $raw Whether or not to force return of the raw value (defaults off) 0163 * @return integer|string 0164 */ 0165 public function getMin($raw = false) 0166 { 0167 $min = $this->_min; 0168 if (!$raw && $this->useByteString()) { 0169 $min = $this->_toByteString($min); 0170 } 0171 0172 return $min; 0173 } 0174 0175 /** 0176 * Sets the minimum filesize 0177 * 0178 * @param integer $min The minimum filesize 0179 * @throws Zend_Validate_Exception When min is greater than max 0180 * @return Zend_Validate_File_Size Provides a fluent interface 0181 */ 0182 public function setMin($min) 0183 { 0184 if (!is_string($min) and !is_numeric($min)) { 0185 // require_once 'Zend/Validate/Exception.php'; 0186 throw new Zend_Validate_Exception ('Invalid options to validator provided'); 0187 } 0188 0189 $min = (integer) $this->_fromByteString($min); 0190 $max = $this->getMax(true); 0191 if (($max !== null) && ($min > $max)) { 0192 // require_once 'Zend/Validate/Exception.php'; 0193 throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum filesize, but $min >" 0194 . " $max"); 0195 } 0196 0197 $this->_min = $min; 0198 return $this; 0199 } 0200 0201 /** 0202 * Returns the maximum filesize 0203 * 0204 * @param bool $raw Whether or not to force return of the raw value (defaults off) 0205 * @return integer|string 0206 */ 0207 public function getMax($raw = false) 0208 { 0209 $max = $this->_max; 0210 if (!$raw && $this->useByteString()) { 0211 $max = $this->_toByteString($max); 0212 } 0213 0214 return $max; 0215 } 0216 0217 /** 0218 * Sets the maximum filesize 0219 * 0220 * @param integer $max The maximum filesize 0221 * @throws Zend_Validate_Exception When max is smaller than min 0222 * @return Zend_Validate_StringLength Provides a fluent interface 0223 */ 0224 public function setMax($max) 0225 { 0226 if (!is_string($max) && !is_numeric($max)) { 0227 // require_once 'Zend/Validate/Exception.php'; 0228 throw new Zend_Validate_Exception ('Invalid options to validator provided'); 0229 } 0230 0231 $max = (integer) $this->_fromByteString($max); 0232 $min = $this->getMin(true); 0233 if (($min !== null) && ($max < $min)) { 0234 // require_once 'Zend/Validate/Exception.php'; 0235 throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum filesize, but " 0236 . "$max < $min"); 0237 } 0238 0239 $this->_max = $max; 0240 return $this; 0241 } 0242 0243 /** 0244 * Retrieve current detected file size 0245 * 0246 * @return int 0247 */ 0248 protected function _getSize() 0249 { 0250 return $this->_size; 0251 } 0252 0253 /** 0254 * Set current size 0255 * 0256 * @param int $size 0257 * @return Zend_Validate_File_Size 0258 */ 0259 protected function _setSize($size) 0260 { 0261 $this->_size = $size; 0262 return $this; 0263 } 0264 0265 /** 0266 * Defined by Zend_Validate_Interface 0267 * 0268 * Returns true if and only if the filesize of $value is at least min and 0269 * not bigger than max (when max is not null). 0270 * 0271 * @param string $value Real file to check for size 0272 * @param array $file File data from Zend_File_Transfer 0273 * @return boolean 0274 */ 0275 public function isValid($value, $file = null) 0276 { 0277 // Is file readable ? 0278 // require_once 'Zend/Loader.php'; 0279 if (!Zend_Loader::isReadable($value)) { 0280 return $this->_throw($file, self::NOT_FOUND); 0281 } 0282 0283 // limited to 4GB files 0284 $size = sprintf("%u", @filesize($value)); 0285 $this->_size = $size; 0286 0287 // Check to see if it's smaller than min size 0288 $min = $this->getMin(true); 0289 $max = $this->getMax(true); 0290 if (($min !== null) && ($size < $min)) { 0291 if ($this->useByteString()) { 0292 $this->_min = $this->_toByteString($min); 0293 $this->_size = $this->_toByteString($size); 0294 $this->_throw($file, self::TOO_SMALL); 0295 $this->_min = $min; 0296 $this->_size = $size; 0297 } else { 0298 $this->_throw($file, self::TOO_SMALL); 0299 } 0300 } 0301 0302 // Check to see if it's larger than max size 0303 if (($max !== null) && ($max < $size)) { 0304 if ($this->useByteString()) { 0305 $this->_max = $this->_toByteString($max); 0306 $this->_size = $this->_toByteString($size); 0307 $this->_throw($file, self::TOO_BIG); 0308 $this->_max = $max; 0309 $this->_size = $size; 0310 } else { 0311 $this->_throw($file, self::TOO_BIG); 0312 } 0313 } 0314 0315 if (count($this->_messages) > 0) { 0316 return false; 0317 } 0318 0319 return true; 0320 } 0321 0322 /** 0323 * Returns the formatted size 0324 * 0325 * @param integer $size 0326 * @return string 0327 */ 0328 protected function _toByteString($size) 0329 { 0330 $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); 0331 for ($i=0; $size >= 1024 && $i < 9; $i++) { 0332 $size /= 1024; 0333 } 0334 0335 return round($size, 2) . $sizes[$i]; 0336 } 0337 0338 /** 0339 * Returns the unformatted size 0340 * 0341 * @param string $size 0342 * @return integer 0343 */ 0344 protected function _fromByteString($size) 0345 { 0346 if (is_numeric($size)) { 0347 return (integer) $size; 0348 } 0349 0350 $type = trim(substr($size, -2, 1)); 0351 0352 $value = substr($size, 0, -1); 0353 if (!is_numeric($value)) { 0354 $value = substr($value, 0, -1); 0355 } 0356 0357 switch (strtoupper($type)) { 0358 case 'Y': 0359 $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); 0360 break; 0361 case 'Z': 0362 $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); 0363 break; 0364 case 'E': 0365 $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024); 0366 break; 0367 case 'P': 0368 $value *= (1024 * 1024 * 1024 * 1024 * 1024); 0369 break; 0370 case 'T': 0371 $value *= (1024 * 1024 * 1024 * 1024); 0372 break; 0373 case 'G': 0374 $value *= (1024 * 1024 * 1024); 0375 break; 0376 case 'M': 0377 $value *= (1024 * 1024); 0378 break; 0379 case 'K': 0380 $value *= 1024; 0381 break; 0382 default: 0383 break; 0384 } 0385 0386 return $value; 0387 } 0388 0389 /** 0390 * Throws an error of the given type 0391 * 0392 * @param string $file 0393 * @param string $errorType 0394 * @return false 0395 */ 0396 protected function _throw($file, $errorType) 0397 { 0398 if ($file !== null) { 0399 $this->_value = $file['name']; 0400 } 0401 0402 $this->_error($errorType); 0403 return false; 0404 } 0405 }