Files
2026-08-09 16:56:13 +03:00

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);
}