requireAuth(); // Set headers for JSON response header('Content-Type: application/json'); // Create uploads directory if it doesn't exist $uploadsDir = '../uploads/images'; if (!file_exists($uploadsDir)) { mkdir($uploadsDir, 0755, true); } // Handle file upload if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['images'])) { $uploadedFiles = []; $errors = []; // Handle multiple files $files = $_FILES['images']; $fileCount = count($files['name']); for ($i = 0; $i < $fileCount; $i++) { if ($files['error'][$i] === UPLOAD_ERR_OK) { $file = [ 'name' => $files['name'][$i], 'type' => $files['type'][$i], 'tmp_name' => $files['tmp_name'][$i], 'error' => $files['error'][$i], 'size' => $files['size'][$i] ]; // Validate file $validation = validateImageFile($file); if ($validation['valid']) { // Generate unique filename $extension = pathinfo($file['name'], PATHINFO_EXTENSION); $filename = uniqid() . '.' . $extension; $filepath = $uploadsDir . '/' . $filename; // Move file to uploads directory if (move_uploaded_file($file['tmp_name'], $filepath)) { // Save to database $imageId = saveImageToDatabase($filename, $file['name'], $file['size']); if ($imageId) { $uploadedFiles[] = [ 'id' => $imageId, 'filename' => $filename, 'original_name' => $file['name'], 'size' => $file['size'], 'url' => '/uploads/images/' . $filename, 'thumbnail_url' => '/uploads/images/' . $filename ]; } else { $errors[] = 'Failed to save ' . $file['name'] . ' to database'; unlink($filepath); // Remove uploaded file } } else { $errors[] = 'Failed to upload ' . $file['name']; } } else { $errors[] = $validation['error']; } } else { $errors[] = 'Error uploading file: ' . getUploadErrorMessage($files['error'][$i]); } } echo json_encode([ 'success' => empty($errors), 'files' => $uploadedFiles, 'errors' => $errors ]); exit; } // Handle GET request to fetch existing images if ($_SERVER['REQUEST_METHOD'] === 'GET') { $images = getExistingImages(); echo json_encode([ 'success' => true, 'images' => $images ]); exit; } // Handle DELETE request to remove image if ($_SERVER['REQUEST_METHOD'] === 'DELETE' && isset($_GET['id'])) { $imageId = (int)$_GET['id']; $success = deleteImage($imageId); echo json_encode([ 'success' => $success ]); exit; } echo json_encode(['success' => false, 'error' => 'Invalid request']); /** * Validate uploaded image file */ function validateImageFile($file) { // Check file size (5MB max) $maxSize = 5 * 1024 * 1024; // 5MB if ($file['size'] > $maxSize) { return ['valid' => false, 'error' => 'File too large. Maximum size is 5MB']; } // Check file type $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; if (!in_array($file['type'], $allowedTypes)) { return ['valid' => false, 'error' => 'Invalid file type. Only JPG, PNG, GIF, and WebP are allowed']; } // Check file extension $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); if (!in_array($extension, $allowedExtensions)) { return ['valid' => false, 'error' => 'Invalid file extension']; } return ['valid' => true]; } /** * Save image information to database */ function saveImageToDatabase($filename, $originalName, $size) { $db = Database::getInstance(); try { $db->insert('images', [ 'filename' => $filename, 'original_name' => $originalName, 'file_size' => $size, 'uploaded_at' => date('Y-m-d H:i:s'), 'uploaded_by' => $_SESSION['user_id'] ?? 1 ]); return $db->lastInsertId(); } catch (Exception $e) { error_log('Failed to save image to database: ' . $e->getMessage()); return false; } } /** * Get existing images from database */ function getExistingImages() { $db = Database::getInstance(); try { $images = $db->fetchAll("SELECT * FROM images ORDER BY uploaded_at DESC"); $result = []; foreach ($images as $image) { $result[] = [ 'id' => $image['id'], 'filename' => $image['filename'], 'original_name' => $image['original_name'], 'size' => $image['file_size'], 'url' => '/uploads/images/' . $image['filename'], 'thumbnail_url' => '/uploads/images/' . $image['filename'], 'uploaded_at' => $image['uploaded_at'] ]; } return $result; } catch (Exception $e) { error_log('Failed to fetch images: ' . $e->getMessage()); return []; } } /** * Delete image from database and filesystem */ function deleteImage($imageId) { $db = Database::getInstance(); try { // Get image info $image = $db->fetch("SELECT * FROM images WHERE id = ?", [$imageId]); if (!$image) { return false; } // Delete from database $db->delete('images', 'id = ?', [$imageId]); // Delete file from filesystem $filepath = '../uploads/images/' . $image['filename']; if (file_exists($filepath)) { unlink($filepath); } return true; } catch (Exception $e) { error_log('Failed to delete image: ' . $e->getMessage()); return false; } } /** * Get upload error message */ function getUploadErrorMessage($errorCode) { switch ($errorCode) { case UPLOAD_ERR_INI_SIZE: return 'The uploaded file exceeds the upload_max_filesize directive in php.ini'; case UPLOAD_ERR_FORM_SIZE: return 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'; case UPLOAD_ERR_PARTIAL: return 'The uploaded file was only partially uploaded'; case UPLOAD_ERR_NO_FILE: return 'No file was uploaded'; case UPLOAD_ERR_NO_TMP_DIR: return 'Missing a temporary folder'; case UPLOAD_ERR_CANT_WRITE: return 'Failed to write file to disk'; case UPLOAD_ERR_EXTENSION: return 'A PHP extension stopped the file upload'; default: return 'Unknown upload error'; } } ?>