mirror of
				https://github.com/billz/raspap-webgui.git
				synced 2025-03-01 10:31:47 +00:00 
			
		
		
		
	Initial commit
This commit is contained in:
		
							
								
								
									
										503
									
								
								app/lib/uploader.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										503
									
								
								app/lib/uploader.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,503 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Simple PHP upload class | ||||
|  * | ||||
|  * Adapted from aivis/PHP-file-upload-class | ||||
|  * | ||||
|  * @description File upload class for RaspAP | ||||
|  * @author      Bill Zimmerman <billzimmerman@gmail.com> | ||||
|  * @author      Aivis Silins | ||||
|  * @link        https://github.com/aivis/PHP-file-upload-class | ||||
|  * @license     https://github.com/raspap/raspap-webgui/blob/master/LICENSE | ||||
|  */ | ||||
|  | ||||
| class Upload | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Default directory persmissions (destination) | ||||
|      */ | ||||
|     protected $default_permissions = 0750; | ||||
|  | ||||
|     /** | ||||
|      * File post array | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $file_post = array(); | ||||
|  | ||||
|     /** | ||||
|      * Destination directory | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $destination; | ||||
|  | ||||
|     /** | ||||
|      * Fileinfo | ||||
|      * | ||||
|      * @var object | ||||
|      */ | ||||
|     protected $finfo; | ||||
|  | ||||
|     /** | ||||
|      * Data about file | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     public $file = array(); | ||||
|  | ||||
|     /** | ||||
|      * Max. file size | ||||
|      * | ||||
|      * @var int | ||||
|      */ | ||||
|     protected $max_file_size; | ||||
|  | ||||
|     /** | ||||
|      * Allowed mime types | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $mimes = array(); | ||||
|  | ||||
|     /** | ||||
|      * Temp path | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $tmp_name; | ||||
|  | ||||
|     /** | ||||
|      * Validation errors | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $validation_errors = array(); | ||||
|  | ||||
|     /** | ||||
|      * Filename (new) | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $filename; | ||||
|  | ||||
|     /** | ||||
|      * Internal callbacks (filesize check, mime, etc) | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     private $callbacks = array(); | ||||
|  | ||||
|     /** | ||||
|      * Root dir | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $root; | ||||
|  | ||||
|     /** | ||||
|      * Return upload object | ||||
|      * | ||||
|      * $destination    = 'path/to/file/destination/'; | ||||
|      * | ||||
|      * @param  string $destination | ||||
|      * @param  string $root | ||||
|      * @return Upload | ||||
|      */ | ||||
|     public static function factory($destination, $root = false) | ||||
|     { | ||||
|         return new Upload($destination, $root); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      *  Define root constant and set & create destination path | ||||
|      * | ||||
|      * @param string $destination | ||||
|      * @param string $root | ||||
|      */ | ||||
|     public function __construct($destination, $root = false) | ||||
|     { | ||||
|         if ($root) { | ||||
|             $this->root = $root; | ||||
|         } else { | ||||
|             $this->root = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR; | ||||
|         } | ||||
|  | ||||
|         // set & create destination path | ||||
|         if (!$this->set_destination($destination)) { | ||||
|             throw new Exception('Upload: Unable to create destination. '.$this->root . $this->destination); | ||||
|         } | ||||
|         //create finfo object | ||||
|         $this->finfo = new finfo(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set target filename | ||||
|      * | ||||
|      * @param string $filename | ||||
|      */ | ||||
|     public function set_filename($filename) | ||||
|     { | ||||
|         $this->filename = $filename; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check & Save file | ||||
|      * | ||||
|      * Return data about current upload | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function upload($filename = false) | ||||
|     { | ||||
|         if($filename ) { | ||||
|             $this->set_filename($filename); | ||||
|         } | ||||
|  | ||||
|         $this->set_filename($filename); | ||||
|          | ||||
|         if ($this->check()) { | ||||
|             $this->save(); | ||||
|         } | ||||
|  | ||||
|         // return state data | ||||
|         return $this->get_state(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Save file on server | ||||
|      * Return state data | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function save() | ||||
|     { | ||||
|         $this->save_file(); | ||||
|         return $this->get_state(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Validate file (execute callbacks) | ||||
|      * Returns TRUE if validation successful | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function check() | ||||
|     { | ||||
|         //execute callbacks (check filesize, mime, also external callbacks | ||||
|         $this->validate(); | ||||
|  | ||||
|         //add error messages | ||||
|         $this->file['errors'] = $this->get_errors(); | ||||
|  | ||||
|         //change file validation status | ||||
|         $this->file['status'] = empty($this->validation_errors); | ||||
|  | ||||
|         return $this->file['status']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get current state data | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function get_state() | ||||
|     { | ||||
|         return $this->file; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Save file on server | ||||
|      */ | ||||
|     protected function save_file() | ||||
|     { | ||||
|         //create & set new filename | ||||
|         if(empty($this->filename)) { | ||||
|             $this->create_new_filename(); | ||||
|         } | ||||
|  | ||||
|         //set filename | ||||
|         $this->file['filename'] = $this->filename; | ||||
|  | ||||
|         //set full path | ||||
|         $this->file['full_path'] = $this->root . $this->destination . $this->filename; | ||||
|             $this->file['path'] = $this->destination . $this->filename; | ||||
|  | ||||
|         $status = move_uploaded_file($this->tmp_name, $this->file['full_path']); | ||||
|  | ||||
|         //checks whether upload successful | ||||
|         if (!$status) { | ||||
|             throw new Exception('Upload: Failed to upload file.'); | ||||
|         } | ||||
|  | ||||
|         //done | ||||
|         $this->file['status'] = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set data about file | ||||
|      */ | ||||
|     protected function set_file_data() | ||||
|     { | ||||
|         $file_size = $this->get_file_size(); | ||||
|         $this->file = array( | ||||
|         'status'            => false, | ||||
|         'destination'       => $this->destination, | ||||
|         'size_in_bytes'     => $file_size, | ||||
|         'size_in_mb'        => $this->bytes_to_mb($file_size), | ||||
|         'mime'              => $this->get_file_mime(), | ||||
|         'filename'          => $this->file_post['name'], | ||||
|         'tmp_name'          => $this->file_post['tmp_name'], | ||||
|         'post_data'         => $this->file_post, | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set validation error | ||||
|      * | ||||
|      * @param string $message | ||||
|      */ | ||||
|     public function set_error($message) | ||||
|     { | ||||
|         $this->validation_errors[] = $message; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Return validation errors | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function get_errors() | ||||
|     { | ||||
|         return $this->validation_errors; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set external callback methods | ||||
|      * | ||||
|      * @param object $instance_of_callback_object | ||||
|      * @param array  $callback_methods | ||||
|      */ | ||||
|     public function callbacks($instance_of_callback_object, $callback_methods) | ||||
|     { | ||||
|         if (empty($instance_of_callback_object)) { | ||||
|             throw new Exception('Upload: $instance_of_callback_object cannot be empty.'); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         if (!is_array($callback_methods)) { | ||||
|             throw new Exception('Upload: $callback_methods data type need to be array.'); | ||||
|         } | ||||
|  | ||||
|         $this->external_callback_object = $instance_of_callback_object; | ||||
|         $this->external_callback_methods = $callback_methods; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute callbacks | ||||
|      */ | ||||
|     protected function validate() | ||||
|     { | ||||
|         //get curent errors | ||||
|         $errors = $this->get_errors(); | ||||
|  | ||||
|         if (empty($errors)) { | ||||
|  | ||||
|             //set data about current file | ||||
|             $this->set_file_data(); | ||||
|  | ||||
|             //execute internal callbacks | ||||
|             $this->execute_callbacks($this->callbacks, $this); | ||||
|  | ||||
|             //execute external callbacks | ||||
|             $this->execute_callbacks($this->external_callback_methods, $this->external_callback_object); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Execute callbacks | ||||
|      */ | ||||
|     protected function execute_callbacks($callbacks, $object) | ||||
|     { | ||||
|         foreach($callbacks as $method) { | ||||
|             $object->$method($this); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * File mime type validation callback | ||||
|      * | ||||
|      * @param object $object | ||||
|      */ | ||||
|     protected function check_mime_type($object) | ||||
|     { | ||||
|         if (!empty($object->mimes)) { | ||||
|             if (!in_array($object->file['mime'], $object->mimes)) { | ||||
|                 $object->set_error('Mime type not allowed.'); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set allowed mime types | ||||
|      * | ||||
|      * @param array $mimes | ||||
|      */ | ||||
|     public function set_allowed_mime_types($mimes) | ||||
|     { | ||||
|         $this->mimes        = $mimes; | ||||
|         //if mime types is set -> set callback | ||||
|         $this->callbacks[]    = 'check_mime_type'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * File size validation callback | ||||
|      * | ||||
|      * @param object $object | ||||
|      */ | ||||
|     protected function check_file_size($object) | ||||
|     { | ||||
|         if (!empty($object->max_file_size)) { | ||||
|             $file_size_in_mb = $this->bytes_to_mb($object->file['size_in_bytes']); | ||||
|             if ($object->max_file_size <= $file_size_in_mb) { | ||||
|                 $object->set_error('File exceeds maximum allowed size.'); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set max file size | ||||
|      * | ||||
|      * @param int $size | ||||
|      */ | ||||
|     public function set_max_file_size($size) | ||||
|     { | ||||
|         $this->max_file_size = $size; | ||||
|          | ||||
|         //if max file size is set -> set callback | ||||
|         $this->callbacks[] = 'check_file_size'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set File array to object | ||||
|      * | ||||
|      * @param array $file | ||||
|      */ | ||||
|     public function file($file) | ||||
|     { | ||||
|         $this->set_file_array($file); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set file array | ||||
|      * | ||||
|      * @param array $file | ||||
|      */ | ||||
|     protected function set_file_array($file) | ||||
|     { | ||||
|         //checks whether file array is valid | ||||
|         if (!$this->check_file_array($file)) { | ||||
|             //file not selected or some bigger problems (broken files array) | ||||
|             $this->set_error('Please select file.'); | ||||
|         } | ||||
|  | ||||
|         //set file data | ||||
|         $this->file_post = $file; | ||||
|  | ||||
|         //set tmp path | ||||
|         $this->tmp_name  = $file['tmp_name']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks whether Files post array is valid | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function check_file_array($file) | ||||
|     { | ||||
|         return isset($file['error']) | ||||
|         && !empty($file['name']) | ||||
|         && !empty($file['type']) | ||||
|         && !empty($file['tmp_name']) | ||||
|         && !empty($file['size']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get file mime type | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function get_file_mime() | ||||
|     { | ||||
|         return $this->finfo->file($this->tmp_name, FILEINFO_MIME_TYPE); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get file size | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     protected function get_file_size() | ||||
|     { | ||||
|         return filesize($this->tmp_name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set destination path (return TRUE on success) | ||||
|      * | ||||
|      * @param  string $destination | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function set_destination($destination) | ||||
|     { | ||||
|         $this->destination = $destination . DIRECTORY_SEPARATOR; | ||||
|         return $this->destination_exist() ? true : $this->create_destination(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks whether destination folder exists | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function destination_exist() | ||||
|     { | ||||
|         return is_writable($this->root . $this->destination); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create path to destination | ||||
|      * | ||||
|      * @param  string $dir | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function create_destination() | ||||
|     { | ||||
|         return mkdir($this->root . $this->destination, $this->default_permissions, true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set unique filename | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function create_new_filename() | ||||
|     { | ||||
|         $filename = sha1(mt_rand(1, 9999) . $this->destination . uniqid()) . time(); | ||||
|         $this->set_filename($filename); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Convert bytes to MB | ||||
|      * | ||||
|      * @param  int $bytes | ||||
|      * @return int | ||||
|      */ | ||||
|     protected function bytes_to_mb($bytes) | ||||
|     { | ||||
|         return round(($bytes / 1048576), 2); | ||||
|     } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user