getMessage() . "\n"; exit(1); } // 1. جلب الرحلات النشطة حالياً $stTrips = $transit_con->query( "SELECT id, route_id, current_stop_seq FROM transit_trips WHERE status='started'" ); $trips = $stTrips->fetchAll(); if (empty($trips)) { echo "No active trips. Nothing to check.\n"; exit(0); } foreach ($trips as $trip) { $tripId = (int)$trip['id']; $routeId = (int)$trip['route_id']; $currentSeq = (int)$trip['current_stop_seq']; // 2. جلب موقع الباص من Redis — تجاهل إن كان قديماً (> 3 دقائق، أي الباص فقد الاتصال) $pos = transitGetBusPosition($tripId); if (!$pos || empty($pos['lat'])) continue; if (empty($pos['ts']) || (time() - (int)$pos['ts']) > 180) continue; $busLat = (float)$pos['lat']; $busLng = (float)$pos['lng']; // 3. جلب المحطة التالية $nextSeq = $currentSeq + 1; $stStop = $transit_con->prepare( "SELECT id, name_ar, latitude, longitude FROM transit_stops WHERE route_id=? AND sequence=? LIMIT 1" ); $stStop->execute([$routeId, $nextSeq]); $nextStop = $stStop->fetch(); if ($nextStop) { $stopId = (int)$nextStop['id']; $stopLat = (float)$nextStop['latitude']; $stopLng = (float)$nextStop['longitude']; $stopName = $nextStop['name_ar']; // حساب المسافة تقريبياً $dist = transitCalculateDistance($busLat, $busLng, $stopLat, $stopLng); // إذا كانت المسافة أقل من 2 كم if ($dist <= 2000) { // نتحقق من Redis كي لا نرسل التنبيه مراراً لنفس المحطة في نفس الرحلة $alertKey = "transit:trip:{$tripId}:alert_stop:{$stopId}"; if (!$redis->exists($alertKey)) { $redis->set($alertKey, '1', 86400); // 24 ساعة // 4. جلب الركاب المشتركين الذين محطتهم المفضلة هي هذه $stPass = $transit_con->prepare( "SELECT passenger_id FROM transit_enrollments WHERE preferred_stop_id=? AND status='active'" ); $stPass->execute([$stopId]); $passengers = $stPass->fetchAll(PDO::FETCH_COLUMN); if (!empty($passengers)) { $title = "الباص يقترب 🚌"; $body = "حافلتك أصبحت قريبة جداً من محطة: {$stopName}. استعد!"; foreach ($passengers as $pId) { transitSendNotificationToPassenger($pId, $title, $body); } } } } } } /** * حساب المسافة بين نقطتين بالمتر (Haversine) */ function transitCalculateDistance($lat1, $lon1, $lat2, $lon2) { $earthRadius = 6371000; // Radius of the earth in meters $dLat = deg2rad($lat2 - $lat1); $dLon = deg2rad($lon2 - $lon1); $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon/2) * sin($dLon/2); $c = 2 * atan2(sqrt($a), sqrt(1-$a)); return $earthRadius * $c; } echo "Approaching alerts checked.\n";