Update: 2026-08-07 01:06:09
This commit is contained in:
@@ -52,21 +52,21 @@ try {
|
||||
// بمسح بيانات التطبيق أو إعادة تثبيته. هذه هي البوابة الحقيقية: سائق
|
||||
// موقوف لا يستطيع أن يفوز برحلة مهما فعل بتطبيقه.
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// الفحص من Redis لا MySQL: هذا المسار يُستدعى على كل محاولة قبول من كل
|
||||
// سائق، والإيقاف حالة نادرة قصيرة العمر. مفتاح بـ TTL يجعل انتهاء
|
||||
// الإيقاف تلقائياً بلا كرون ولا استعلام تنظيف.
|
||||
// MySQL يبقى السجل الدائم للمراجعة الإدارية، ولا يُقرأ هنا.
|
||||
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;
|
||||
if (isset($redisLocation) && $redisLocation) {
|
||||
$blockedUntil = $redisLocation->get("driver:$driverId:blocked");
|
||||
if ($blockedUntil) {
|
||||
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());
|
||||
} catch (Throwable $eBlock) {
|
||||
error_log("[accept_ride] تعذّر فحص الإيقاف: " . $eBlock->getMessage());
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
@@ -111,44 +111,49 @@ try {
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
// STEP B1 — تثبيت مسافة الاقتراب لحظة القبول
|
||||
// هذه هي المسافة التي سيقطعها السائق نحو الراكب، وهي أساس تعويض عدم
|
||||
// الحضور لاحقاً. تُقاس الآن حصراً: عند الإلغاء يكون السائق واقفاً عند
|
||||
// نقطة الالتقاط فتصير المسافة صفراً، فلا يمكن استنتاجها بأثر رجعي.
|
||||
// مصدر الموقع هو Redis لا الطلب — حتى لا يتحكم العميل بالمبلغ.
|
||||
// STEP B1 — تثبيت مسافة الاقتراب لحظة القبول (في Redis لا MySQL)
|
||||
//
|
||||
// هذه المسافة أساس تعويض عدم الحضور لاحقاً، ويجب أن تُقاس الآن حصراً:
|
||||
// عند الإلغاء يكون السائق واقفاً عند نقطة الالتقاط فتصير صفراً.
|
||||
//
|
||||
// لكنها قيمة عابرة تُقرأ مرة واحدة عند نهاية الرحلة — فلا تستحق كتابتين
|
||||
// في MySQL على أسخن مسار في النظام. تُحفظ في نفس الهاش الذي يستخدمه
|
||||
// السوكِت لحالة الرحلة (ride:$id:state)، وتُثبَّت في MySQL كتابةً واحدة
|
||||
// مع تحديث الحالة النهائي عند الإلغاء.
|
||||
//
|
||||
// hSet لا يمسح حقول السوكِت الأخرى في نفس الهاش، وTTL الـ24 ساعة الذي
|
||||
// يضبطه السوكِت يغطي هذه الحقول تلقائياً.
|
||||
// ═══════════════════════════════════════════════════════════
|
||||
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 (isset($redisLocation) && $redisLocation) {
|
||||
$stmtPickup = $con->prepare("SELECT start_location FROM ride WHERE id = ?");
|
||||
$stmtPickup->execute([$rideId]);
|
||||
[$pickupLat, $pickupLng] = array_pad(
|
||||
array_map('trim', explode(',', (string) $stmtPickup->fetchColumn(), 2)), 2, null
|
||||
);
|
||||
|
||||
if (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) {
|
||||
$redisLocation->hSet("ride:$rideId:state", 'pickup_approach_km', $approachKm);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
if ($approachKm <= 0) {
|
||||
error_log("[accept_ride] تعذّر قياس مسافة الاقتراب RideID=$rideId"
|
||||
. " — التعويض سيحتسب زمن الانتظار وحده");
|
||||
}
|
||||
} catch (PDOException $eApproach) {
|
||||
} catch (Throwable $eApproach) {
|
||||
// قياس التعويض لا يُسقط قبول الرحلة أبداً.
|
||||
error_log("[accept_ride] pickupApproachKm WARNING: " . $eApproach->getMessage());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user