2016-12-28 14:21:52 +00:00
|
|
|
<?php
|
2019-12-23 17:50:43 +00:00
|
|
|
defined('PROJECT_PATH') OR exit('No direct script access allowed');
|
2016-12-28 14:21:52 +00:00
|
|
|
|
|
|
|
class Image
|
|
|
|
{
|
2019-12-23 22:06:59 +00:00
|
|
|
const THUMB_W = 476;
|
|
|
|
const THUMB_H = 476;
|
|
|
|
|
2020-06-25 15:56:35 +00:00
|
|
|
const PHP_FILE_UPLOAD_ERRORS = [
|
|
|
|
0 => 'There is no error, the file uploaded with success.',
|
|
|
|
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
|
|
|
|
2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
|
|
|
|
3 => 'The uploaded file was only partially uploaded.',
|
|
|
|
4 => 'No file was uploaded.',
|
|
|
|
6 => 'Missing a temporary folder.',
|
|
|
|
7 => 'Failed to write file to disk.',
|
|
|
|
8 => 'A PHP extension stopped the file upload.',
|
|
|
|
];
|
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
private static function random_str($len = 10){
|
|
|
|
$chr = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
|
|
$chr_len = strlen($chr);
|
|
|
|
$random_str = '';
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
for($i = 0; $i < $len; $i++){
|
|
|
|
$random_str .= $chr[rand(0, $chr_len - 1)];
|
|
|
|
}
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
return $random_str;
|
|
|
|
}
|
2019-11-08 21:01:58 +00:00
|
|
|
|
|
|
|
private static function fix_orientation($path, $img){
|
|
|
|
if(!function_exists('exif_read_data')){
|
|
|
|
return $img;
|
|
|
|
}
|
|
|
|
|
|
|
|
$exif = exif_read_data($path);
|
|
|
|
if(!$exif || !isset($exif['Orientation'])){
|
|
|
|
return $img;
|
|
|
|
}
|
|
|
|
|
|
|
|
$deg = 0;
|
|
|
|
switch($exif['Orientation']){
|
|
|
|
case 3:
|
|
|
|
$deg = 180;
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
$deg = 270;
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
$deg = 90;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($deg){
|
|
|
|
return imagerotate($img, $deg, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $img;
|
|
|
|
}
|
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
private static function thumb($source_path, $thumb_path){
|
|
|
|
ini_set('memory_limit', '128M');
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
$source_details = getimagesize($source_path);
|
|
|
|
$source_w = $source_details[0];
|
|
|
|
$source_h = $source_details[1];
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
if($source_w > $source_h){
|
2019-12-23 22:06:59 +00:00
|
|
|
$new_w = self::THUMB_W;
|
2016-12-28 14:21:52 +00:00
|
|
|
$new_h = intval($source_h * $new_w / $source_w);
|
|
|
|
} else {
|
2019-12-23 22:06:59 +00:00
|
|
|
$new_h = self::THUMB_H;
|
2016-12-28 14:21:52 +00:00
|
|
|
$new_w = intval($source_w * $new_h / $source_h);
|
|
|
|
}
|
2019-12-18 23:32:09 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
switch($source_details[2]){
|
|
|
|
case IMAGETYPE_GIF:
|
2019-12-23 22:06:59 +00:00
|
|
|
$imgt = "imagegif";
|
|
|
|
$imgcreatefrom = "imagecreatefromgif";
|
2016-12-28 14:21:52 +00:00
|
|
|
break;
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
case IMAGETYPE_JPEG:
|
2019-12-23 22:06:59 +00:00
|
|
|
$imgt = "imagejpeg";
|
|
|
|
$imgcreatefrom = "imagecreatefromjpeg";
|
2016-12-28 14:21:52 +00:00
|
|
|
break;
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
case IMAGETYPE_PNG:
|
2019-12-23 22:06:59 +00:00
|
|
|
$imgt = "imagepng";
|
|
|
|
$imgcreatefrom = "imagecreatefrompng";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMAGETYPE_WEBP:
|
|
|
|
$imgt = "imagewebp";
|
|
|
|
$imgcreatefrom = "imagecreatefromwebp";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMAGETYPE_WBMP:
|
|
|
|
$imgt = "imagewbmp";
|
|
|
|
$imgcreatefrom = "imagecreatefromwbmp";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMAGETYPE_BMP:
|
|
|
|
$imgt = "imagebmp";
|
|
|
|
$imgcreatefrom = "imagecreatefrombmp";
|
2016-12-28 14:21:52 +00:00
|
|
|
break;
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
$old_image = $imgcreatefrom($source_path);
|
2022-01-06 16:23:43 +00:00
|
|
|
if ($old_image === false) return false;
|
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
$new_image = imagecreatetruecolor($new_w, $new_h);
|
|
|
|
imagecopyresampled($new_image, $old_image, 0, 0, 0, 0, $new_w, $new_h, $source_w, $source_h);
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2019-11-08 21:01:58 +00:00
|
|
|
$new_image = self::fix_orientation($source_path, $new_image);
|
2019-11-08 21:15:13 +00:00
|
|
|
$old_image = self::fix_orientation($source_path, $old_image);
|
|
|
|
|
2022-01-06 16:23:43 +00:00
|
|
|
return $imgt($new_image, $thumb_path)
|
|
|
|
&& $imgt($old_image, $source_path);
|
2016-12-28 14:21:52 +00:00
|
|
|
}
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2019-12-18 23:15:08 +00:00
|
|
|
public static function upload(){
|
|
|
|
if(!$_FILES){
|
2019-12-18 22:56:05 +00:00
|
|
|
throw new Exception("No file.");
|
2016-12-28 14:21:52 +00:00
|
|
|
}
|
2019-12-18 23:15:08 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
// Create MD5
|
2019-12-18 23:15:08 +00:00
|
|
|
$md5 = md5_file($_FILES['file']['tmp_name']);
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
// Find duplicate
|
|
|
|
if($d = DB::get_instance()->query("SELECT `path`, `thumb` FROM `images` WHERE `md5` = ? AND `status` = 1 LIMIT 1", $md5)->first()){
|
|
|
|
return $d;
|
|
|
|
}
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2019-12-26 17:05:34 +00:00
|
|
|
// Ensure, that directories exists
|
|
|
|
$_images_path = Config::get('images_path');
|
|
|
|
$_thumbnails_path = Config::get('thumbnails_path');
|
2020-06-25 15:57:37 +00:00
|
|
|
if(
|
|
|
|
(!is_dir($_images_path) && !mkdir($_images_path, 0755, true)) ||
|
|
|
|
(!is_dir($_thumbnails_path) && !mkdir($_thumbnails_path, 0755, true))
|
|
|
|
){
|
2019-12-26 17:05:34 +00:00
|
|
|
throw new Exception("Images or thumbnails directory could not be created.");
|
|
|
|
}
|
|
|
|
|
2019-12-18 23:15:08 +00:00
|
|
|
// Get metadata
|
|
|
|
$name = $_FILES['file']['name'];
|
|
|
|
$ext = pathinfo($name, PATHINFO_EXTENSION);
|
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
// Save to DB
|
2020-06-11 14:52:13 +00:00
|
|
|
$id = DB::get_instance()->insert('images', [
|
|
|
|
'name' => $name,
|
|
|
|
'type' => $ext,
|
|
|
|
'md5' => $md5,
|
|
|
|
'datetime' => 'NOW()',
|
|
|
|
'status' => 0,
|
|
|
|
])->last_id();
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
// Create path name
|
|
|
|
$name = dechex($id).self::random_str(3).".".$ext;
|
2019-12-26 17:05:34 +00:00
|
|
|
$path = $_images_path.$name;
|
|
|
|
$thumb = $_thumbnails_path.$name;
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
// Save path
|
2019-12-18 23:15:08 +00:00
|
|
|
if(!move_uploaded_file($_FILES['file']['tmp_name'], $path)){
|
2020-06-25 15:56:35 +00:00
|
|
|
throw new Exception(self::PHP_FILE_UPLOAD_ERRORS[$_FILES['file']['error']]);
|
2016-12-28 14:21:52 +00:00
|
|
|
}
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
// Create thumb
|
2019-12-18 23:15:08 +00:00
|
|
|
if(!self::thumb($path, $thumb)){
|
|
|
|
unlink($path);
|
|
|
|
unlink($thumb);
|
2020-06-25 15:56:35 +00:00
|
|
|
throw new Exception("File is not valid image.");
|
2019-12-18 23:15:08 +00:00
|
|
|
}
|
2019-12-20 17:38:48 +00:00
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
// Save to DB
|
2020-06-11 14:52:13 +00:00
|
|
|
DB::get_instance()->update('images', [
|
|
|
|
'path' => $path,
|
|
|
|
'thumb' => $thumb,
|
|
|
|
'status' => 1,
|
|
|
|
], "WHERE `id` = ?", $id);
|
|
|
|
|
2016-12-28 14:21:52 +00:00
|
|
|
return [
|
|
|
|
"path" => $path,
|
|
|
|
"thumb" => $thumb
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|