'error', 'message' => 'Unauthorized access']); exit; } $user_role = getUserRole(); if (!in_array($user_role, ['admin', 'superadmin'])) { 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 = trim($_POST['start_date'] ?? ''); $end_date = trim($_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); // Debug: Log received values // error_log("START_DATE: " . var_export($start_date, true), 3, $rootPath . "/logs/trip_debug.log"); // error_log("END_DATE: " . var_export($end_date, true), 3, $rootPath . "/logs/trip_debug.log"); // Validation if (empty($trip_name) || empty($location) || empty($start_date) || empty($end_date)) { throw new Exception('Required fields are missing'); } // Validate and format dates (expecting YYYY-MM-DD format from HTML5 date input) if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $start_date)) { throw new Exception('Start date format invalid: "' . $start_date . '" must be in YYYY-MM-DD format'); } if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $end_date)) { throw new Exception('End date format invalid: "' . $end_date . '" must be in YYYY-MM-DD format'); } // Validate dates are actual dates $start_timestamp = strtotime($start_date); $end_timestamp = strtotime($end_date); if ($start_timestamp === false) { throw new Exception('Invalid start date'); } if ($end_timestamp === false) { throw new Exception('Invalid end date'); } if ($vehicle_capacity <= 0) { throw new Exception('Vehicle capacity must be greater than 0'); } if ($start_timestamp >= $end_timestamp) { 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( "sssissssddddd", $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( "sssissssdddddi", $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()]); } ?>