Update: 2026-08-07 00:57:03

This commit is contained in:
Hamza-Ayed
2026-08-07 00:57:03 +03:00
parent 6e451e8b71
commit a1104a4695
10 changed files with 338 additions and 188 deletions
+65
View File
@@ -46,6 +46,29 @@ if (!in_array($status, $allowedStatuses, true)) {
error_log("[accept_ride] DriverID=$driverId attempting RideID=$rideId");
try {
// ═══════════════════════════════════════════════════════════
// STEP A0 — تطبيق الإيقاف على الخادم
// ‏كان الإيقاف بعد ٣ إلغاءات يُكتب في تخزين تطبيق السائق وحده، فيُفكّ
// ‏بمسح بيانات التطبيق أو إعادة تثبيته. هذه هي البوابة الحقيقية: سائق
// ‏موقوف لا يستطيع أن يفوز برحلة مهما فعل بتطبيقه.
// ═══════════════════════════════════════════════════════════
try {
$stmtBlock = $con->prepare("SELECT blockedUntil FROM driver WHERE id = ?");
$stmtBlock->execute([$driverId]);
$blockedUntil = $stmtBlock->fetchColumn();
if (!empty($blockedUntil) && strtotime($blockedUntil) > time()) {
error_log("[accept_ride] DriverID=$driverId موقوف حتى $blockedUntil — رُفض القبول");
printFailure("Your account is temporarily suspended until $blockedUntil");
exit;
}
} catch (PDOException $eBlock) {
// ‏العمود غير موجود بعد (قبل تشغيل ترحيل 2026_08_07) — لا نمنع القبول
// ‏بسبب فحصٍ لا يمكن إجراؤه، لكن نسجّله بوضوح.
error_log("[accept_ride] تعذّر فحص blockedUntil (شغّل"
. " migrations/2026_08_07_driver_cancel_compensation.sql): " . $eBlock->getMessage());
}
// ═══════════════════════════════════════════════════════════
// STEP A — القفل على ride DB (المرجع الأساسي)
// Optimistic lock: نغير فقط إذا status لا يزال 'waiting' أو 'wait'
@@ -87,6 +110,48 @@ try {
error_log("[accept_ride] primary DB sync WARNING: " . $eSync->getMessage());
}
// ═══════════════════════════════════════════════════════════
// STEP B1 — تثبيت مسافة الاقتراب لحظة القبول
// ‏هذه هي المسافة التي سيقطعها السائق نحو الراكب، وهي أساس تعويض عدم
// ‏الحضور لاحقاً. تُقاس الآن حصراً: عند الإلغاء يكون السائق واقفاً عند
// ‏نقطة الالتقاط فتصير المسافة صفراً، فلا يمكن استنتاجها بأثر رجعي.
// ‏مصدر الموقع هو Redis لا الطلب — حتى لا يتحكم العميل بالمبلغ.
// ═══════════════════════════════════════════════════════════
try {
$stmtPickup = $con->prepare("SELECT start_location FROM ride WHERE id = ?");
$stmtPickup->execute([$rideId]);
$pickupRaw = (string) $stmtPickup->fetchColumn();
[$pickupLat, $pickupLng] = array_pad(
array_map('trim', explode(',', $pickupRaw, 2)), 2, null
);
$approachKm = 0.0;
if (isset($redisLocation) && $redisLocation
&& is_numeric($pickupLat) && is_numeric($pickupLng)) {
$loc = $redisLocation->hGetAll("driver:public:$driverId");
if (!empty($loc['lat']) && !empty($loc['lng'])) {
$approachKm = round(getDistanceBetweenPoints(
(float) $loc['lat'], (float) $loc['lng'],
(float) $pickupLat, (float) $pickupLng
), 3);
}
}
if ($approachKm > 0) {
$sqlApproach = "UPDATE ride SET pickupApproachKm = ? WHERE id = ?";
$con->prepare($sqlApproach)->execute([$approachKm, $rideId]);
try {
$con_ride->prepare($sqlApproach)->execute([$approachKm, $rideId]);
} catch (PDOException $e) { /* primary يكفي لحساب التعويض */ }
} else {
error_log("[accept_ride] تعذّر قياس مسافة الاقتراب RideID=$rideId"
. " — التعويض سيحتسب زمن الانتظار وحده");
}
} catch (PDOException $eApproach) {
error_log("[accept_ride] pickupApproachKm WARNING: " . $eApproach->getMessage());
}
// ═══════════════════════════════════════════════════════════
// STEP C — driver_orders (INSERT أو UPDATE بسطر واحد آمن)
// ON DUPLICATE KEY يمنع race condition ثانية على هذا الجدول