permit_file_extensions = $permit_file_extensions; } if($target_dir) { $this->target_dir = PUBLIC_DIR . DIRECTORY_SEPARATOR. $target_dir; $this->public_dir = "/".$target_dir; } $setup_res = $this->setUp(); if($setup_res->getStatus() == AppResponse::SUCCESS) { $this->setup_success = true; } } /** * @description (rename if set) and resize file * @param string $name * @param string $new_name * @param array $resized_sizes [] array('small' => ['width' => 100, 'height' => 100], 'large' => ['width' => 200, 'height' => 200] ) * @return array|false */ public function resizeFile(string $name, string $new_name = '', array $resized_sizes = []) { if($new_name) { $renamed = $this->renameFile($name, $new_name); if(!$renamed) { return false; } //$file_name = $renamed['file_name']; //$public_path = $renamed['public_path']; $local_path = $renamed['local_path']; }else{ //$file_name = $name; //$public_path = $this->public_dir . "/".$name; $local_path = $this->target_dir . "/" . $name; } $objHuraImage = new HuraImage(); list(, $expected_files, ) = $objHuraImage->resize($local_path, $resized_sizes); return $expected_files; } /** * @description we can rename the uploaded file to new file name, for example: we want product's image have the format [PRODUCT_ID]-name * @param string $name * @param string $new_name * @return array | false */ public function renameFile(string $name, string $new_name) { if(@rename($this->target_dir . "/" . $name, $this->target_dir . "/" . $new_name)){ return [ "file_name" => $new_name, "public_path" => $this->public_dir . "/".$new_name, "local_path" => $this->target_dir . "/" . $new_name, ]; } return false; } // public utility public static function getFileExtension($file_name) { return strtolower(strrchr($file_name,".")); } /** * @description run clean up after finish using the FileHandle instance */ public function cleanUp() { if($this->tmp_folder) { FileSystem::removeDir($this->tmp_folder); } } protected function processFile( $original_file_name, $original_file_tmp_name, // temporary uploaded file as in case of $_FILES[$input_file_name]["tmp_name"] $fixed_file_name="", $max_file_size=0 ) : FileHandleResponse { if(!$original_file_name) { return new FileHandleResponse(AppResponse::ERROR, 'no file', null); } $file_size = filesize($original_file_tmp_name); if($max_file_size > 0 && $max_file_size < $file_size) { return new FileHandleResponse(AppResponse::ERROR, 'Size is too large: '.round($file_size/1000).'KB', null); } //validate extension $file_ext = self::getFileExtension($original_file_name); if(!in_array($file_ext, $this->permit_file_extensions)) { return new FileHandleResponse(AppResponse::ERROR, "Type ".$file_ext." is not allowed!", null); } $file_name = substr($original_file_name, 0, strrpos($original_file_name,".")); $file_name = preg_replace("/[^a-z0-9_-]/i","", $file_name); $file_name = substr($file_name, 0, 50); // max- length $clean_file_name = ($fixed_file_name) ?: $file_name . $file_ext; $tmp_file_path = $this->tmp_folder . "/". $clean_file_name; $return_data = null; //debug_var([$original_data, $tmp_file_path]); if(@rename($original_file_tmp_name, $tmp_file_path)){ $is_file_image = (in_array($file_ext, static::$image_extensions )); if($is_file_image) { list($width, $height) = getimagesize($tmp_file_path); }else{ $width = 0; $height = 0; } $detector = new FinfoMimeTypeDetector(); $mimeType = $detector->detectMimeTypeFromPath($tmp_file_path); // if image, we re-create and optimize it if($is_file_image) { if(in_array($mimeType, $this->permit_mine_types)) { $objHuraImage = new HuraImage(); if($objHuraImage->create($tmp_file_path, $this->target_dir . DIRECTORY_SEPARATOR . $clean_file_name)){ $return_data = new FileHandleInfo([ "file_name" => $clean_file_name, "public_path" => $this->public_dir . "/".$clean_file_name, "local_path" => $this->target_dir . "/" . $clean_file_name, "mime_type" => $mimeType, "file_size" => $file_size, "file_ext" => $file_ext, "width" => $width, "height" => $height, ]); } } }elseif(@rename ($tmp_file_path, $this->target_dir . DIRECTORY_SEPARATOR . $clean_file_name )) { $return_data = new FileHandleInfo([ "file_name" => $clean_file_name, "public_path" => $this->public_dir . "/".$clean_file_name, "local_path" => $this->target_dir . "/" . $clean_file_name, "mime_type" => $mimeType, "file_size" => $file_size, "file_ext" => $file_ext, "width" => 0, "height" => 0, ]); } } // delete tmp file on server if(file_exists($original_file_tmp_name)) { @unlink($original_file_tmp_name); } if($return_data) { return new FileHandleResponse(AppResponse::SUCCESS, 'Success', $return_data); } return new FileHandleResponse(AppResponse::ERROR, 'Unknown', null); } protected function setUp(): AppResponse { // check target dir if($this->target_dir && !is_dir($this->target_dir)) { @mkdir($this->target_dir, 0755, true); } if(!file_exists($this->target_dir)) { return new AppResponse(AppResponse::ERROR, $this->target_dir.' not exists'); } // create tmp_folder to upload file to $this->tmp_folder = $this->create_tmp_folder(); if(!$this->tmp_folder) { return new AppResponse(AppResponse::ERROR, "Check ".$this->tmp_dir." and make sure it exists and writable"); } return new AppResponse(AppResponse::SUCCESS); } protected function create_tmp_folder() : ?string { $tmp_folder = $this->tmp_dir . IDGenerator::createStringId(5); if(!@mkdir($tmp_folder, 0777, true)) { return null; } // retest if(!$tmp_folder || !is_dir($tmp_folder)) { return null; } return $tmp_folder; } }