- Added dedicated cover image upload field in create_album.php form - Display current cover image preview when editing - Drag-and-drop support for cover image with real-time preview - Shows filename and file size after selection - Updated save_album.php to handle cover image upload - Updated update_album.php to handle cover image replacement - Deletes old cover image when updating - Cover image optional - first photo in album used as fallback - Recommended cover dimensions: 500x500px or larger (square) - File validation: max 5MB, supports JPG, PNG, GIF, WEBP - All cover image changes included in transaction with rollback on error
184 lines
6.2 KiB
PHP
184 lines
6.2 KiB
PHP
<?php
|
|
$rootPath = dirname(dirname(__DIR__));
|
|
require_once($rootPath . '/src/config/env.php');
|
|
require_once($rootPath . '/src/config/session.php');
|
|
require_once($rootPath . '/src/config/connection.php');
|
|
require_once($rootPath . '/src/config/functions.php');
|
|
|
|
if (!isset($_SESSION['user_id']) || $_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(403);
|
|
exit('Forbidden');
|
|
}
|
|
|
|
// Validate CSRF token
|
|
if (!isset($_POST['csrf_token']) || !validateCSRFToken($_POST['csrf_token'])) {
|
|
http_response_code(400);
|
|
exit('Invalid request');
|
|
}
|
|
|
|
$title = trim($_POST['title'] ?? '');
|
|
$description = trim($_POST['description'] ?? '');
|
|
$user_id = $_SESSION['user_id'];
|
|
|
|
// Validate inputs
|
|
if (empty($title) || !validateName($title)) {
|
|
$conn->close();
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Album title is required and must be valid']);
|
|
exit;
|
|
}
|
|
|
|
if (!empty($description) && strlen($description) > 500) {
|
|
$conn->close();
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Description must be 500 characters or less']);
|
|
exit;
|
|
}
|
|
|
|
// Create album directory
|
|
$album_id = null;
|
|
$cover_image = null;
|
|
|
|
try {
|
|
// Start transaction
|
|
$conn->begin_transaction();
|
|
|
|
// Insert album record
|
|
$stmt = $conn->prepare("INSERT INTO photo_albums (user_id, title, description, created_at, updated_at) VALUES (?, ?, ?, NOW(), NOW())");
|
|
$stmt->bind_param("iss", $user_id, $title, $description);
|
|
$stmt->execute();
|
|
$album_id = $conn->insert_id;
|
|
$stmt->close();
|
|
|
|
// Create album directory
|
|
$albumDir = $rootPath . '/assets/uploads/gallery/' . $album_id;
|
|
if (!is_dir($albumDir)) {
|
|
if (!mkdir($albumDir, 0755, true)) {
|
|
throw new Exception('Failed to create album directory');
|
|
}
|
|
}
|
|
|
|
// Handle cover image upload
|
|
$coverImagePath = null;
|
|
if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] !== UPLOAD_ERR_NO_FILE) {
|
|
$allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
|
$maxSize = 5 * 1024 * 1024; // 5MB
|
|
|
|
$fileName = $_FILES['cover_image']['name'];
|
|
$fileTmpName = $_FILES['cover_image']['tmp_name'];
|
|
$fileSize = $_FILES['cover_image']['size'];
|
|
$fileMime = mime_content_type($fileTmpName);
|
|
|
|
// Validate file
|
|
if (!in_array($fileMime, $allowedMimes)) {
|
|
throw new Exception('Invalid cover image file type');
|
|
}
|
|
|
|
if ($fileSize > $maxSize) {
|
|
throw new Exception('Cover image file too large (max 5MB)');
|
|
}
|
|
|
|
// Generate unique filename
|
|
$ext = pathinfo($fileName, PATHINFO_EXTENSION);
|
|
$newFileName = 'cover_' . uniqid() . '.' . $ext;
|
|
$filePath = $albumDir . '/' . $newFileName;
|
|
$coverImagePath = '/assets/uploads/gallery/' . $album_id . '/' . $newFileName;
|
|
|
|
if (!move_uploaded_file($fileTmpName, $filePath)) {
|
|
throw new Exception('Failed to upload cover image');
|
|
}
|
|
|
|
// Update cover image in album record
|
|
$updateCover = $conn->prepare("UPDATE photo_albums SET cover_image = ? WHERE album_id = ?");
|
|
$updateCover->bind_param("si", $coverImagePath, $album_id);
|
|
$updateCover->execute();
|
|
$updateCover->close();
|
|
}
|
|
|
|
// Handle photo uploads
|
|
if (isset($_FILES['photos']) && $_FILES['photos']['error'][0] !== UPLOAD_ERR_NO_FILE) {
|
|
$allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
|
$maxSize = 5 * 1024 * 1024; // 5MB
|
|
|
|
$displayOrder = 1;
|
|
$firstPhoto = true;
|
|
|
|
for ($i = 0; $i < count($_FILES['photos']['name']); $i++) {
|
|
if ($_FILES['photos']['error'][$i] !== UPLOAD_ERR_OK) {
|
|
continue;
|
|
}
|
|
|
|
$fileName = $_FILES['photos']['name'][$i];
|
|
$fileTmpName = $_FILES['photos']['tmp_name'][$i];
|
|
$fileSize = $_FILES['photos']['size'][$i];
|
|
$fileMime = mime_content_type($fileTmpName);
|
|
|
|
// Validate file
|
|
if (!in_array($fileMime, $allowedMimes)) {
|
|
throw new Exception('Invalid file type: ' . $fileName);
|
|
}
|
|
|
|
if ($fileSize > $maxSize) {
|
|
throw new Exception('File too large: ' . $fileName);
|
|
}
|
|
|
|
// Generate unique filename
|
|
$ext = pathinfo($fileName, PATHINFO_EXTENSION);
|
|
$newFileName = uniqid('photo_') . '.' . $ext;
|
|
$filePath = $albumDir . '/' . $newFileName;
|
|
$relativePath = '/assets/uploads/gallery/' . $album_id . '/' . $newFileName;
|
|
|
|
if (!move_uploaded_file($fileTmpName, $filePath)) {
|
|
throw new Exception('Failed to upload: ' . $fileName);
|
|
}
|
|
|
|
// Set first photo as cover if no cover image was uploaded
|
|
if ($firstPhoto && !$coverImagePath) {
|
|
$updateCover = $conn->prepare("UPDATE photo_albums SET cover_image = ? WHERE album_id = ?");
|
|
$updateCover->bind_param("si", $relativePath, $album_id);
|
|
$updateCover->execute();
|
|
$updateCover->close();
|
|
$firstPhoto = false;
|
|
}
|
|
|
|
// Insert photo record
|
|
$caption = $fileName; // Default caption is filename
|
|
$photoStmt = $conn->prepare("INSERT INTO photos (album_id, file_path, caption, display_order, created_at) VALUES (?, ?, ?, ?, NOW())");
|
|
$photoStmt->bind_param("issi", $album_id, $relativePath, $caption, $displayOrder);
|
|
$photoStmt->execute();
|
|
$photoStmt->close();
|
|
|
|
$displayOrder++;
|
|
}
|
|
}
|
|
|
|
// Commit transaction
|
|
$conn->commit();
|
|
$conn->close();
|
|
|
|
// Redirect to view album
|
|
header('Location: view_album?id=' . $album_id);
|
|
exit;
|
|
|
|
} catch (Exception $e) {
|
|
// Rollback on error
|
|
$conn->rollback();
|
|
$conn->close();
|
|
|
|
// Clean up partially uploaded files
|
|
if ($album_id) {
|
|
$albumDir = $rootPath . '/assets/uploads/gallery/' . $album_id;
|
|
if (is_dir($albumDir)) {
|
|
array_map('unlink', glob($albumDir . '/*'));
|
|
rmdir($albumDir);
|
|
}
|
|
// Delete album record (will cascade delete photos)
|
|
$conn->query("DELETE FROM photo_albums WHERE album_id = " . intval($album_id));
|
|
}
|
|
|
|
http_response_code(400);
|
|
echo json_encode(['error' => $e->getMessage()]);
|
|
exit;
|
|
}
|
|
?>
|