قرار المالك 2026-07-27: باك إند سيرو PHP هو المعتمد، وتطبيقاته المجرّبة ميدانياً تحل محل إعادة البناء المؤرشفة. سيرو نفسه لم يُمسّ. الخريطة: backend · payment_server · loction_server · ride_server · passenger_server · docker · dashboard · stress_test → الجذر siro_rider → apps/rider siro_driver → apps/driver siro_admin → dashboards/admin siro_service → dashboards/service android_bot → apps/android_bot socialBot → apps/socialBot نُسخ المتعقَّب في git سيرو فقط عبر `git archive` (3,198 ملفاً / ~169 م.ب) لا `cp -r` — فاستُثنيت مخلفات البناء تلقائياً. بلا أي تعديل محتوى عمداً: كل ما يلي يصير فرقاً مقروءاً مقابل المصدر. لم يُستورد وسببه: siromove.com (الموقع التسويقي يبقى marketing/ في تريبز، سيرو فيه 8 ملفات) · docs و planning (تريبز له docs/ الخاص) · deploy.sh (ليس نشراً على سيرفر بل `git add . && git push origin --all` — فخّ في مستودع آخر) · transit_dashboard (بانتظار قرار مصير backend-transit و dashboards/transit-web). ⚠️ لا يبني بعد — ثلاثة نواقص متوقعة ومقصودة: 1. `.env` و `lib/env/env.g.dart` غير متعقَّبين في سيرو (أسرار لكل مستأجر): كل تطبيق فلاتر يحتاج .env خاصاً ثم توليد env.g.dart بـ build_runner. 2. إعدادات Firebase (9 ملفات google-services.json و GoogleService-Info.plist) يستبعدها .gitignore تريبز — ولكل مستأجر مشروع Firebase خاص أصلاً. 3. apps/driver في سيرو يشير إلى `../../Intaleq/packages/get` خارج المستودع → يجب ضمّ الحزم داخله أسوة بـ apps/rider. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
158 lines
6.2 KiB
PHP
158 lines
6.2 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../../connect.php';
|
|
|
|
if ($role !== 'admin' && $role !== 'super_admin') {
|
|
http_response_code(403);
|
|
echo json_encode(['error' => 'Unauthorized: Admin access required']);
|
|
exit;
|
|
}
|
|
|
|
// التطبيع عبر normalizePhone() الموحّدة في core/helpers.php (نفس المنطق سابقاً)
|
|
|
|
// 1. تسجيل بداية الطلب
|
|
$phone = filterRequest("phone");
|
|
error_log("[MONITOR_RIDE] ---------------- START REQUEST ----------------");
|
|
error_log("[MONITOR_RIDE] 1. Received Phone: " . $phone);
|
|
|
|
// تطبيع الرقم
|
|
$phone = normalizePhone($phone);
|
|
error_log("[MONITOR_RIDE] 1.5 Normalized Phone: " . $phone);
|
|
|
|
//------------------------------------------------------------------------
|
|
// 1) البحث عن الهاتف أولاً في جدول السائق ثم جدول الراكب
|
|
//------------------------------------------------------------------------
|
|
|
|
$encPhone = $encryptionHelper->encryptData($phone);
|
|
|
|
// فهرس البحث لكل جدول على حدة (النطاقات معزولة عمداً)
|
|
global $blindIndex;
|
|
$dBidx = $blindIndex ? $blindIndex->index('driver.phone', $phone) : null;
|
|
$pBidx = $blindIndex ? $blindIndex->index('passengers.phone', $phone) : null;
|
|
error_log("[MONITOR_RIDE] 2. Encrypted Phone: " . $encPhone);
|
|
|
|
// Check Driver Table
|
|
$driverQuery = $con->prepare("SELECT id AS driverID FROM driver WHERE phone = :phone OR (:bidx IS NOT NULL AND phone_bidx = :bidx) LIMIT 1");
|
|
$driverQuery->execute([':phone' => $encPhone, ':bidx' => $dBidx]);
|
|
$driver = $driverQuery->fetch(PDO::FETCH_ASSOC);
|
|
|
|
// Check Passenger Table
|
|
$customerQuery = $con->prepare("SELECT id AS customerID FROM passengers WHERE phone = :phone OR (:bidx IS NOT NULL AND phone_bidx = :bidx) LIMIT 1");
|
|
$customerQuery->execute([':phone' => $encPhone, ':bidx' => $pBidx]);
|
|
$customer = $customerQuery->fetch(PDO::FETCH_ASSOC);
|
|
|
|
// حدد نوع المستخدم
|
|
$userType = '';
|
|
$driverID = null;
|
|
$customerID = null;
|
|
|
|
if ($driver) {
|
|
$userType = 'driver';
|
|
$driverID = $driver['driverID'];
|
|
error_log("[MONITOR_RIDE] 3. User Found: Type = DRIVER, ID = " . $driverID);
|
|
} elseif ($customer) {
|
|
$userType = 'customer';
|
|
$customerID = $customer['customerID'];
|
|
error_log("[MONITOR_RIDE] 3. User Found: Type = CUSTOMER, ID = " . $customerID);
|
|
} else {
|
|
error_log("[MONITOR_RIDE] 3. FAILURE: Phone number not found in Driver or Passenger tables.");
|
|
jsonError("رقم الهاتف غير موجود في النظام.");
|
|
exit;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// 2) جلب آخر رحلة حالتها نشطة (Apply, Applied, Arrived, Begin)
|
|
//------------------------------------------------------------------------
|
|
|
|
$activeStatuses = "'Apply','Applied','Arrived','arrived','Begin'";
|
|
|
|
if ($userType == 'driver') {
|
|
error_log("[MONITOR_RIDE] 4. Searching for active ride for Driver ID: " . $driverID);
|
|
$rideQuery = $con->prepare("
|
|
SELECT * FROM ride
|
|
WHERE driver_id = :driverID AND status IN ($activeStatuses)
|
|
ORDER BY id DESC LIMIT 1
|
|
");
|
|
$rideQuery->execute([':driverID' => $driverID]);
|
|
} else {
|
|
error_log("[MONITOR_RIDE] 4. Searching for active ride for Customer ID: " . $customerID);
|
|
$rideQuery = $con->prepare("
|
|
SELECT * FROM ride
|
|
WHERE passenger_id = :customerID AND status IN ($activeStatuses)
|
|
ORDER BY id DESC LIMIT 1
|
|
");
|
|
$rideQuery->execute([':customerID' => $customerID]);
|
|
}
|
|
|
|
$ride = $rideQuery->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$ride) {
|
|
error_log("[MONITOR_RIDE] 4. FAILURE: No active ride found.");
|
|
jsonError("لا توجد رحلة نشطة لهذا المستخدم.");
|
|
exit;
|
|
} else {
|
|
error_log("[MONITOR_RIDE] 4. SUCCESS: Active Ride Found. Ride ID: " . $ride['id'] . " Status: " . $ride['status']);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// 3) جلب معلومات السائق من الرحلة
|
|
//------------------------------------------------------------------------
|
|
|
|
$rideDriverID = $ride['driverID'] ?? $ride['driver_id'];
|
|
error_log("[MONITOR_RIDE] 5. Fetching info for Driver ID from Ride: " . $rideDriverID);
|
|
|
|
$driverInfoQuery = $con->prepare("
|
|
SELECT id, first_name, last_name, phone
|
|
FROM driver
|
|
WHERE id = :driverID
|
|
LIMIT 1
|
|
");
|
|
|
|
$driverInfoQuery->execute([':driverID' => $rideDriverID]);
|
|
$driverInfo = $driverInfoQuery->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($driverInfo) {
|
|
$driverInfo['phone'] = $encryptionHelper->decryptData($driverInfo['phone']);
|
|
$driverInfo['first_name'] = $encryptionHelper->decryptData($driverInfo['first_name']);
|
|
$driverInfo['last_name'] = $encryptionHelper->decryptData($driverInfo['last_name']);
|
|
$fullName = $driverInfo['first_name'] . " " . $driverInfo['last_name'];
|
|
$driverInfo['fullname'] = $fullName;
|
|
error_log("[MONITOR_RIDE] 5. Driver Info Found: " . $fullName);
|
|
} else {
|
|
error_log("[MONITOR_RIDE] 5. WARNING: Driver info not found for ID " . $rideDriverID);
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// 4) جلب آخر موقع للسائق من جدول car_locations بشرط الحالة ON
|
|
//------------------------------------------------------------------------
|
|
|
|
error_log("[MONITOR_RIDE] 6. Querying Tracking DB for Driver ID: " . $rideDriverID);
|
|
|
|
$locationQuery = $con_tracking->prepare("
|
|
SELECT latitude, longitude, speed, heading, updated_at
|
|
FROM car_locations
|
|
WHERE driver_id = :driverID AND status = 'ON'
|
|
ORDER BY updated_at DESC LIMIT 1
|
|
");
|
|
$locationQuery->execute([':driverID' => $rideDriverID]);
|
|
$location = $locationQuery->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($location) {
|
|
error_log("[MONITOR_RIDE] 6. Location Found: Lat=" . $location['latitude'] . " Lng=" . $location['longitude']);
|
|
} else {
|
|
error_log("[MONITOR_RIDE] 6. WARNING: No live location found.");
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// 5) تجهيز البيانات للرد
|
|
//------------------------------------------------------------------------
|
|
|
|
$response = [
|
|
"ride_details" => $ride,
|
|
"driver_details" => $driverInfo,
|
|
"driver_location" => $location ?: "No live location"
|
|
];
|
|
|
|
error_log("[MONITOR_RIDE] 7. Sending Success Response.");
|
|
jsonSuccess($response);
|
|
error_log("[MONITOR_RIDE] 7. Sending Success Response.");
|
|
jsonSuccess($response); |