116 lines
3.5 KiB
PHP
116 lines
3.5 KiB
PHP
<?php
|
|
|
|
class ImageHandler {
|
|
private $upload_path;
|
|
private $allowed_types;
|
|
private $max_size;
|
|
|
|
public function __construct() {
|
|
$this->upload_path = UPLOAD_PATH;
|
|
$this->allowed_types = ALLOWED_IMAGE_TYPES;
|
|
$this->max_size = MAX_IMAGE_SIZE;
|
|
|
|
if (!file_exists($this->upload_path)) {
|
|
mkdir($this->upload_path, 0755, true);
|
|
}
|
|
}
|
|
|
|
public function upload($file, $optimize = true) {
|
|
if (!isset($file['tmp_name']) || !is_uploaded_file($file['tmp_name'])) {
|
|
throw new Exception('No file uploaded');
|
|
}
|
|
|
|
// Validate file
|
|
$this->validateFile($file);
|
|
|
|
// Generate unique filename
|
|
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
|
|
$filename = uniqid() . '_' . time() . '.' . $extension;
|
|
$filepath = $this->upload_path . '/' . $filename;
|
|
|
|
// Move and optimize
|
|
if (move_uploaded_file($file['tmp_name'], $filepath)) {
|
|
if ($optimize) {
|
|
$this->optimizeImage($filepath);
|
|
}
|
|
return $filename;
|
|
}
|
|
|
|
throw new Exception('Failed to move uploaded file');
|
|
}
|
|
|
|
private function validateFile($file) {
|
|
// Check file size
|
|
if ($file['size'] > $this->max_size) {
|
|
throw new Exception('File size exceeds limit');
|
|
}
|
|
|
|
// Check file type
|
|
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
|
$mime_type = finfo_file($finfo, $file['tmp_name']);
|
|
finfo_close($finfo);
|
|
|
|
if (!in_array($mime_type, $this->allowed_types)) {
|
|
throw new Exception('Invalid file type');
|
|
}
|
|
}
|
|
|
|
private function optimizeImage($filepath) {
|
|
$image = null;
|
|
$mime = mime_content_type($filepath);
|
|
|
|
switch ($mime) {
|
|
case 'image/jpeg':
|
|
$image = imagecreatefromjpeg($filepath);
|
|
imagejpeg($image, $filepath, 85); // 85% quality
|
|
break;
|
|
case 'image/png':
|
|
$image = imagecreatefrompng($filepath);
|
|
imagepng($image, $filepath, 8); // Compression level 8
|
|
break;
|
|
case 'image/webp':
|
|
$image = imagecreatefromwebp($filepath);
|
|
imagewebp($image, $filepath, 85);
|
|
break;
|
|
}
|
|
|
|
if ($image) {
|
|
imagedestroy($image);
|
|
}
|
|
}
|
|
|
|
public function createThumbnail($filename, $width = 200, $height = 200) {
|
|
$source_path = $this->upload_path . '/' . $filename;
|
|
$thumb_path = $this->upload_path . '/thumbnails/' . $filename;
|
|
|
|
if (!file_exists(dirname($thumb_path))) {
|
|
mkdir(dirname($thumb_path), 0755, true);
|
|
}
|
|
|
|
$source_image = imagecreatefromstring(file_get_contents($source_path));
|
|
$source_width = imagesx($source_image);
|
|
$source_height = imagesy($source_image);
|
|
|
|
$thumb = imagecreatetruecolor($width, $height);
|
|
imagecopyresampled($thumb, $source_image, 0, 0, 0, 0, $width, $height, $source_width, $source_height);
|
|
|
|
$mime = mime_content_type($source_path);
|
|
switch ($mime) {
|
|
case 'image/jpeg':
|
|
imagejpeg($thumb, $thumb_path, 85);
|
|
break;
|
|
case 'image/png':
|
|
imagepng($thumb, $thumb_path, 8);
|
|
break;
|
|
case 'image/webp':
|
|
imagewebp($thumb, $thumb_path, 85);
|
|
break;
|
|
}
|
|
|
|
imagedestroy($source_image);
|
|
imagedestroy($thumb);
|
|
|
|
return 'thumbnails/' . $filename;
|
|
}
|
|
}
|