"failure", "message" => "Missing Parameters"]); exit; } try { // ================================================================= // الخطوة 1: الاتصال بسيرفر الرحلات ($con_ride) // الهدف: جلب driver_id وحالة الرحلة للتحقق // ================================================================= $sqlRide = "SELECT driver_id, status FROM ride WHERE id = :rideID LIMIT 1"; $stmtRide = $con_ride->prepare($sqlRide); $stmtRide->bindParam(':rideID', $rideID); $stmtRide->execute(); $rideData = $stmtRide->fetch(PDO::FETCH_ASSOC); // إذا لم توجد الرحلة if (!$rideData) { echo json_encode(["status" => "failure", "message" => "Ride not found"]); exit; } $driverID = $rideData['driver_id']; $status = $rideData['status']; // ================================================================= // الخطوة 2: التحقق الأمني (Hashing Validation) // القاعدة: Token = MD5(rideID + driverID + SecretSalt) // هذا يضمن أن الرابط تم توليده بواسطة التطبيق ولم يتم تخمينه // ================================================================= // * هام: هذه الكلمة السرية يجب أن تكون مطابقة تماماً للموجودة في تطبيق Flutter $secretSalt = getenv("secretSaltParent"); // إعادة بناء الهاش للمقارنة (HMAC-SHA256 بدلاً من MD5) $generatedToken = hash_hmac('sha256', $rideID . $driverID, $secretSalt); if ($token !== $generatedToken) { http_response_code(403); echo json_encode(["status" => "failure", "message" => "Invalid Security Token"]); exit; } // ================================================================= // الخطوة 3: التحقق من حالة الرحلة (Logic Check) // الشرط: التتبع يعمل فقط إذا كانت الرحلة قد بدأت // ================================================================= // يمكنك إضافة 'Applied' أو 'Arrived' إذا أردت التتبع قبل الركوب $allowedStatuses = ['Begin', 'inProgress']; if (!in_array($status, $allowedStatuses)) { echo json_encode(["status" => "failure", "message" => "Ride is not active", "ride_status" => $status]); exit; } // ================================================================= // الخطوة 4: الاتصال بسيرفر التتبع ($con_tracking) // الهدف: جلب أحدث إحداثيات للسائق // ================================================================= $sqlLoc = "SELECT latitude, longitude, heading, speed, updated_at FROM car_locations WHERE driver_id = :driverID ORDER BY updated_at DESC LIMIT 1"; $stmtLoc = $con_tracking->prepare($sqlLoc); $stmtLoc->bindParam(':driverID', $driverID); $stmtLoc->execute(); $locData = $stmtLoc->fetch(PDO::FETCH_ASSOC); if (!$locData) { // السائق لم يرسل موقعه بعد echo json_encode(["status" => "failure", "message" => "Waiting for driver signal..."]); exit; } // ================================================================= // الخطوة 5: الاتصال بالسيرفر الرئيسي ($con) // الهدف: جلب اسم السائق وموديل السيارة للعرض (اختياري لجمالية الصفحة) // ================================================================= $sqlDriver = "SELECT d.first_name, d.last_name, c.model, c.color, c.car_plate FROM driver d LEFT JOIN CarRegistration c ON d.id = c.driverID WHERE d.id = :driverID LIMIT 1"; $stmtDriver = $con->prepare($sqlDriver); $stmtDriver->bindParam(':driverID', $driverID); $stmtDriver->execute(); $driverInfo = $stmtDriver->fetch(PDO::FETCH_ASSOC); // فك التشفير إذا لزم الأمر (أسماء السائقين واللوحات غالباً مشفرة) if ($driverInfo) { // فك تشفير الاسم if (!empty($driverInfo['first_name'])) { $driverInfo['first_name'] = $encryptionHelper->decryptData($driverInfo['first_name']); } // فك تشفير اللوحة if (!empty($driverInfo['car_plate'])) { $driverInfo['car_plate'] = $encryptionHelper->decryptData($driverInfo['car_plate']); } // يمكنك فك تشفير باقي الحقول حسب الحاجة } // ================================================================= // الخطوة 6: تجميع البيانات وإرسال الرد النهائي // ================================================================= $response = [ "status" => "success", "data" => [ "lat" => $locData['latitude'], "lng" => $locData['longitude'], "heading" => $locData['heading'], "speed" => $locData['speed'], "last_update" => $locData['updated_at'], "driver_name" => $driverInfo['first_name'] ?? "Captain", "car_model" => $driverInfo['model'] ?? "", "car_color" => $driverInfo['color'] ?? "", "plate" => $driverInfo['car_plate'] ?? "" ] ]; echo json_encode($response); } catch (Exception $e) { // تسجيل الخطأ دون إظهاره للمستخدم العام error_log("Tracking Error: " . $e->getMessage()); echo json_encode(["status" => "failure", "message" => "Server Error"]); } ?>