'get_nearby_ride_ids', 'lat' => $lat, 'lng' => $lng, 'radius' => $radius ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $locationServerUrl); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 500); curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $INTERNAL_KEY"]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode == 200 && $response) { $jsonResults = json_decode($response, true); if (is_array($jsonResults) && !empty($jsonResults)) { foreach ($jsonResults as $res) { $rideIds[] = $res[0]; $redisResultsMap[$res[0]] = $res[1]; } } } } catch (Exception $e) { // نتابع للخطة ب } // 2. جلب البيانات (إما عبر IDs أو بحث مباشر) try { if (!empty($rideIds)) { // --- الحالة أ: الريدز وجد رحلات --- $placeholders = implode(',', array_fill(0, count($rideIds), '?')); $sql = " SELECT wr.id, wr.start_location AS startName, wr.end_location AS endName, wr.date, wr.time, wr.price, wr.passenger_id, wr.status, wr.carType, wr.passengerRate, wr.created_at, wr.price_for_passenger, wr.distance, wr.duration, wr.start_lat, wr.start_lng, wr.end_lat, wr.end_lng, wr.payment_method, wr.passenger_wallet, p.email, p.first_name, p.phone, p.id AS passengerId, t.token AS passengerToken FROM waitingRides wr INNER JOIN passengers p ON p.id = wr.passenger_id LEFT JOIN tokens t ON t.passengerID = wr.passenger_id LEFT JOIN passengerWallet pw ON pw.passenger_id = wr.passenger_id WHERE wr.id IN ($placeholders) AND wr.status IN ('wait', 'waiting') "; $stmt = $con->prepare($sql); $stmt->execute($rideIds); $waitingRides = $stmt->fetchAll(PDO::FETCH_ASSOC); } else { // --- الحالة ب: بحث مباشر MySQL (Fallback) --- // 🔥 التصحيح هنا: استخدام أسماء فريدة (:lat1, :lat2) لتجنب خطأ التكرار $haversine = "( 6371 * acos( cos( radians(:lat1) ) * cos( radians( wr.start_lat ) ) * cos( radians( wr.start_lng ) - radians(:lng) ) + sin( radians(:lat2) ) * sin( radians( wr.start_lat ) ) ) )"; $sql = " SELECT wr.id, wr.start_location AS startName, wr.end_location AS endName, wr.date, wr.time, wr.price, wr.passenger_id, wr.status, wr.carType, wr.passengerRate, wr.created_at, wr.price_for_passenger, wr.distance, wr.duration, wr.start_lat, wr.start_lng, wr.end_lat, wr.end_lng, wr.payment_method, wr.passenger_wallet, p.email, p.first_name, p.phone, p.id AS passengerId, t.token AS passengerToken, {$haversine} AS driver_distance_km FROM waitingRides wr INNER JOIN passengers p ON p.id = wr.passenger_id LEFT JOIN tokens t ON t.passengerID = wr.passenger_id LEFT JOIN passengerWallet pw ON pw.passenger_id = wr.passenger_id WHERE wr.status IN ('wait', 'waiting') AND wr.created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR) AND wr.start_lat IS NOT NULL HAVING driver_distance_km <= :radius ORDER BY driver_distance_km ASC LIMIT 50 "; $stmt = $con->prepare($sql); // نمرر القيمة مرتين للمفتاحين المختلفين $stmt->execute([ ':lat1' => $lat, ':lng' => $lng, ':lat2' => $lat, // تكرار القيمة للمتغير الثاني ':radius' => $radius ]); $waitingRides = $stmt->fetchAll(PDO::FETCH_ASSOC); } // 3. التنسيق foreach ($waitingRides as $ride) { $ride['phone'] = $encryptionHelper->decryptData($ride['phone'] ?? ''); $ride['first_name'] = $encryptionHelper->decryptData($ride['first_name'] ?? ''); $ride['email'] = $encryptionHelper->decryptData($ride['email'] ?? ''); $ride['start_location'] = $ride['start_lat'] . ',' . $ride['start_lng']; $ride['end_location'] = (!empty($ride['end_lat'])) ? $ride['end_lat'] . ',' . $ride['end_lng'] : $ride['endName']; $ride['id'] = (string)$ride['id']; if (isset($ride['driver_distance_km'])) { $ride['driver_distance_km'] = number_format((float)$ride['driver_distance_km'], 1); } elseif (isset($redisResultsMap[$ride['id']])) { $ride['driver_distance_km'] = number_format((float)$redisResultsMap[$ride['id']], 1); } else { $ride['driver_distance_km'] = "0.0"; } $finalRides[] = $ride; } usort($finalRides, function($a, $b) { return $a['driver_distance_km'] <=> $b['driver_distance_km']; }); jsonSuccess($finalRides); } catch (PDOException $e) { error_log("DB Error getRideWaiting: " . $e->getMessage()); jsonError("Database error"); } ?>