57 lines
2.1 KiB
PHP
57 lines
2.1 KiB
PHP
<?php
|
|
// ride/scheduled/cancel.php — إلغاء حجز مسبق
|
|
//
|
|
// بلا رسم: لا سائق قُبِل ولا أحد تحرّك. رسم الإلغاء يبدأ من لحظة قبول
|
|
// السائق، والحجز لم يصل تلك المرحلة بعد.
|
|
//
|
|
// أما إن كان الكرون قد حوّله لرحلة فعلية (status=dispatched) فالإلغاء
|
|
// يتبع مسار الرحلات العادي — cancel_ride_by_passenger.php — بقواعده
|
|
// وإعفاءاته ورسومه.
|
|
|
|
require_once __DIR__ . '/../../connect.php';
|
|
|
|
$passengerId = $user_id ?? '';
|
|
$bookingId = filterRequest('id', 'int');
|
|
$reason = filterRequest('reason');
|
|
|
|
if (empty($passengerId)) jsonError('Unauthorized', 401);
|
|
if (!$bookingId) jsonError('Missing id');
|
|
|
|
try {
|
|
$stmt = $con->prepare("SELECT * FROM scheduled_rides WHERE id = ? LIMIT 1");
|
|
$stmt->execute([$bookingId]);
|
|
$booking = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$booking) {
|
|
jsonError('Booking not found', 404);
|
|
}
|
|
|
|
// الملكية: الحجز يحمل نقاط انطلاق ووجهة الراكب — لا يُلغيه غيره.
|
|
if ((string) $booking['passenger_id'] !== (string) $passengerId) {
|
|
error_log("[scheduled/cancel] SECURITY: محاولة إلغاء حجز غير مملوك"
|
|
. " (booking=$bookingId caller=$passengerId)");
|
|
jsonError('Forbidden', 403);
|
|
}
|
|
|
|
if ($booking['status'] === 'dispatched') {
|
|
jsonError('Ride already created — cancel it from the active ride screen', 409);
|
|
}
|
|
|
|
if ($booking['status'] !== 'scheduled') {
|
|
jsonSuccess(['id' => $bookingId, 'status' => $booking['status']],
|
|
'Booking is not active');
|
|
}
|
|
|
|
$con->prepare("
|
|
UPDATE scheduled_rides
|
|
SET status = 'cancelled', cancelled_reason = ?
|
|
WHERE id = ? AND status = 'scheduled'
|
|
")->execute([$reason ? mb_substr($reason, 0, 255) : null, $bookingId]);
|
|
|
|
jsonSuccess(['id' => $bookingId, 'status' => 'cancelled'], 'Booking cancelled');
|
|
|
|
} catch (PDOException $e) {
|
|
error_log('[scheduled/cancel] ' . $e->getMessage());
|
|
jsonError('DB Error', 500);
|
|
}
|