File indexing completed on 2024-12-22 05:37:12
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_Upload extends Zend_Validate_Abstract 0036 { 0037 /**@#+ 0038 * @const string Error constants 0039 */ 0040 const INI_SIZE = 'fileUploadErrorIniSize'; 0041 const FORM_SIZE = 'fileUploadErrorFormSize'; 0042 const PARTIAL = 'fileUploadErrorPartial'; 0043 const NO_FILE = 'fileUploadErrorNoFile'; 0044 const NO_TMP_DIR = 'fileUploadErrorNoTmpDir'; 0045 const CANT_WRITE = 'fileUploadErrorCantWrite'; 0046 const EXTENSION = 'fileUploadErrorExtension'; 0047 const ATTACK = 'fileUploadErrorAttack'; 0048 const FILE_NOT_FOUND = 'fileUploadErrorFileNotFound'; 0049 const UNKNOWN = 'fileUploadErrorUnknown'; 0050 /**@#-*/ 0051 0052 /** 0053 * @var array Error message templates 0054 */ 0055 protected $_messageTemplates = array( 0056 self::INI_SIZE => "File '%value%' exceeds the defined ini size", 0057 self::FORM_SIZE => "File '%value%' exceeds the defined form size", 0058 self::PARTIAL => "File '%value%' was only partially uploaded", 0059 self::NO_FILE => "File '%value%' was not uploaded", 0060 self::NO_TMP_DIR => "No temporary directory was found for file '%value%'", 0061 self::CANT_WRITE => "File '%value%' can't be written", 0062 self::EXTENSION => "A PHP extension returned an error while uploading the file '%value%'", 0063 self::ATTACK => "File '%value%' was illegally uploaded. This could be a possible attack", 0064 self::FILE_NOT_FOUND => "File '%value%' was not found", 0065 self::UNKNOWN => "Unknown error while uploading file '%value%'" 0066 ); 0067 0068 /** 0069 * Internal array of files 0070 * @var array 0071 */ 0072 protected $_files = array(); 0073 0074 /** 0075 * Sets validator options 0076 * 0077 * The array $files must be given in syntax of Zend_File_Transfer to be checked 0078 * If no files are given the $_FILES array will be used automatically. 0079 * NOTE: This validator will only work with HTTP POST uploads! 0080 * 0081 * @param array|Zend_Config $files Array of files in syntax of Zend_File_Transfer 0082 */ 0083 public function __construct($files = array()) 0084 { 0085 if ($files instanceof Zend_Config) { 0086 $files = $files->toArray(); 0087 } 0088 0089 $this->setFiles($files); 0090 } 0091 0092 /** 0093 * Returns the array of set files 0094 * 0095 * @param string $file (Optional) The file to return in detail 0096 * @return array 0097 * @throws Zend_Validate_Exception If file is not found 0098 */ 0099 public function getFiles($file = null) 0100 { 0101 if ($file !== null) { 0102 $return = array(); 0103 foreach ($this->_files as $name => $content) { 0104 if ($name === $file) { 0105 $return[$file] = $this->_files[$name]; 0106 } 0107 0108 if ($content['name'] === $file) { 0109 $return[$name] = $this->_files[$name]; 0110 } 0111 } 0112 0113 if (count($return) === 0) { 0114 // require_once 'Zend/Validate/Exception.php'; 0115 throw new Zend_Validate_Exception("The file '$file' was not found"); 0116 } 0117 0118 return $return; 0119 } 0120 0121 return $this->_files; 0122 } 0123 0124 /** 0125 * Sets the files to be checked 0126 * 0127 * @param array $files The files to check in syntax of Zend_File_Transfer 0128 * @return Zend_Validate_File_Upload Provides a fluent interface 0129 */ 0130 public function setFiles($files = array()) 0131 { 0132 if (count($files) === 0) { 0133 $this->_files = $_FILES; 0134 } else { 0135 $this->_files = $files; 0136 } 0137 0138 // see ZF-10738 0139 if (is_null($this->_files)) { 0140 $this->_files = array(); 0141 } 0142 0143 foreach($this->_files as $file => $content) { 0144 if (!isset($content['error'])) { 0145 unset($this->_files[$file]); 0146 } 0147 } 0148 0149 return $this; 0150 } 0151 0152 /** 0153 * Defined by Zend_Validate_Interface 0154 * 0155 * Returns true if and only if the file was uploaded without errors 0156 * 0157 * @param string $value Single file to check for upload errors, when giving null the $_FILES array 0158 * from initialization will be used 0159 * @param string|null $file 0160 * @return boolean 0161 */ 0162 public function isValid($value, $file = null) 0163 { 0164 $this->_messages = null; 0165 if (array_key_exists($value, $this->_files)) { 0166 $files[$value] = $this->_files[$value]; 0167 } else { 0168 foreach ($this->_files as $file => $content) { 0169 if (isset($content['name']) && ($content['name'] === $value)) { 0170 $files[$file] = $this->_files[$file]; 0171 } 0172 0173 if (isset($content['tmp_name']) && ($content['tmp_name'] === $value)) { 0174 $files[$file] = $this->_files[$file]; 0175 } 0176 } 0177 } 0178 0179 if (empty($files)) { 0180 return $this->_throw($file, self::FILE_NOT_FOUND); 0181 } 0182 0183 foreach ($files as $file => $content) { 0184 $this->_value = $file; 0185 switch($content['error']) { 0186 case 0: 0187 if (!is_uploaded_file($content['tmp_name'])) { 0188 $this->_throw($content, self::ATTACK); 0189 } 0190 break; 0191 0192 case 1: 0193 $this->_throw($content, self::INI_SIZE); 0194 break; 0195 0196 case 2: 0197 $this->_throw($content, self::FORM_SIZE); 0198 break; 0199 0200 case 3: 0201 $this->_throw($content, self::PARTIAL); 0202 break; 0203 0204 case 4: 0205 $this->_throw($content, self::NO_FILE); 0206 break; 0207 0208 case 6: 0209 $this->_throw($content, self::NO_TMP_DIR); 0210 break; 0211 0212 case 7: 0213 $this->_throw($content, self::CANT_WRITE); 0214 break; 0215 0216 case 8: 0217 $this->_throw($content, self::EXTENSION); 0218 break; 0219 0220 default: 0221 $this->_throw($content, self::UNKNOWN); 0222 break; 0223 } 0224 } 0225 0226 if (count($this->_messages) > 0) { 0227 return false; 0228 } else { 0229 return true; 0230 } 0231 } 0232 0233 /** 0234 * Throws an error of the given type 0235 * 0236 * @param string $file 0237 * @param string $errorType 0238 * @return false 0239 */ 0240 protected function _throw($file, $errorType) 0241 { 0242 if ($file !== null) { 0243 if (is_array($file) and !empty($file['name'])) { 0244 $this->_value = $file['name']; 0245 } 0246 } 0247 0248 $this->_error($errorType); 0249 return false; 0250 } 0251 }