$lat, 'lng' => $lng, 'radius' => 5, // 5 كم كافية للعرض 'limit' => 50 ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 3); curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $INTERNAL_KEY"]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $redisDrivers = []; if ($httpCode == 200 && $response) { $json = json_decode($response, true); if (isset($json['status']) && $json['status'] === true) { $redisDrivers = $json['data']; } } if (empty($redisDrivers)) { jsonSuccess([]); exit; } // تجهيز خريطة لدمج البيانات لاحقاً (ID => RedisData) $driversMap = []; $driverIds = []; foreach ($redisDrivers as $d) { $driverIds[] = $d['id']; $driversMap[$d['id']] = $d; } // ========================================== // 3. جلب التفاصيل الكاملة من MySQL (مثل الملف القديم تماماً) // ========================================== // تجهيز الـ Placeholders $placeholders = implode(',', array_fill(0, count($driverIds), '?')); // الاستعلام الشامل (نفس الحقول القديمة) $sql_drivers_info = " SELECT d.id AS driver_id, d.phone, d.email, d.birthdate, d.first_name, d.last_name, d.gender, d.maritalStatus, COALESCE(cr.make, d.make, '') AS make, cr.car_plate, COALESCE(cr.model, d.model, '') AS model, cr.color, cr.vin, cr.color_hex, COALESCE(cr.year, d.year, 0) AS year, cr.vehicle_category_id, dt.token, COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver FROM driver d LEFT JOIN CarRegistration cr ON cr.driverID = d.id LEFT JOIN driverToken dt ON dt.captain_id = d.id LEFT JOIN ( SELECT driver_id, AVG(rating) AS ratingDriver FROM ratingDriver GROUP BY driver_id ) rdAvg ON rdAvg.driver_id = d.id WHERE d.id IN ($placeholders) AND COALESCE(cr.year, d.year, 0) > 2000 AND (COALESCE(cr.make, d.make, '') NOT LIKE '%دراج%' AND COALESCE(cr.model, d.model, '') NOT LIKE '%دراج%') "; $stmt = $con->prepare($sql_drivers_info); $stmt->execute($driverIds); $drivers_db = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($drivers_db)) { jsonSuccess([], "No matching drivers in DB"); exit; } // ========================================== // 4. معالجة البيانات، الدمج، وفك التشفير // ========================================== $final_result = []; $serverNow = date('Y-m-d H:i:s'); $fieldsToDecrypt = ['phone','email','gender','birthdate','first_name','last_name','token','car_plate','vin']; // الهاش الخاص بالإناث (لتحديد النوع لاحقاً إذا لزم الأمر) // $femaleHash = 'bQ6yWJ2EVXKZooHdGclvmFiDlZCM8UYeO+ILFjDUvpQ='; foreach ($drivers_db as $row) { $did = $row['driver_id']; // دمج بيانات الموقع الحية من الريدز (أهم خطوة) if (isset($driversMap[$did])) { $redisInfo = $driversMap[$did]; $row['latitude'] = $redisInfo['lat']; $row['longitude'] = $redisInfo['lng']; $row['heading'] = $redisInfo['heading']; $row['speed'] = $redisInfo['speed']; // $row['distance'] = $redisInfo['distance']; // إذا أردت إضافتها } else { // حالة نادرة: السائق موجود في الاستعلام ولكن ليس في مصفوفة الريدز (لا يجب أن تحدث) continue; } $row['serverNow'] = $serverNow; // فك التشفير (Decrypt) foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && $row[$field] !== null && $row[$field] !== '') { try { $row[$field] = $encryptionHelper->decryptData($row[$field]); } catch (Exception $e) { $row[$field] = null; } } } // حساب العمر if (!empty($row['birthdate'])) { try { $birthdate = new DateTime($row['birthdate']); $today = new DateTime(); $row['age'] = $today->diff($birthdate)->y; } catch (Exception $e) { $row['age'] = null; } } else { $row['age'] = null; } // إضافة نوع السيارة البسيط (اختياري، إذا كان التطبيق يعتمد عليه) /* $type = 'car'; if ($row['vehicle_category_id'] == 2) $type = 'bike'; elseif ($row['gender'] == 'female') $type = 'lady'; // بعد فك التشفير تكون female $row['type'] = $type; */ $final_result[] = $row; } // إرجاع النتيجة بنفس الهيكل القديم jsonSuccess($final_result); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ?>