Feature: Add trip publisher system - create, edit, delete, and publish trips

This commit is contained in:
twotalesanimation
2025-12-04 16:56:31 +02:00
parent ec563e0376
commit 674af23994
9 changed files with 782 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
<?php
ob_start();
header('Content-Type: application/json');
$rootPath = dirname(dirname(__DIR__));
require_once($rootPath . '/src/config/functions.php');
require_once($rootPath . '/src/config/connection.php');
// Check admin status
session_start();
if (empty($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
ob_end_clean();
echo json_encode(['status' => 'error', 'message' => 'Unauthorized access']);
exit;
}
try {
$trip_id = intval($_POST['trip_id'] ?? 0);
if ($trip_id <= 0) {
throw new Exception('Invalid trip ID');
}
// Delete trip images from filesystem
$upload_dir = $rootPath . '/assets/images/trips/';
if (is_dir($upload_dir)) {
$files = glob($upload_dir . $trip_id . '_*.{jpg,jpeg,png,gif,webp}', GLOB_BRACE);
foreach ($files as $file) {
if (is_file($file)) {
unlink($file);
}
}
}
// Delete trip from database
$stmt = $conn->prepare("DELETE FROM trips WHERE trip_id = ?");
$stmt->bind_param("i", $trip_id);
if (!$stmt->execute()) {
throw new Exception('Failed to delete trip: ' . $stmt->error);
}
$stmt->close();
ob_end_clean();
echo json_encode(['status' => 'success', 'message' => 'Trip deleted successfully']);
} catch (Exception $e) {
ob_end_clean();
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
?>

View File

@@ -0,0 +1,156 @@
<?php
ob_start();
header('Content-Type: application/json');
$rootPath = dirname(dirname(__DIR__));
require_once($rootPath . '/src/config/functions.php');
require_once($rootPath . '/src/config/connection.php');
// Check admin status
session_start();
if (empty($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
ob_end_clean();
echo json_encode(['status' => 'error', 'message' => 'Unauthorized access']);
exit;
}
// Validate CSRF token
if (empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token'] ?? '') {
ob_end_clean();
echo json_encode(['status' => 'error', 'message' => 'Invalid CSRF token']);
exit;
}
try {
$trip_id = $_POST['trip_id'] ?? null;
$trip_name = trim($_POST['trip_name'] ?? '');
$location = trim($_POST['location'] ?? '');
$trip_code = trim($_POST['trip_code'] ?? '');
$vehicle_capacity = intval($_POST['vehicle_capacity'] ?? 0);
$start_date = $_POST['start_date'] ?? '';
$end_date = $_POST['end_date'] ?? '';
$short_description = trim($_POST['short_description'] ?? '');
$long_description = trim($_POST['long_description'] ?? '');
$cost_members = floatval($_POST['cost_members'] ?? 0);
$cost_nonmembers = floatval($_POST['cost_nonmembers'] ?? 0);
$cost_pensioner_member = floatval($_POST['cost_pensioner_member'] ?? 0);
$cost_pensioner = floatval($_POST['cost_pensioner'] ?? 0);
$booking_fee = floatval($_POST['booking_fee'] ?? 0);
// Validation
if (empty($trip_name) || empty($location) || empty($start_date) || empty($end_date)) {
throw new Exception('Required fields are missing');
}
if ($vehicle_capacity <= 0) {
throw new Exception('Vehicle capacity must be greater than 0');
}
if (strtotime($start_date) >= strtotime($end_date)) {
throw new Exception('Start date must be before end date');
}
// If creating new trip, insert first to get trip_id
if (!$trip_id) {
$stmt = $conn->prepare("
INSERT INTO trips (
trip_name, location, trip_code, vehicle_capacity, start_date, end_date,
short_description, long_description, cost_members, cost_nonmembers,
cost_pensioner_member, cost_pensioner, booking_fee, published, places_booked
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 0)
");
$stmt->bind_param(
"sssiissssdddd",
$trip_name, $location, $trip_code, $vehicle_capacity,
$start_date, $end_date, $short_description, $long_description,
$cost_members, $cost_nonmembers, $cost_pensioner_member,
$cost_pensioner, $booking_fee
);
if (!$stmt->execute()) {
throw new Exception('Failed to create trip: ' . $stmt->error);
}
$trip_id = $conn->insert_id;
$stmt->close();
} else {
// Update existing trip
$stmt = $conn->prepare("
UPDATE trips SET
trip_name = ?, location = ?, trip_code = ?, vehicle_capacity = ?,
start_date = ?, end_date = ?, short_description = ?, long_description = ?,
cost_members = ?, cost_nonmembers = ?, cost_pensioner_member = ?,
cost_pensioner = ?, booking_fee = ?
WHERE trip_id = ?
");
$stmt->bind_param(
"sssiisssdddddi",
$trip_name, $location, $trip_code, $vehicle_capacity,
$start_date, $end_date, $short_description, $long_description,
$cost_members, $cost_nonmembers, $cost_pensioner_member,
$cost_pensioner, $booking_fee, $trip_id
);
if (!$stmt->execute()) {
throw new Exception('Failed to update trip: ' . $stmt->error);
}
$stmt->close();
}
// Handle image uploads
if (!empty($_FILES['trip_images']['name'][0])) {
$upload_dir = $rootPath . '/assets/images/trips/';
// Create directory if it doesn't exist
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
$allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
$image_count = 1;
foreach ($_FILES['trip_images']['name'] as $key => $filename) {
if (empty($filename)) continue;
$file_ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
// Validate file extension
if (!in_array($file_ext, $allowed_extensions)) {
throw new Exception('Invalid file type: ' . $filename . '. Only images allowed.');
}
// Validate file size (5MB max per file)
if ($_FILES['trip_images']['size'][$key] > 5 * 1024 * 1024) {
throw new Exception('File too large: ' . $filename . '. Max 5MB per file.');
}
// Generate filename: {trip_id}_0{number}.{ext}
$new_filename = $trip_id . '_0' . $image_count . '.' . $file_ext;
$file_path = $upload_dir . $new_filename;
// Move uploaded file
if (!move_uploaded_file($_FILES['trip_images']['tmp_name'][$key], $file_path)) {
throw new Exception('Failed to upload image: ' . $filename);
}
// Optimize image (resize if too large)
optimizeImage($file_path, 1920, 1080);
$image_count++;
}
}
ob_end_clean();
echo json_encode([
'status' => 'success',
'message' => $trip_id ? 'Trip updated successfully' : 'Trip created successfully',
'trip_id' => $trip_id
]);
} catch (Exception $e) {
ob_end_clean();
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
?>

View File

@@ -0,0 +1,59 @@
<?php
ob_start();
header('Content-Type: application/json');
$rootPath = dirname(dirname(__DIR__));
require_once($rootPath . '/src/config/functions.php');
require_once($rootPath . '/src/config/connection.php');
// Check admin status
session_start();
if (empty($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
ob_end_clean();
echo json_encode(['status' => 'error', 'message' => 'Unauthorized access']);
exit;
}
try {
$trip_id = intval($_POST['trip_id'] ?? 0);
if ($trip_id <= 0) {
throw new Exception('Invalid trip ID');
}
// Fetch current published status
$stmt = $conn->prepare("SELECT published FROM trips WHERE trip_id = ?");
$stmt->bind_param("i", $trip_id);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 0) {
throw new Exception('Trip not found');
}
$row = $result->fetch_assoc();
$new_status = $row['published'] == 1 ? 0 : 1;
$stmt->close();
// Update published status
$stmt = $conn->prepare("UPDATE trips SET published = ? WHERE trip_id = ?");
$stmt->bind_param("ii", $new_status, $trip_id);
if (!$stmt->execute()) {
throw new Exception('Failed to update trip status: ' . $stmt->error);
}
$stmt->close();
ob_end_clean();
echo json_encode([
'status' => 'success',
'message' => $new_status == 1 ? 'Trip published successfully' : 'Trip unpublished successfully',
'published' => $new_status
]);
} catch (Exception $e) {
ob_end_clean();
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
?>