Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 479 |
|
0.00% |
0 / 21 |
CRAP | |
0.00% |
0 / 1 |
| Upload | |
0.00% |
0 / 479 |
|
0.00% |
0 / 21 |
26082 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
| __destruct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| __ | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| clear | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
2 | |||
| clearUploadedAtTemp | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
42 | |||
| getUploadedData | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
210 | |||
| moveUploadedFiles | |
0.00% |
0 / 28 |
|
0.00% |
0 / 1 |
132 | |||
| renameDuplicateFile | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
30 | |||
| securityScan | |
0.00% |
0 / 28 |
|
0.00% |
0 / 1 |
90 | |||
| setErrorMessage | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
42 | |||
| setInputFileName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| setNewFileName | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
72 | |||
| setNewFileNameToRandom | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| setupFileExtensionsMimeTypesForValidation | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
42 | |||
| setWebSafeFileName | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
| testGetUploadedMimetype | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
132 | |||
| upload | |
0.00% |
0 / 42 |
|
0.00% |
0 / 1 |
342 | |||
| uploadSingleFile | |
0.00% |
0 / 123 |
|
0.00% |
0 / 1 |
600 | |||
| validateExtensionAndMimeType | |
0.00% |
0 / 67 |
|
0.00% |
0 / 1 |
182 | |||
| validateFileSize | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
42 | |||
| validateOptionsProperties | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
272 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Rundiz Upload component. |
| 4 | * |
| 5 | * @author Vee W. |
| 6 | * @license http://opensource.org/licenses/MIT MIT |
| 7 | */ |
| 8 | |
| 9 | |
| 10 | namespace Rundiz\Upload; |
| 11 | |
| 12 | /** |
| 13 | * PHP upload class that is able to validate requirements and limitations, real file's mime type check, detect the errors and report. |
| 14 | * |
| 15 | * @package Upload |
| 16 | * @version 2.0.2 |
| 17 | * @author Vee W. |
| 18 | */ |
| 19 | class Upload |
| 20 | { |
| 21 | |
| 22 | |
| 23 | /** |
| 24 | * @var array Allowed file extensions. Example: array('jpg', 'gif', 'png'). |
| 25 | */ |
| 26 | public $allowed_file_extensions; |
| 27 | /** |
| 28 | * @var array The array set of file extensions and its valid mime types for check when process the uploaded files.<br> |
| 29 | * Example: |
| 30 | * <pre> |
| 31 | * array( |
| 32 | * 'jpg' => array('image/jpeg', 'image/pjpeg'), |
| 33 | * 'txt' => array('text/plain'), |
| 34 | * ); |
| 35 | * </pre> |
| 36 | * If you don't want to validate mime type, set this property to an empty array. Example: $Upload->file_extensions_mime_types = array(); |
| 37 | */ |
| 38 | public $file_extensions_mime_types; |
| 39 | /** |
| 40 | * @var integer Set max file size to upload. This file size unit is in bytes only. |
| 41 | */ |
| 42 | public $max_file_size; |
| 43 | /** |
| 44 | * @var string Set new file name, just set the file name only. No extension.<br> |
| 45 | * Important! This property is not recommend to set it if you upload multiple files with same input file name. It is recommended to leave this as null and set overwrite property to true or false.<br> |
| 46 | * If you want to set the name while upload multiple files, it is recommended that you set overwrite property to false. |
| 47 | */ |
| 48 | public $new_file_name; |
| 49 | /** |
| 50 | * @var boolean To overwrite the uploaded file set it to true, otherwise set it to false. |
| 51 | */ |
| 52 | public $overwrite = false; |
| 53 | /** |
| 54 | * @var boolean To rename uploaded file name to safe for web set it to true, otherwise set it to false.<br> |
| 55 | * The safe for web file name is English and number chacters, no space (replaced with dash), no special characters, allowed dash and underscore. |
| 56 | */ |
| 57 | public $web_safe_file_name = true; |
| 58 | /** |
| 59 | * @var boolean Set to true to enable security scan such as php open tag (<?php). Set to false to not scan. This is optional security. |
| 60 | */ |
| 61 | public $security_scan = false; |
| 62 | /** |
| 63 | * @var boolean If you upload multiple files and there is at least one file that did not pass the validation, do you want it to stop?<br> |
| 64 | * Set to true to stop and delete all uploaded files (all uploaded files must pass validation).<br> |
| 65 | * Set to false to skip the error files (failed validation files are report as error, success validation files continue the process). |
| 66 | */ |
| 67 | public $stop_on_failed_upload_multiple = true; |
| 68 | /** |
| 69 | * @var string Path to store files that was uploaded to move to. Do not end with trailing slash. |
| 70 | */ |
| 71 | public $move_uploaded_to = '.'; |
| 72 | |
| 73 | /** |
| 74 | * Contain error codes. |
| 75 | * |
| 76 | * The array format will be: |
| 77 | * <pre> |
| 78 | * array( |
| 79 | * index => array(// the `index` will be the same as it is in error_messages property. |
| 80 | * 'code' => 'RDU_1',// this will be error code, start with RDU_ and follow with number or short error message without space. it is easy for check and replace with your translation. |
| 81 | * 'errorAttributes' => 'string',// this key contain error attributes as string |
| 82 | * // for example: 9MB > 2MB in case that limit file size to 2MB but uploaded 9MB, or showing file name that have problem. |
| 83 | * // this key may contain empty string so check it before use. |
| 84 | * 'errorFileName' => 'filename.ext',// the file name with extension that cause error message. |
| 85 | * // this key may contain empty string. |
| 86 | * 'errorFileSize' => '12345',// the file size in bytes. |
| 87 | * // this key may contain empty string. |
| 88 | * 'errorFileMime' => 'mime/type',// the file mime type. |
| 89 | * // this key may contain empty string. |
| 90 | * ) |
| 91 | * ) |
| 92 | * </pre> |
| 93 | * |
| 94 | * The error codes and description. |
| 95 | * |
| 96 | * RDU_MOVE_UPLOADED_FAILED = Failed to move uploaded file.<br> |
| 97 | * RDU_SEC_ERR_PHP = Security error! Found PHP embedded in the uploaded file.<br> |
| 98 | * RDU_SEC_ERR_CGI = Security error! Found CGI/Pearl embedded in the uploaded file.<br> |
| 99 | * RDU_MOVE_UPLOADED_TO_NOT_DIR = The target upload location is not folder.<br> |
| 100 | * RDU_MOVE_UPLOADED_TO_NOT_WRITABLE = The target upload location is not writable. Please check folder permission.<br> |
| 101 | * RDU_UNABLE_VALIDATE_EXT = Unable to validate file extension.<br> |
| 102 | * RDU_NOT_ALLOW_EXT = The uploaded file is not in allowed extensions.<br> |
| 103 | * RDU_UNABLE_VALIDATE_EXT_AND_MIME = Unable to validate file extension and mime type.<br> |
| 104 | * RDU_INVALID_MIME = The uploaded file has invalid mime type.<br> |
| 105 | * RDU_UNABLE_VALIDATE_MIME = Unable to validate mime type. |
| 106 | * |
| 107 | * For the RDU_1 to RDU_8 use PHP upload errors. ( http://php.net/manual/en/features.file-upload.errors.php ).<br> |
| 108 | * RDU_1 = The uploaded file exceeds the max file size directive.<br> |
| 109 | * RDU_2 = The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.<br> |
| 110 | * RDU_3 = The uploaded file was only partially uploaded.<br> |
| 111 | * RDU_4 = No file was uploaded.<br> |
| 112 | * RDU_6 = Missing a temporary folder.<br> |
| 113 | * RDU_7 = Failed to write file to disk.<br> |
| 114 | * RDU_8 = A PHP extension stopped the file upload.<br> |
| 115 | * |
| 116 | * @since 2.0.1 |
| 117 | * @var array If there is at least one error, it will be set to here. |
| 118 | */ |
| 119 | public $error_codes = array(); |
| 120 | |
| 121 | /** |
| 122 | * @var array If there is at least one error message it will be set to here. |
| 123 | */ |
| 124 | public $error_messages = array(); |
| 125 | |
| 126 | /** |
| 127 | * @var string The input file name. ($_FILES['input_file_name']). |
| 128 | */ |
| 129 | protected $input_file_name; |
| 130 | /** |
| 131 | * @var array Contain all values from $_FILES['input_file_name'] for works with upload process. This will be very useful when upload multiple files.<br> |
| 132 | * Example:<br> |
| 133 | * <code>$Upload->files['input_file_name'];</code> is same as <code>$_FILES['input_file_name']</code> |
| 134 | */ |
| 135 | protected $files = array(); |
| 136 | /** |
| 137 | * @var array The queue for move uploaded file(s). This is very useful when upload multiple files. |
| 138 | */ |
| 139 | protected $move_uploaded_queue = array(); |
| 140 | |
| 141 | |
| 142 | /** |
| 143 | * Begins upload class. |
| 144 | * |
| 145 | * @param string $input_file_name The name of input file. |
| 146 | */ |
| 147 | public function __construct($input_file_name) |
| 148 | { |
| 149 | $this->clear(); |
| 150 | $this->setInputFileName($input_file_name); |
| 151 | }// __construct |
| 152 | |
| 153 | |
| 154 | /** |
| 155 | * Class destructor. Works at end of class (unset class's variable). |
| 156 | */ |
| 157 | public function __destruct() |
| 158 | { |
| 159 | $this->clear(); |
| 160 | }// __destruct |
| 161 | |
| 162 | |
| 163 | /** |
| 164 | * Placeholder method for language editor program like Poedit to lookup for the words that is using this method.<br> |
| 165 | * This method does nothing but for who use program like Poedit to search/lookup the words that is using this method to create translation.<br> |
| 166 | * Example:<br> |
| 167 | * There is this code in generator class. <code>static::__('Hello');</code><br> |
| 168 | * Use Poedit to search for __ function to update/retreive the source text and translate it. |
| 169 | * |
| 170 | * @param string $string The message to use. |
| 171 | * @return string Return the same string. |
| 172 | */ |
| 173 | protected static function __($string) |
| 174 | { |
| 175 | return $string; |
| 176 | }// __ |
| 177 | |
| 178 | |
| 179 | /** |
| 180 | * Clear all properties to its default values. |
| 181 | */ |
| 182 | public function clear() |
| 183 | { |
| 184 | $this->allowed_file_extensions = null; |
| 185 | $this->error_messages = array(); |
| 186 | $this->file_extensions_mime_types = null; |
| 187 | $this->files = array(); |
| 188 | $this->input_file_name = null; |
| 189 | $this->max_file_size = null; |
| 190 | $this->move_uploaded_queue = array(); |
| 191 | $this->move_uploaded_to = '.'; |
| 192 | $this->new_file_name = null; |
| 193 | $this->overwrite = false; |
| 194 | $this->web_safe_file_name = true; |
| 195 | $this->security_scan = false; |
| 196 | $this->stop_on_failed_upload_multiple = true; |
| 197 | }// clear |
| 198 | |
| 199 | |
| 200 | /** |
| 201 | * Clear uploaded files at temp folder. (if it is able to write/delete). |
| 202 | */ |
| 203 | protected function clearUploadedAtTemp() |
| 204 | { |
| 205 | foreach ($this->move_uploaded_queue as $key => $queue_item) { |
| 206 | if (is_array($queue_item) && isset($queue_item['tmp_name'])) { |
| 207 | if (is_file($queue_item['tmp_name']) && is_writable($queue_item['tmp_name'])) { |
| 208 | unlink($queue_item['tmp_name']); |
| 209 | } |
| 210 | } |
| 211 | }// endforeach; |
| 212 | unset($key, $queue_item); |
| 213 | $this->move_uploaded_queue = array(); |
| 214 | }// clearUploadedAtTemp |
| 215 | |
| 216 | |
| 217 | /** |
| 218 | * Get the uploaded data. |
| 219 | * |
| 220 | * @return array Return array set of successful uploaded files and its data.<br> |
| 221 | * Example: |
| 222 | * <pre> |
| 223 | * $output = array( |
| 224 | * 'input_file_name_key' => array( |
| 225 | * 'name' => 'file_name_where_user_selected_in_the_upload_form.ext', |
| 226 | * 'extension' => 'ext', |
| 227 | * 'size' => 'file size in bytes.', |
| 228 | * 'new_name' => 'new_file_name_that_was_set_while_upload_process.ext', |
| 229 | * 'full_path_new_name' => '/full/move_uploaded_path/to/new_file_name_that_was_set_while_upload_process.ext', |
| 230 | * 'mime' => 'The real file mime type', |
| 231 | * 'md5_file' => 'The md5 file value.', |
| 232 | * ), |
| 233 | * 'other_input_file_name_key' => array( |
| 234 | * 'name' => '...', |
| 235 | * 'extension' => '...', |
| 236 | * 'size' => '...', |
| 237 | * 'new_name' => '...', |
| 238 | * 'full_path_new_name' => '...', |
| 239 | * 'mime' => '...', |
| 240 | * 'md5_file' => '...', |
| 241 | * ), |
| 242 | * ); |
| 243 | * </pre> |
| 244 | * If failed to upload, it will return empty array. |
| 245 | */ |
| 246 | public function getUploadedData() |
| 247 | { |
| 248 | if (empty($this->move_uploaded_queue) || !is_array($this->move_uploaded_queue)) { |
| 249 | return array(); |
| 250 | } |
| 251 | |
| 252 | $output = array(); |
| 253 | |
| 254 | foreach ($this->move_uploaded_queue as $key => $queue_item) { |
| 255 | if ( |
| 256 | is_array($queue_item) && |
| 257 | array_key_exists('name', $queue_item) && |
| 258 | array_key_exists('tmp_name', $queue_item) && |
| 259 | array_key_exists('new_name', $queue_item) && |
| 260 | array_key_exists('move_uploaded_to', $queue_item) && |
| 261 | array_key_exists('move_uploaded_status', $queue_item) && |
| 262 | $queue_item['move_uploaded_status'] === 'success' |
| 263 | ) { |
| 264 | // get file extension only |
| 265 | $file_name_explode = explode('.', $queue_item['name']); |
| 266 | $file_extension = (isset($file_name_explode[count($file_name_explode)-1]) ? $file_name_explode[count($file_name_explode)-1] : null); |
| 267 | unset($file_name_explode); |
| 268 | |
| 269 | // get file info |
| 270 | $Finfo = new \finfo(); |
| 271 | $mime = $Finfo->file($queue_item['move_uploaded_to'], FILEINFO_MIME_TYPE); |
| 272 | unset($Finfo); |
| 273 | |
| 274 | $output[$key] = array(); |
| 275 | $output[$key]['name'] = $queue_item['name']; |
| 276 | $output[$key]['extension'] = $file_extension; |
| 277 | $output[$key]['size'] = (is_file($queue_item['move_uploaded_to']) ? filesize($queue_item['move_uploaded_to']) : 0); |
| 278 | $output[$key]['new_name'] = $queue_item['new_name']; |
| 279 | $output[$key]['full_path_new_name'] = $queue_item['move_uploaded_to']; |
| 280 | $output[$key]['mime'] = $mime; |
| 281 | $output[$key]['md5_file'] = (is_file($queue_item['move_uploaded_to']) ? md5_file($queue_item['move_uploaded_to']) : null); |
| 282 | |
| 283 | unset($file_extension, $mime); |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | return $output; |
| 288 | }// getUploadedData |
| 289 | |
| 290 | |
| 291 | /** |
| 292 | * Move the uploaded file(s). |
| 293 | * |
| 294 | * @return boolean Return true on success, false on failure. |
| 295 | */ |
| 296 | protected function moveUploadedFiles() |
| 297 | { |
| 298 | $i = 0; |
| 299 | if (is_array($this->move_uploaded_queue)) { |
| 300 | foreach ($this->move_uploaded_queue as $key => $queue_item) { |
| 301 | if (is_array($queue_item) && isset($queue_item['name']) && isset($queue_item['tmp_name']) && isset($queue_item['new_name'])) { |
| 302 | $destination_name = $queue_item['new_name']; |
| 303 | |
| 304 | if ($this->overwrite === false) { |
| 305 | // verify file exists and set new name. |
| 306 | $destination_name = $this->renameDuplicateFile($destination_name); |
| 307 | } |
| 308 | |
| 309 | $move_result = move_uploaded_file($queue_item['tmp_name'], $this->move_uploaded_to.DIRECTORY_SEPARATOR.$destination_name); |
| 310 | if ($move_result === true) { |
| 311 | // move uploaded file success. add status and some data to array. |
| 312 | $this->move_uploaded_queue[$key] = array_merge( |
| 313 | $this->move_uploaded_queue[$key], |
| 314 | array( |
| 315 | 'new_name' => $destination_name, |
| 316 | 'move_uploaded_status' => 'success', |
| 317 | 'move_uploaded_to' => $this->move_uploaded_to.DIRECTORY_SEPARATOR.$destination_name, |
| 318 | ) |
| 319 | ); |
| 320 | $i++; |
| 321 | } else { |
| 322 | $this->setErrorMessage( |
| 323 | sprintf(static::__('Unable to move uploaded file. (%s => %s)'), $queue_item['name'], $this->move_uploaded_to . DIRECTORY_SEPARATOR . $destination_name), |
| 324 | 'RDU_MOVE_UPLOADED_FAILED', |
| 325 | $queue_item['name'] . '=> ' . $this->move_uploaded_to . DIRECTORY_SEPARATOR . $destination_name |
| 326 | ); |
| 327 | } |
| 328 | |
| 329 | unset($destination_name, $move_result); |
| 330 | } |
| 331 | }// endforeach; |
| 332 | unset($key, $queue_item); |
| 333 | } |
| 334 | |
| 335 | if ($i == count($this->move_uploaded_queue) && $i > 0) { |
| 336 | return true; |
| 337 | } else { |
| 338 | return false; |
| 339 | } |
| 340 | }// moveUploadedFiles |
| 341 | |
| 342 | |
| 343 | /** |
| 344 | * Rename the file where it is duplicate with existing file. |
| 345 | * |
| 346 | * @param string $file_name File name to check |
| 347 | * @return string Return renamed file that will not duplicate the existing file. |
| 348 | */ |
| 349 | protected function renameDuplicateFile($file_name, $loop_count = 1) |
| 350 | { |
| 351 | if (!file_exists($this->move_uploaded_to.DIRECTORY_SEPARATOR.$file_name)) { |
| 352 | return $file_name; |
| 353 | } else { |
| 354 | $file_name_explode = explode('.', $file_name); |
| 355 | $file_extension = (isset($file_name_explode[count($file_name_explode)-1]) ? $file_name_explode[count($file_name_explode)-1] : null); |
| 356 | unset($file_name_explode[count($file_name_explode)-1]); |
| 357 | $file_name_only = implode('.', $file_name_explode); |
| 358 | unset($file_name_explode); |
| 359 | |
| 360 | $i = 1; |
| 361 | $found = true; |
| 362 | do { |
| 363 | $new_file_name = $file_name_only.'_'.$i.'.'.$file_extension; |
| 364 | if (file_exists($this->move_uploaded_to.DIRECTORY_SEPARATOR.$new_file_name)) { |
| 365 | $found = true; |
| 366 | if ($i > 1000) { |
| 367 | // too many loop |
| 368 | $file_name = uniqid().'-'.str_replace('.', '', microtime(true)); |
| 369 | $found = false; |
| 370 | } |
| 371 | } else { |
| 372 | $file_name = $new_file_name; |
| 373 | $found = false; |
| 374 | } |
| 375 | $i++; |
| 376 | } while ($found === true); |
| 377 | |
| 378 | unset($file_extension, $file_name_only, $new_file_name); |
| 379 | return $file_name; |
| 380 | } |
| 381 | }// renameDuplicateFile |
| 382 | |
| 383 | |
| 384 | /** |
| 385 | * Security scan. Scan for such as embedded php code in the uploaded file. |
| 386 | * |
| 387 | * @return boolean Return true on safety, return false for otherwise. |
| 388 | */ |
| 389 | protected function securityScan() |
| 390 | { |
| 391 | if ( |
| 392 | is_array($this->files[$this->input_file_name]) && |
| 393 | array_key_exists('name', $this->files[$this->input_file_name]) && |
| 394 | array_key_exists('tmp_name', $this->files[$this->input_file_name]) && |
| 395 | $this->files[$this->input_file_name]['tmp_name'] != null |
| 396 | ) { |
| 397 | // there is an uploaded file. |
| 398 | if (is_file($this->files[$this->input_file_name]['tmp_name'])) { |
| 399 | $file_content = file_get_contents($this->files[$this->input_file_name]['tmp_name']); |
| 400 | |
| 401 | // scan php open tag |
| 402 | if (strpos($file_content, '<?php') !== false) { |
| 403 | // found php open tag. (<?php). |
| 404 | $this->setErrorMessage( |
| 405 | sprintf(static::__('Error! Found php embedded in the uploaded file. (%s).'), $this->files[$this->input_file_name]['name']), |
| 406 | 'RDU_SEC_ERR_PHP', |
| 407 | $this->files[$this->input_file_name]['name'], |
| 408 | $this->files[$this->input_file_name]['name'], |
| 409 | $this->files[$this->input_file_name]['size'], |
| 410 | $this->files[$this->input_file_name]['type'] |
| 411 | ); |
| 412 | return false; |
| 413 | } |
| 414 | |
| 415 | // scan cgi/perl |
| 416 | if (strpos($file_content, '#!/') !== false && strpos($file_content, '/perl') !== false) { |
| 417 | // found cgi/perl header. |
| 418 | $this->setErrorMessage( |
| 419 | sprintf(static::__('Error! Found cgi/perl embedded in the uploaded file. (%s).'), $this->files[$this->input_file_name]['name']), |
| 420 | 'RDU_SEC_ERR_CGI', |
| 421 | $this->files[$this->input_file_name]['name'], |
| 422 | $this->files[$this->input_file_name]['name'], |
| 423 | $this->files[$this->input_file_name]['size'], |
| 424 | $this->files[$this->input_file_name]['type'] |
| 425 | ); |
| 426 | return false; |
| 427 | } |
| 428 | |
| 429 | unset($file_content); |
| 430 | } |
| 431 | } |
| 432 | |
| 433 | return true; |
| 434 | }// securityScan |
| 435 | |
| 436 | |
| 437 | /** |
| 438 | * Set the error message into error_messages and error_codes properties. |
| 439 | * |
| 440 | * @since 2.0.1 |
| 441 | * @param string $error_messages The error message. |
| 442 | * @param string $code The error code, start with RDU_ and follow with number or short error message without space. |
| 443 | * @param string $errorAttributes Error attributes. For example: 9MB > 2MB in case that limit file size to 2MB but uploaded 9MB, or showing file name that have problem. |
| 444 | * @param string $errorFileName The file name with extension. |
| 445 | * @param string $errorFileSize The file size in bytes. |
| 446 | * @param string $errorFileMime The file mime type. |
| 447 | */ |
| 448 | protected function setErrorMessage( |
| 449 | $error_messages, |
| 450 | $code, |
| 451 | $errorAttributes = '', |
| 452 | $errorFileName = '', |
| 453 | $errorFileSize = '', |
| 454 | $errorFileMime = '' |
| 455 | ) { |
| 456 | $arg_list = func_get_args(); |
| 457 | $numargs = func_num_args(); |
| 458 | for ($i = 0; $i < $numargs; $i++) { |
| 459 | if (is_array($arg_list) && array_key_exists($i, $arg_list) && !is_scalar($arg_list[$i])) { |
| 460 | return false; |
| 461 | } elseif ($arg_list === false) { |
| 462 | return false; |
| 463 | } |
| 464 | } |
| 465 | unset($arg_list, $i, $numargs); |
| 466 | |
| 467 | $this->error_messages[] = $error_messages; |
| 468 | $this->error_codes[] = array( |
| 469 | 'code' => $code, |
| 470 | 'errorAttributes' => $errorAttributes, |
| 471 | 'errorFileName' => $errorFileName, |
| 472 | 'errorFileSize' => $errorFileSize, |
| 473 | 'errorFileMime' => $errorFileMime, |
| 474 | ); |
| 475 | }// setErrorMessage |
| 476 | |
| 477 | |
| 478 | /** |
| 479 | * Set input file name.<br> |
| 480 | * If you begins new class object then you don't have to call this method. You must call this method after called to the clear() method.<br> |
| 481 | * Or you can call this method in case that you want to process the other uploaded file next to previous one. |
| 482 | * |
| 483 | * @param string $input_file_name The name of input file. |
| 484 | */ |
| 485 | public function setInputFileName($input_file_name) |
| 486 | { |
| 487 | $this->input_file_name = $input_file_name; |
| 488 | }// setInputFileName |
| 489 | |
| 490 | |
| 491 | /** |
| 492 | * Set the new file name if it was not set, check for reserved file name and removed those characters. |
| 493 | * |
| 494 | * @link http://windows.microsoft.com/en-us/windows/file-names-extensions-faq#1TC=windows-7 Windows file name FAQ. |
| 495 | * @link https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 Windows reserved file name. |
| 496 | * @link https://en.wikipedia.org/wiki/Filename Global reserved file name. |
| 497 | */ |
| 498 | protected function setNewFileName() |
| 499 | { |
| 500 | $this->new_file_name = trim($this->new_file_name); |
| 501 | |
| 502 | if ($this->new_file_name == null) { |
| 503 | // if new file name was not set, set it from uploaded file name. |
| 504 | if (is_array($this->files[$this->input_file_name]) && array_key_exists('name', $this->files[$this->input_file_name])) { |
| 505 | $file_name_explode = explode('.', $this->files[$this->input_file_name]['name']); |
| 506 | unset($file_name_explode[count($file_name_explode)-1]); |
| 507 | $this->new_file_name = implode('.', $file_name_explode); |
| 508 | unset($file_name_explode); |
| 509 | } else { |
| 510 | $this->setNewFileNameToRandom(); |
| 511 | } |
| 512 | } |
| 513 | |
| 514 | // do not allow name that contain one of these characters. |
| 515 | $reserved_characters = array('\\', '/', '?', '%', '*', ':', '|', '"', '<', '>', '!', '@'); |
| 516 | $this->new_file_name = str_replace($reserved_characters, '', $this->new_file_name); |
| 517 | unset($reserved_characters); |
| 518 | |
| 519 | if (preg_match('#[^\.]+#iu', $this->new_file_name) == 0) { |
| 520 | // found the name is only dots. example ., .., ..., .... |
| 521 | $this->setNewFileNameToRandom(); |
| 522 | } |
| 523 | |
| 524 | // reserved words or reserved names. do not allow if new name is set to one of these words or names. |
| 525 | // make it case in-sensitive. |
| 526 | $reserved_words = array( |
| 527 | 'CON', 'PRN', 'AUX', 'CLOCK$', 'NUL', |
| 528 | 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', |
| 529 | 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9', |
| 530 | 'LST', 'KEYBD$', 'SCREEN$', '$IDLE$', 'CONFIG$', |
| 531 | '$Mft', '$MftMirr', '$LogFile', '$Volume', '$AttrDef', '$Bitmap', '$Boot', '$BadClus', '$Secure', |
| 532 | '$Upcase', '$Extend', '$Quota', '$ObjId', '$Reparse', |
| 533 | ); |
| 534 | foreach ($reserved_words as $reserved_word) { |
| 535 | if (strtolower($reserved_word) == strtolower($this->new_file_name)) { |
| 536 | $this->setNewFileNameToRandom(); |
| 537 | } |
| 538 | } |
| 539 | unset($reserved_word, $reserved_words); |
| 540 | |
| 541 | // in the end if it is still left new name as null... set random name to it. |
| 542 | if ($this->new_file_name == null) { |
| 543 | $this->setNewFileNameToRandom(); |
| 544 | } |
| 545 | }// setNewFileName |
| 546 | |
| 547 | |
| 548 | /** |
| 549 | * Set the new file name to random. (unique id and microtime). |
| 550 | */ |
| 551 | protected function setNewFileNameToRandom() |
| 552 | { |
| 553 | $this->new_file_name = uniqid().'-'.str_replace('.', '', microtime(true)); |
| 554 | }// setNewFileNameToRandom |
| 555 | |
| 556 | |
| 557 | /** |
| 558 | * Setup file extensions mime types for validation. (In case that it was not set). |
| 559 | */ |
| 560 | protected function setupFileExtensionsMimeTypesForValidation() |
| 561 | { |
| 562 | if (!is_array($this->file_extensions_mime_types) && $this->file_extensions_mime_types == null) { |
| 563 | // extensions mime types was not set and not set to NOT validate (empty array). |
| 564 | $default_mime_types_file = 'file-extensions-mime-types.php'; |
| 565 | if (is_file(__DIR__.DIRECTORY_SEPARATOR.$default_mime_types_file)) { |
| 566 | $this->file_extensions_mime_types = include __DIR__.DIRECTORY_SEPARATOR.$default_mime_types_file; |
| 567 | } |
| 568 | unset($default_mime_types_file); |
| 569 | } |
| 570 | |
| 571 | if (is_array($this->file_extensions_mime_types)) { |
| 572 | // if mime types was set, change the keys to lower case. |
| 573 | $this->file_extensions_mime_types = array_change_key_case($this->file_extensions_mime_types, CASE_LOWER); |
| 574 | } |
| 575 | |
| 576 | if (is_array($this->allowed_file_extensions)) { |
| 577 | // if allowed extensions was set, change the values to lower case. |
| 578 | $this->allowed_file_extensions = array_map('strtolower', $this->allowed_file_extensions); |
| 579 | } |
| 580 | }// setupFileExtensionsMimeTypesForValidation |
| 581 | |
| 582 | |
| 583 | /** |
| 584 | * Set the file name that is safe for web.<br> |
| 585 | * The safe for web file name is English and number chacters, no space (replaced with dash), no special characters, allowed dash and underscore. |
| 586 | */ |
| 587 | protected function setWebSafeFileName() |
| 588 | { |
| 589 | if ($this->new_file_name == null) { |
| 590 | $this->setNewFileName(); |
| 591 | } |
| 592 | |
| 593 | // replace multiple spaces to one space. |
| 594 | $this->new_file_name = preg_replace('#\s+#iu', ' ', $this->new_file_name); |
| 595 | // replace space to dash. |
| 596 | $this->new_file_name = str_replace(' ', '-', $this->new_file_name); |
| 597 | // replace non alpha-numeric to nothing. |
| 598 | $this->new_file_name = preg_replace('#[^\da-z\-_]#iu', '', $this->new_file_name); |
| 599 | // replace multiple dashes to one dash. |
| 600 | $this->new_file_name = preg_replace('#-{2,}#', '-', $this->new_file_name); |
| 601 | }// setWebSafeFileName |
| 602 | |
| 603 | |
| 604 | /** |
| 605 | * Test get the real file's mime type using finfo_file.<br> |
| 606 | * This is very useful when you want to add new file extension and mime type to validate uploaded files. |
| 607 | * |
| 608 | * @link http://php.net/manual/en/function.finfo-file.php More info about finfo_file() function. |
| 609 | * @param string $input_file_name The input file name. This support only one file upload. |
| 610 | * @return string Return file's mime type or error message. |
| 611 | */ |
| 612 | public function testGetUploadedMimetype($input_file_name = null) |
| 613 | { |
| 614 | if ($input_file_name == null) { |
| 615 | $input_file_name = $this->input_file_name; |
| 616 | } |
| 617 | |
| 618 | if ( |
| 619 | !isset($_FILES[$input_file_name]['name']) || |
| 620 | (isset($_FILES[$input_file_name]['name']) && $_FILES[$input_file_name]['name'] == null) || |
| 621 | !isset($_FILES[$input_file_name]['tmp_name']) || |
| 622 | (isset($_FILES[$input_file_name]['tmp_name']) && $_FILES[$input_file_name]['tmp_name'] == null) |
| 623 | ) { |
| 624 | return static::__('You did not upload any file, please upload a file to get info.'); |
| 625 | } |
| 626 | |
| 627 | if (!function_exists('finfo_open') || !function_exists('finfo_file')) { |
| 628 | return static::__('There is no finfo_open() function or finfo_file() function to get file\'s info. Please verify PHP installation.'); |
| 629 | } |
| 630 | |
| 631 | $output = sprintf(static::__('File name: %s'), $_FILES[$input_file_name]['name']).'<br>'."\n"; |
| 632 | $file_name_exp = explode('.', $_FILES[$input_file_name]['name']); |
| 633 | $file_extension = $file_name_exp[count($file_name_exp)-1]; |
| 634 | unset($file_name_exp); |
| 635 | $output .= sprintf(static::__('File extension: %s'), $file_extension).'<br>'."\n"; |
| 636 | |
| 637 | $Finfo = new \finfo(); |
| 638 | $file_mimetype = $Finfo->file($_FILES[$input_file_name]['tmp_name'], FILEINFO_MIME_TYPE); |
| 639 | $output .= sprintf(static::__('Mime type: %s'), $file_mimetype).'<br>'."\n"; |
| 640 | $output .= '<br>'."\n"; |
| 641 | $output .= static::__('The array for use with extension-mime types validation.').'<br>'."\n"; |
| 642 | $output .= 'array(<br>'."\n"; |
| 643 | $output .= ' \''.$file_extension.'\' => array(\''.$file_mimetype.'\'),<br>'."\n"; |
| 644 | $output .= ');'."\n"; |
| 645 | unset($Finfo); |
| 646 | |
| 647 | if (is_writable($_FILES[$input_file_name]['tmp_name'])) { |
| 648 | unlink($_FILES[$input_file_name]['tmp_name']); |
| 649 | } |
| 650 | |
| 651 | unset($file_extension, $file_mimetype); |
| 652 | return $output; |
| 653 | }// testGetUploadedMimetype |
| 654 | |
| 655 | |
| 656 | /** |
| 657 | * Start the upload and move uploaded files process. |
| 658 | * |
| 659 | * @return boolean Return true on success, false for otherwise. If upload multiple file and there is error only one it return false. |
| 660 | */ |
| 661 | public function upload() |
| 662 | { |
| 663 | // validate that all options properties was properly set to correct type. |
| 664 | $this->validateOptionsProperties(); |
| 665 | // setup file extensions and mime types for validation. (in case that it was not set). |
| 666 | $this->setupFileExtensionsMimeTypesForValidation(); |
| 667 | |
| 668 | // verify that location where the uploaded file(s) will be moved to is writable. |
| 669 | if (!is_dir($this->move_uploaded_to)) { |
| 670 | $this->setErrorMessage( |
| 671 | static::__('The target location where the uploaded file(s) will be moved to is not folder or directory.'), |
| 672 | 'RDU_MOVE_UPLOADED_TO_NOT_DIR', |
| 673 | $this->move_uploaded_to |
| 674 | ); |
| 675 | return false; |
| 676 | } elseif (is_dir($this->move_uploaded_to) && !is_writable($this->move_uploaded_to)) { |
| 677 | $this->setErrorMessage( |
| 678 | static::__('The target location where the uploaded file(s) will be moved to is not writable. Please check the folder permission.'), |
| 679 | 'RDU_MOVE_UPLOADED_TO_NOT_WRITABLE', |
| 680 | $this->move_uploaded_to |
| 681 | ); |
| 682 | return false; |
| 683 | } else { |
| 684 | // solve the move uploaded to as a real path. |
| 685 | $this->move_uploaded_to = realpath($this->move_uploaded_to); |
| 686 | } |
| 687 | |
| 688 | if (isset($_FILES[$this->input_file_name]['name']) && is_array($_FILES[$this->input_file_name]['name'])) { |
| 689 | foreach ($_FILES[$this->input_file_name]['name'] as $key => $value) { |
| 690 | $this->files[$this->input_file_name]['input_file_key'] = $key; |
| 691 | $this->files[$this->input_file_name]['name'] = $_FILES[$this->input_file_name]['name'][$key]; |
| 692 | $this->files[$this->input_file_name]['type'] = (isset($_FILES[$this->input_file_name]['type'][$key]) ? $_FILES[$this->input_file_name]['type'][$key] : null); |
| 693 | $this->files[$this->input_file_name]['tmp_name'] = (isset($_FILES[$this->input_file_name]['tmp_name'][$key]) ? $_FILES[$this->input_file_name]['tmp_name'][$key] : null); |
| 694 | $this->files[$this->input_file_name]['error'] = (isset($_FILES[$this->input_file_name]['error'][$key]) ? $_FILES[$this->input_file_name]['error'][$key] : 4); |
| 695 | $this->files[$this->input_file_name]['size'] = (isset($_FILES[$this->input_file_name]['size'][$key]) ? $_FILES[$this->input_file_name]['size'][$key] : 0); |
| 696 | |
| 697 | $result = $this->uploadSingleFile(); |
| 698 | |
| 699 | if ($result == false && $this->stop_on_failed_upload_multiple === true) { |
| 700 | // it was set to sop on failed to upload multiple file. return false. |
| 701 | unset($result); |
| 702 | return false; |
| 703 | } |
| 704 | }// endforeach; |
| 705 | unset($key, $value); |
| 706 | } else { |
| 707 | $this->files[$this->input_file_name] = $_FILES[$this->input_file_name]; |
| 708 | $this->files[$this->input_file_name]['input_file_key'] = 0; |
| 709 | |
| 710 | $result = $this->uploadSingleFile(); |
| 711 | } |
| 712 | |
| 713 | if (isset($result) && $result == false && $this->stop_on_failed_upload_multiple === true) { |
| 714 | // there is at lease one upload error and it was set to stop on error. |
| 715 | unset($result); |
| 716 | $this->clearUploadedAtTemp(); |
| 717 | return false; |
| 718 | } elseif (count($this->error_messages) > 0 && $this->stop_on_failed_upload_multiple === true) { |
| 719 | // there is at lease one upload error and it was set to stop on error. |
| 720 | unset($result); |
| 721 | $this->clearUploadedAtTemp(); |
| 722 | return false; |
| 723 | } |
| 724 | |
| 725 | return $this->moveUploadedFiles(); |
| 726 | }// upload |
| 727 | |
| 728 | |
| 729 | /** |
| 730 | * Start upload process for single file.<br> |
| 731 | * Even upload multiple file will call to this method because it will be re-format the uploaded files property to become a single file and then call this. |
| 732 | * |
| 733 | * @return boolean Return true on success, false for otherwise. |
| 734 | */ |
| 735 | protected function uploadSingleFile() |
| 736 | { |
| 737 | // check if there is error while uploading from error array key. |
| 738 | if (is_array($this->files[$this->input_file_name]) && array_key_exists('error', $this->files[$this->input_file_name]) && $this->files[$this->input_file_name]['error'] != 0) { |
| 739 | switch ($this->files[$this->input_file_name]['error']) { |
| 740 | case 1: |
| 741 | $this->setErrorMessage( |
| 742 | sprintf(static::__('The uploaded file exceeds the max file size directive. (%s > %s).'), $this->files[$this->input_file_name]['size'], ini_get('upload_max_filesize')), |
| 743 | 'RDU_' . $this->files[$this->input_file_name]['error'], |
| 744 | $this->files[$this->input_file_name]['size'] . ' > ' . ini_get('upload_max_filesize'), |
| 745 | $this->files[$this->input_file_name]['name'], |
| 746 | $this->files[$this->input_file_name]['size'], |
| 747 | $this->files[$this->input_file_name]['type'] |
| 748 | ); |
| 749 | return false; |
| 750 | case 2: |
| 751 | $this->setErrorMessage( |
| 752 | static::__('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.'), |
| 753 | 'RDU_' . $this->files[$this->input_file_name]['error'], |
| 754 | '', |
| 755 | $this->files[$this->input_file_name]['name'], |
| 756 | $this->files[$this->input_file_name]['size'], |
| 757 | $this->files[$this->input_file_name]['type'] |
| 758 | ); |
| 759 | return false; |
| 760 | case 3: |
| 761 | $this->setErrorMessage( |
| 762 | static::__('The uploaded file was only partially uploaded.'), |
| 763 | 'RDU_' . $this->files[$this->input_file_name]['error'], |
| 764 | '', |
| 765 | $this->files[$this->input_file_name]['name'], |
| 766 | $this->files[$this->input_file_name]['size'], |
| 767 | $this->files[$this->input_file_name]['type'] |
| 768 | ); |
| 769 | return false; |
| 770 | case 4: |
| 771 | $this->setErrorMessage( |
| 772 | static::__('You did not upload the file.'), |
| 773 | 'RDU_' . $this->files[$this->input_file_name]['error'], |
| 774 | '', |
| 775 | $this->files[$this->input_file_name]['name'], |
| 776 | $this->files[$this->input_file_name]['size'], |
| 777 | $this->files[$this->input_file_name]['type'] |
| 778 | ); |
| 779 | return false; |
| 780 | case 6: |
| 781 | $this->setErrorMessage( |
| 782 | static::__('Missing a temporary folder.'), |
| 783 | 'RDU_' . $this->files[$this->input_file_name]['error'], |
| 784 | '', |
| 785 | $this->files[$this->input_file_name]['name'], |
| 786 | $this->files[$this->input_file_name]['size'], |
| 787 | $this->files[$this->input_file_name]['type'] |
| 788 | ); |
| 789 | return false; |
| 790 | case 7: |
| 791 | $this->setErrorMessage( |
| 792 | static::__('Failed to write file to disk.'), |
| 793 | 'RDU_' . $this->files[$this->input_file_name]['error'], |
| 794 | '', |
| 795 | $this->files[$this->input_file_name]['name'], |
| 796 | $this->files[$this->input_file_name]['size'], |
| 797 | $this->files[$this->input_file_name]['type'] |
| 798 | ); |
| 799 | return false; |
| 800 | case 8: |
| 801 | $this->setErrorMessage( |
| 802 | static::__('A PHP extension stopped the file upload.'), |
| 803 | 'RDU_' . $this->files[$this->input_file_name]['error'], |
| 804 | '', |
| 805 | $this->files[$this->input_file_name]['name'], |
| 806 | $this->files[$this->input_file_name]['size'], |
| 807 | $this->files[$this->input_file_name]['type'] |
| 808 | ); |
| 809 | return false; |
| 810 | } |
| 811 | } |
| 812 | |
| 813 | // validate that there is file upload. |
| 814 | if ( |
| 815 | empty($this->files[$this->input_file_name]) || |
| 816 | ( |
| 817 | is_array($this->files[$this->input_file_name]) && |
| 818 | array_key_exists('name', $this->files[$this->input_file_name]) && |
| 819 | $this->files[$this->input_file_name]['name'] == null |
| 820 | ) || |
| 821 | ( |
| 822 | is_array($this->files[$this->input_file_name]) && |
| 823 | array_key_exists('tmp_name', $this->files[$this->input_file_name]) && |
| 824 | $this->files[$this->input_file_name]['tmp_name'] == null |
| 825 | ) |
| 826 | ) { |
| 827 | $this->setErrorMessage( |
| 828 | static::__('You did not upload the file.'), |
| 829 | 'RDU_4', |
| 830 | '', |
| 831 | $this->files[$this->input_file_name]['name'], |
| 832 | $this->files[$this->input_file_name]['size'], |
| 833 | $this->files[$this->input_file_name]['type'] |
| 834 | ); |
| 835 | return false; |
| 836 | } |
| 837 | |
| 838 | // validate allowed extension and its mime types. |
| 839 | $result = $this->validateExtensionAndMimeType(); |
| 840 | if ($result !== true) { |
| 841 | return false; |
| 842 | } |
| 843 | unset($result); |
| 844 | |
| 845 | // validate max file size. |
| 846 | $result = $this->validateFileSize(); |
| 847 | if ($result !== true) { |
| 848 | return false; |
| 849 | } |
| 850 | unset($result); |
| 851 | |
| 852 | // security scan. |
| 853 | if ($this->security_scan === true) { |
| 854 | $result = $this->securityScan(); |
| 855 | if ($result !== true) { |
| 856 | return false; |
| 857 | } |
| 858 | unset($result); |
| 859 | } |
| 860 | |
| 861 | // set new file name (in case that it was not set) and check for reserved file name. |
| 862 | $tmp_new_file_name = $this->new_file_name; |
| 863 | $this->setNewFileName(); |
| 864 | |
| 865 | // check for safe web file name if this option was set to true. |
| 866 | if ($this->web_safe_file_name === true) { |
| 867 | $this->setWebSafeFileName(); |
| 868 | } |
| 869 | |
| 870 | // now, it should all passed validation. add the uploaded file to move uploaded queue in case that it is upload multiple file and has option to stop on error. |
| 871 | // get the uploaded file extension. |
| 872 | $file_name_explode = explode('.', $this->files[$this->input_file_name]['name']); |
| 873 | $file_extension = null; |
| 874 | if (is_array($file_name_explode)) { |
| 875 | $file_extension = '.'.$file_name_explode[count($file_name_explode)-1]; |
| 876 | } |
| 877 | unset($file_name_explode); |
| 878 | // add to queue. |
| 879 | $this->move_uploaded_queue = array_merge( |
| 880 | $this->move_uploaded_queue, |
| 881 | array( |
| 882 | $this->files[$this->input_file_name]['input_file_key'] => array( |
| 883 | 'name' => $this->files[$this->input_file_name]['name'], |
| 884 | 'tmp_name' => $this->files[$this->input_file_name]['tmp_name'], |
| 885 | 'new_name' => $this->new_file_name.$file_extension, |
| 886 | ) |
| 887 | ) |
| 888 | ); |
| 889 | // restore temp of new file name to ready for next loop of upload multiple. |
| 890 | $this->new_file_name = $tmp_new_file_name; |
| 891 | unset($file_extension, $tmp_new_file_name); |
| 892 | |
| 893 | // done. |
| 894 | return true; |
| 895 | }// uploadSingleFile |
| 896 | |
| 897 | |
| 898 | /** |
| 899 | * Validate allowed extension and its mime types (if all of these was set). |
| 900 | * |
| 901 | * @return boolean Return true on success, false on failure. |
| 902 | */ |
| 903 | protected function validateExtensionAndMimeType() |
| 904 | { |
| 905 | if ($this->allowed_file_extensions == null && ($this->file_extensions_mime_types == null || empty($this->file_extensions_mime_types))) { |
| 906 | // it is not set to limit uploaded file extensions and mime types. |
| 907 | return true; |
| 908 | } |
| 909 | |
| 910 | // get only file extension of uploaded file. |
| 911 | $file_name_explode = explode('.', $this->files[$this->input_file_name]['name']); |
| 912 | if (!is_array($file_name_explode)) { |
| 913 | unset($file_name_explode); |
| 914 | $this->setErrorMessage( |
| 915 | sprintf(static::__('Unable to validate extension for the file %s.'), $this->files[$this->input_file_name]['name']), |
| 916 | 'RDU_UNABLE_VALIDATE_EXT', |
| 917 | $this->files[$this->input_file_name]['name'], |
| 918 | $this->files[$this->input_file_name]['name'], |
| 919 | $this->files[$this->input_file_name]['size'], |
| 920 | $this->files[$this->input_file_name]['type'] |
| 921 | ); |
| 922 | return false; |
| 923 | } |
| 924 | $file_extension = strtolower($file_name_explode[count($file_name_explode)-1]); |
| 925 | unset($file_name_explode); |
| 926 | |
| 927 | // validate allowed extensions. |
| 928 | if (is_array($this->allowed_file_extensions) && !in_array($file_extension, $this->allowed_file_extensions)) { |
| 929 | unset($file_extension); |
| 930 | $this->setErrorMessage( |
| 931 | sprintf(static::__('You have uploaded the file that is not allowed extension. (%s)'), $this->files[$this->input_file_name]['name']), |
| 932 | 'RDU_NOT_ALLOW_EXT', |
| 933 | $this->files[$this->input_file_name]['name'], |
| 934 | $this->files[$this->input_file_name]['name'], |
| 935 | $this->files[$this->input_file_name]['size'], |
| 936 | $this->files[$this->input_file_name]['type'] |
| 937 | ); |
| 938 | return false; |
| 939 | } |
| 940 | |
| 941 | // validate allowed mime types that match uploaded file's extension. |
| 942 | if (is_array($this->file_extensions_mime_types) && !empty($this->file_extensions_mime_types)) { |
| 943 | if (!array_key_exists($file_extension, $this->file_extensions_mime_types)) { |
| 944 | unset($file_extension); |
| 945 | $this->setErrorMessage( |
| 946 | sprintf(static::__('Unable to validate the file extension and mime type. (%s). This file extension was not set in the "file_extensions_mime_types" property.'), $this->files[$this->input_file_name]['name']), |
| 947 | 'RDU_UNABLE_VALIDATE_EXT_AND_MIME', |
| 948 | $this->files[$this->input_file_name]['name'], |
| 949 | $this->files[$this->input_file_name]['name'], |
| 950 | $this->files[$this->input_file_name]['size'], |
| 951 | $this->files[$this->input_file_name]['type'] |
| 952 | ); |
| 953 | return false; |
| 954 | } else { |
| 955 | $Finfo = new \finfo(); |
| 956 | $file_mimetype = $Finfo->file($this->files[$this->input_file_name]['tmp_name'], FILEINFO_MIME_TYPE); |
| 957 | if (is_array($this->file_extensions_mime_types[$file_extension]) && !in_array(strtolower($file_mimetype), array_map('strtolower', $this->file_extensions_mime_types[$file_extension]))) { |
| 958 | unset($file_extension, $Finfo); |
| 959 | $this->setErrorMessage( |
| 960 | sprintf(static::__('The uploaded file has invalid mime type. (%s : %s).'), $this->files[$this->input_file_name]['name'], $file_mimetype), |
| 961 | 'RDU_INVALID_MIME', |
| 962 | $this->files[$this->input_file_name]['name'] . ' : ' . $file_mimetype, |
| 963 | $this->files[$this->input_file_name]['name'], |
| 964 | $this->files[$this->input_file_name]['size'], |
| 965 | $file_mimetype |
| 966 | ); |
| 967 | unset($file_mimetype); |
| 968 | return false; |
| 969 | } elseif (!is_array($this->file_extensions_mime_types[$file_extension])) { |
| 970 | unset($file_extension, $file_mimetype, $Finfo); |
| 971 | $this->setErrorMessage( |
| 972 | static::__('Unable to validate mime type. The format of "file_extensions_mime_types" property is incorrect.'), |
| 973 | 'RDU_UNABLE_VALIDATE_MIME', |
| 974 | '', |
| 975 | $this->files[$this->input_file_name]['name'], |
| 976 | $this->files[$this->input_file_name]['size'], |
| 977 | $this->files[$this->input_file_name]['type'] |
| 978 | ); |
| 979 | return false; |
| 980 | } |
| 981 | unset($file_mimetype, $Finfo); |
| 982 | } |
| 983 | } |
| 984 | |
| 985 | unset($file_extension); |
| 986 | return true; |
| 987 | }// validateExtensionAndMimeType |
| 988 | |
| 989 | |
| 990 | /** |
| 991 | * Validate uploaded file must not exceed max file size limit. (if max file size limit was set). |
| 992 | * |
| 993 | * @return boolean Return true on success, false on failure. |
| 994 | */ |
| 995 | protected function validateFileSize() |
| 996 | { |
| 997 | if (!is_numeric($this->max_file_size) && !is_int($this->max_file_size)) { |
| 998 | // it is not set max file size limitation. |
| 999 | return true; |
| 1000 | } |
| 1001 | |
| 1002 | if (is_array($this->files[$this->input_file_name]) && array_key_exists('size', $this->files[$this->input_file_name]) && $this->files[$this->input_file_name]['size'] > $this->max_file_size) { |
| 1003 | $this->setErrorMessage( |
| 1004 | sprintf(static::__('The uploaded file exceeds the max file size directive. (%s > %s).'), $this->files[$this->input_file_name]['size'], $this->max_file_size), |
| 1005 | 'RDU_1', |
| 1006 | $this->files[$this->input_file_name]['size'] . ' > ' . $this->max_file_size, |
| 1007 | $this->files[$this->input_file_name]['name'], |
| 1008 | $this->files[$this->input_file_name]['size'], |
| 1009 | $this->files[$this->input_file_name]['type'] |
| 1010 | ); |
| 1011 | return false; |
| 1012 | } |
| 1013 | |
| 1014 | return true; |
| 1015 | }// validateFileSize |
| 1016 | |
| 1017 | |
| 1018 | /** |
| 1019 | * Validate that these options properties has properly set in the correct type. |
| 1020 | */ |
| 1021 | protected function validateOptionsProperties() |
| 1022 | { |
| 1023 | if (!is_array($this->allowed_file_extensions) && $this->allowed_file_extensions != null) { |
| 1024 | $this->allowed_file_extensions = array($this->allowed_file_extensions); |
| 1025 | } |
| 1026 | |
| 1027 | if (!is_array($this->file_extensions_mime_types) && $this->file_extensions_mime_types != null) { |
| 1028 | $this->file_extensions_mime_types = null; |
| 1029 | } |
| 1030 | |
| 1031 | if (is_numeric($this->max_file_size) && !is_int($this->max_file_size)) { |
| 1032 | $this->max_file_size = intval($this->max_file_size); |
| 1033 | } elseif (!is_int($this->max_file_size) && $this->max_file_size != null) { |
| 1034 | $this->max_file_size = null; |
| 1035 | } |
| 1036 | |
| 1037 | if ($this->move_uploaded_to == null) { |
| 1038 | $this->move_uploaded_to = '.'; |
| 1039 | } |
| 1040 | |
| 1041 | if (!is_string($this->new_file_name) && $this->new_file_name != null) { |
| 1042 | $this->new_file_name = null; |
| 1043 | } |
| 1044 | |
| 1045 | if (!is_bool($this->overwrite)) { |
| 1046 | $this->overwrite = false; |
| 1047 | } |
| 1048 | |
| 1049 | if (!is_bool($this->web_safe_file_name)) { |
| 1050 | $this->web_safe_file_name = true; |
| 1051 | } |
| 1052 | |
| 1053 | if (!is_bool($this->security_scan)) { |
| 1054 | $this->security_scan = false; |
| 1055 | } |
| 1056 | |
| 1057 | if (!is_bool($this->stop_on_failed_upload_multiple)) { |
| 1058 | $this->stop_on_failed_upload_multiple = true; |
| 1059 | } |
| 1060 | }// validateOptionsProperties |
| 1061 | |
| 1062 | |
| 1063 | } |