(string)$rideId, 'start_lat' => $lat, 'start_lng' => $lng, 'price' => $payloadData[2], // السعر 'carType' => $payloadData[31], // نوع السيارة 'startName' => $payloadData[29], // اسم موقع البدء 'endName' => $payloadData[30], // اسم موقع الوصول 'distance' => $payloadData[11], // المسافة 'duration' => $payloadData[15], // الوقت 'passengerRate' => $payloadData[33], // تقييم الراكب // يمكنك إضافة المزيد هنا حسب الحاجة ]; $postData = [ 'action' => 'market_new_ride', // اسم الحدث في السوكيت 'payload' => $marketPayload ]; // إرسال الطلب (cURL) $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // وقت انتظار قصير جداً (200ms) لأننا لا نريد تأخير استجابة الراكب curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $INTERNAL_KEY"]); curl_exec($ch); curl_close($ch); } // ================================================================================= // 2. استقبال وتصفية البيانات من التطبيق // ================================================================================= $start_location = filterRequest("start_location"); $end_location = filterRequest("end_location"); $date_raw = filterRequest("date"); $time_raw = filterRequest("time"); $endtime_raw = filterRequest("endtime"); $price = filterRequest("price"); $passenger_id = filterRequest("passenger_id"); $driver_id = filterRequest("driver_id") ?: 0; $status = filterRequest("status"); $price_for_driver = filterRequest("price_for_driver"); $price_for_passenger = filterRequest("price_for_passenger"); $distance = filterRequest("distance"); $carType = filterRequest("carType"); // بيانات الراكب الإضافية $passenger_name = filterRequest("passenger_name"); $passenger_phone = filterRequest("passenger_phone"); $passenger_token = filterRequest("passenger_token"); $passenger_email = filterRequest("passenger_email"); $passenger_wallet = filterRequest("passenger_wallet"); $passenger_rating = filterRequest("passenger_rating"); // تفاصيل الرحلة والنصوص $start_name_loc = filterRequest("start_name"); $end_name_loc = filterRequest("end_name"); $duration_text = filterRequest("duration_text"); $distance_text = filterRequest("distance_text"); $is_wallet = filterRequest("is_wallet"); $has_steps = filterRequest("has_steps"); $step0 = filterRequest("step0"); $step1 = filterRequest("step1"); $step2 = filterRequest("step2"); $step3 = filterRequest("step3"); $step4 = filterRequest("step4"); // معالجة الإحداثيات (فصل النص إلى Lat/Lng) $startLat = ""; $startLng = ""; if (!empty($start_location)) { $parts = explode(',', $start_location); $startLat = trim($parts[0] ?? ""); $startLng = trim($parts[1] ?? ""); } $endLat = ""; $endLng = ""; if (!empty($end_location)) { $parts = explode(',', $end_location); $endLat = trim($parts[0] ?? ""); $endLng = trim($parts[1] ?? ""); } // تنسيق التواريخ $date_formatted = date("Y-m-d", strtotime($date_raw)); $time_formatted = date("H:i:s", strtotime($time_raw)); $endtime_formatted = $endtime_raw ? date("H:i:s", strtotime($endtime_raw)) : "00:00:00"; // مصفوفة البيانات للإدخال $data = [ ":start_location" => $start_location, ":end_location" => $end_location, ":date" => $date_formatted, ":time" => $time_formatted, ":endtime" => $endtime_formatted, ":price" => $price, ":passenger_id" => $passenger_id, ":driver_id" => $driver_id, ":status" => $status, ":carType" => $carType, ":price_for_driver" => $price_for_driver, ":price_for_passenger" => $price_for_passenger, ":distance" => $distance, ]; // جملة SQL للإدخال $sql = "INSERT INTO `ride` ( `start_location`, `end_location`, `date`, `time`, `endtime`, `price`, `passenger_id`, `driver_id`, `status`, `carType`, `price_for_driver`, `price_for_passenger`, `distance` ) VALUES ( :start_location, :end_location, :date, :time, :endtime, :price, :passenger_id, :driver_id, :status, :carType, :price_for_driver, :price_for_passenger, :distance )"; try { // 3. الإدخال في قاعدة بيانات الرحلات أولاً (Ride DB - المرجع الأساسي) $stmtRide = $con_ride->prepare($sql); $stmtRide->execute($data); $insertedId = $con_ride->lastInsertId(); // ID الرحلة الجديد if (!$insertedId) { jsonError("Failed to create ride"); } // 4. الإدخال في قاعدة البيانات الرئيسية ثانياً (Main DB) بنفس الـ ID try { $sqlMain = "INSERT INTO `ride` ( `id`, `start_location`, `end_location`, `date`, `time`, `endtime`, `price`, `passenger_id`, `driver_id`, `status`, `carType`, `price_for_driver`, `price_for_passenger`, `distance` ) VALUES ( :id, :start_location, :end_location, :date, :time, :endtime, :price, :passenger_id, :driver_id, :status, :carType, :price_for_driver, :price_for_passenger, :distance )"; $stmtMain = $con->prepare($sqlMain); $data[':id'] = $insertedId; $stmtMain->execute($data); } catch (Exception $eMain) { error_log("⚠️ Main DB Sync Warning: " . $eMain->getMessage()); } if ($insertedId) { error_log("📝 Ride #$insertedId added successfully."); // 5. تجهيز الـ Payload (قائمة البيانات للتطبيق) $kazan = (double)$price - (double)$price_for_driver; $payloadTemplate = []; // تعبئة البيانات بالترتيب الذي يتوقعه التطبيق (Indices 0-33) $payloadTemplate[0] = (string)$startLat; $payloadTemplate[1] = (string)$startLng; $payloadTemplate[2] = (string)number_format($price, 2, '.', ''); $payloadTemplate[3] = (string)$endLat; $payloadTemplate[4] = (string)$endLng; $payloadTemplate[5] = (string)$distance_text; $payloadTemplate[6] = ""; $payloadTemplate[7] = (string)$passenger_id; $payloadTemplate[8] = (string)$passenger_name; $payloadTemplate[9] = (string)$passenger_token; $payloadTemplate[10] = (string)$passenger_phone; $payloadTemplate[11] = (string)$distance; $payloadTemplate[12] = "1"; $payloadTemplate[13] = (string)$is_wallet; $payloadTemplate[14] = (string)$distance; $payloadTemplate[15] = (string)$duration_text; $payloadTemplate[16] = (string)$insertedId; $payloadTemplate[17] = ""; $payloadTemplate[18] = ""; $payloadTemplate[19] = (string)$duration_text; $payloadTemplate[20] = $has_steps ?: 'false'; $payloadTemplate[21] = (string)$step0; $payloadTemplate[22] = (string)$step1; $payloadTemplate[23] = (string)$step2; $payloadTemplate[24] = (string)$step3; $payloadTemplate[25] = (string)$step4; $payloadTemplate[26] = (string)number_format($price_for_driver, 2, '.', ''); $payloadTemplate[27] = (string)$passenger_wallet; $payloadTemplate[28] = (string)$passenger_email; $payloadTemplate[29] = (string)$start_name_loc; $payloadTemplate[30] = (string)$end_name_loc; $payloadTemplate[31] = (string)$carType; $payloadTemplate[32] = (string)number_format($kazan, 2, '.', ''); $payloadTemplate[33] = (string)$passenger_rating; ksort($payloadTemplate); $payloadTemplate = array_values($payloadTemplate); // 6. البحث عن السائقين للتوزيع المباشر (Direct Dispatch) $driversData = findBestDrivers($con, $startLat, $startLng, $carType); // متغير لنعرف هل وجدنا سائقين للتوجيه المباشر أم لا $foundDirectDrivers = false; if (!empty($driversData)) { // أ. إرسال إشعار مباشر للسائقين المختارين dispatchRideToDrivers($driversData, $insertedId, $payloadTemplate, $start_name_loc, $encryptionHelper); error_log("📨 Dispatched Ride #$insertedId to " . count($driversData) . " drivers."); $foundDirectDrivers = true; } else { error_log("⚠️ No specific drivers found for Direct Dispatch for Ride #$insertedId. Moved to Market only."); } // ب. 🔥 نشر الرحلة في السوق المفتوح (Marketplace) دائماً 🔥 // هذا هو طوق النجاة: حتى لو لم نجد سائقين أعلاه، نضعها في السوق broadcastRideToMarket($insertedId, $startLat, $startLng, $payloadTemplate); // ج. ✅ إرجاع نجاح للتطبيق دائماً (ليبقى الراكب في شاشة البحث) // يمكنك إرسال معلومة إضافية للتطبيق أن البحث "عام" وليس "مباشر" إذا أردت jsonSuccess($insertedId); // ملاحظة: قمنا بإزالة كود الإلغاء (UPDATE ride SET status = 'cancelled...') // لأننا نريد منح الفرصة للسائقين البعيدين قليلاً أو الذين فتحوا التطبيق للتو /* else { // 🛑 حالة عدم العثور على سائقين error_log("⚠️ No drivers found for Ride #$insertedId."); // أ. إلغاء الرحلة فوراً في قواعد البيانات // ملاحظة: غيرنا الحالة إلى رسالة واضحة $con->prepare("UPDATE ride SET status = 'cancelled_no_driver_found' WHERE id = ?")->execute([$insertedId]); $con_ride->prepare("UPDATE ride SET status = 'cancelled_no_driver_found' WHERE id = ?")->execute([$insertedId]); // ب. إشعار الراكب عبر السوكيت (لإظهار Popup) if (function_exists('notifyPassengerSocket')) { notifyPassengerSocket($passenger_id, 'no_drivers_found', [ 'ride_id' => $insertedId, 'message' => 'No drivers available nearby' ]); } // ج. إرجاع فشل للتطبيق jsonError("no_drivers_found"); */ } else { jsonError("Failed to add ride"); } } catch (Exception $e) { error_log("AddRide Critical Error: " . $e->getMessage()); jsonError("Database Error"); } ?>