00001 <?php
00025 require_once 'Zend/Validate/Abstract.php';
00026
00035 class Zend_Validate_File_Size extends Zend_Validate_Abstract
00036 {
00040 const TOO_BIG = 'fileSizeTooBig';
00041 const TOO_SMALL = 'fileSizeTooSmall';
00042 const NOT_FOUND = 'fileSizeNotFound';
00048 protected $_messageTemplates = array(
00049 self::TOO_BIG => "Maximum allowed size for file '%value%' is '%max%' but '%size%' detected",
00050 self::TOO_SMALL => "Minimum expected size for file '%value%' is '%min%' but '%size%' detected",
00051 self::NOT_FOUND => "The file '%value%' could not be found"
00052 );
00053
00057 protected $_messageVariables = array(
00058 'min' => '_min',
00059 'max' => '_max',
00060 'size' => '_size',
00061 );
00062
00067 protected $_min;
00068
00076 protected $_max;
00077
00083 protected $_size;
00084
00090 protected $_useByteString = true;
00091
00103 public function __construct($options)
00104 {
00105 if ($options instanceof Zend_Config) {
00106 $options = $options->toArray();
00107 } elseif (is_string($options) || is_numeric($options)) {
00108 $options = array('max' => $options);
00109 } elseif (!is_array($options)) {
00110 require_once 'Zend/Validate/Exception.php';
00111 throw new Zend_Validate_Exception ('Invalid options to validator provided');
00112 }
00113
00114 if (1 < func_num_args()) {
00115
00116
00117 $argv = func_get_args();
00118 array_shift($argv);
00119 $options['max'] = array_shift($argv);
00120 if (!empty($argv)) {
00121 $options['bytestring'] = array_shift($argv);
00122 }
00123 }
00124
00125 if (isset($options['bytestring'])) {
00126 $this->setUseByteString($options['bytestring']);
00127 }
00128
00129 if (isset($options['min'])) {
00130 $this->setMin($options['min']);
00131 }
00132
00133 if (isset($options['max'])) {
00134 $this->setMax($options['max']);
00135 }
00136 }
00137
00144 public function setUseByteString($byteString = true)
00145 {
00146 $this->_useByteString = (bool) $byteString;
00147 return $this;
00148 }
00149
00155 public function useByteString()
00156 {
00157 return $this->_useByteString;
00158 }
00159
00166 public function getMin($raw = false)
00167 {
00168 $min = $this->_min;
00169 if (!$raw && $this->useByteString()) {
00170 $min = $this->_toByteString($min);
00171 }
00172
00173 return $min;
00174 }
00175
00183 public function setMin($min)
00184 {
00185 if (!is_string($min) and !is_numeric($min)) {
00186 require_once 'Zend/Validate/Exception.php';
00187 throw new Zend_Validate_Exception ('Invalid options to validator provided');
00188 }
00189
00190 $min = (integer) $this->_fromByteString($min);
00191 $max = $this->getMax(true);
00192 if (($max !== null) && ($min > $max)) {
00193 require_once 'Zend/Validate/Exception.php';
00194 throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum filesize, but $min >"
00195 . " $max");
00196 }
00197
00198 $this->_min = $min;
00199 return $this;
00200 }
00201
00208 public function getMax($raw = false)
00209 {
00210 $max = $this->_max;
00211 if (!$raw && $this->useByteString()) {
00212 $max = $this->_toByteString($max);
00213 }
00214
00215 return $max;
00216 }
00217
00225 public function setMax($max)
00226 {
00227 if (!is_string($max) && !is_numeric($max)) {
00228 require_once 'Zend/Validate/Exception.php';
00229 throw new Zend_Validate_Exception ('Invalid options to validator provided');
00230 }
00231
00232 $max = (integer) $this->_fromByteString($max);
00233 $min = $this->getMin(true);
00234 if (($min !== null) && ($max < $min)) {
00235 require_once 'Zend/Validate/Exception.php';
00236 throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum filesize, but "
00237 . "$max < $min");
00238 }
00239
00240 $this->_max = $max;
00241 return $this;
00242 }
00243
00249 protected function _getSize()
00250 {
00251 return $this->_size;
00252 }
00253
00260 protected function _setSize($size)
00261 {
00262 $this->_size = $size;
00263 return $this;
00264 }
00265
00276 public function isValid($value, $file = null)
00277 {
00278
00279 require_once 'Zend/Loader.php';
00280 if (!Zend_Loader::isReadable($value)) {
00281 return $this->_throw($file, self::NOT_FOUND);
00282 }
00283
00284
00285 $size = sprintf("%u", @filesize($value));
00286
00287
00288 $min = $this->getMin(true);
00289 $max = $this->getMax(true);
00290 if (($min !== null) && ($size < $min)) {
00291 if ($this->useByteString()) {
00292 $this->_min = $this->_toByteString($min);
00293 $this->_size = $this->_toByteString($size);
00294 $this->_throw($file, self::TOO_SMALL);
00295 $this->_min = $min;
00296 $this->_size = $size;
00297 } else {
00298 $this->_throw($file, self::TOO_SMALL);
00299 }
00300 }
00301
00302
00303 if (($max !== null) && ($max < $size)) {
00304 if ($this->useByteString()) {
00305 $this->_max = $this->_toByteString($max);
00306 $this->_size = $this->_toByteString($size);
00307 $this->_throw($file, self::TOO_BIG);
00308 $this->_max = $max;
00309 $this->_size = $size;
00310 } else {
00311 $this->_throw($file, self::TOO_BIG);
00312 }
00313 }
00314
00315 if (count($this->_messages) > 0) {
00316 return false;
00317 }
00318
00319 return true;
00320 }
00321
00328 protected function _toByteString($size)
00329 {
00330 $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
00331 for ($i=0; $size >= 1024 && $i < 9; $i++) {
00332 $size /= 1024;
00333 }
00334
00335 return round($size, 2) . $sizes[$i];
00336 }
00337
00344 protected function _fromByteString($size)
00345 {
00346 if (is_numeric($size)) {
00347 return (integer) $size;
00348 }
00349
00350 $type = trim(substr($size, -2, 1));
00351
00352 $value = substr($size, 0, -1);
00353 if (!is_numeric($value)) {
00354 $value = substr($value, 0, -1);
00355 }
00356
00357 switch (strtoupper($type)) {
00358 case 'Y':
00359 $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
00360 break;
00361 case 'Z':
00362 $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
00363 break;
00364 case 'E':
00365 $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024);
00366 break;
00367 case 'P':
00368 $value *= (1024 * 1024 * 1024 * 1024 * 1024);
00369 break;
00370 case 'T':
00371 $value *= (1024 * 1024 * 1024 * 1024);
00372 break;
00373 case 'G':
00374 $value *= (1024 * 1024 * 1024);
00375 break;
00376 case 'M':
00377 $value *= (1024 * 1024);
00378 break;
00379 case 'K':
00380 $value *= 1024;
00381 break;
00382 default:
00383 break;
00384 }
00385
00386 return $value;
00387 }
00388
00396 protected function _throw($file, $errorType)
00397 {
00398 if ($file !== null) {
00399 $this->_value = $file['name'];
00400 }
00401
00402 $this->_error($errorType);
00403 return false;
00404 }
00405 }