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 (!file_exists($albumDir)) { mkdir($albumDir, 0777, true); } // Handle cover image upload $coverImagePath = null; if (isset($_FILES['cover_image']) && $_FILES['cover_image']['error'] === UPLOAD_ERR_OK) { $maxSize = 5 * 1024 * 1024; // 5MB $fileName = $_FILES['cover_image']['name']; $fileTmpName = $_FILES['cover_image']['tmp_name']; $fileSize = $_FILES['cover_image']['size']; // Validate file extension $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; if (!in_array($ext, $allowedExtensions)) { throw new Exception('Invalid cover image file type. Allowed: jpg, jpeg, png, gif, webp'); } 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_OK) { $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]; // Validate file extension $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; if (!in_array($ext, $allowedExtensions)) { throw new Exception('Invalid file type: ' . $fileName . '. Allowed: jpg, jpeg, png, gif, webp'); } 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; } ?>