# Siro V1 - Secure Latest Version ## File: functions.php ``` $action, ...$data ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); 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"]); curl_exec($ch); curl_close($ch); } function findBestDrivers($con, $lat, $lng, $carType) { // 1. الاتصال بـ Redis لجلب الأقرب $locationServerUrl = "https://location.intaleq.xyz/api_get_nearby.php"; $INTERNAL_KEY = trim(@file_get_contents('/home/siro-api/.internal_socket_key')); $postData = ['lat' => $lat, 'lng' => $lng, 'radius' => 5, 'limit' => 100]; $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, 3); curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $INTERNAL_KEY"]); $response = curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch); if ($info['http_code'] !== 200) return []; $json = json_decode($response, true); $nearbyDrivers = ($json['status'] ?? false) ? $json['data'] : []; if (empty($nearbyDrivers)) return []; // 2. تجهيز البيانات للفلترة $driverIds = []; $redisMap = []; foreach ($nearbyDrivers as $d) { $driverIds[] = $d['id']; $redisMap[$d['id']] = $d; } $placeholders = implode(',', array_fill(0, count($driverIds), '?')); // تعريف الثوابت $CAT_CAR = 1; $CAT_BIKE = 2; $CAT_VAN = 3; $FUEL_ELECTRIC = 3; // 3. الاستعلام (بدون platform) $sql = "SELECT d.id AS driver_id, dt.token, cr.year, cr.vehicle_category_id, d.gender FROM driver d JOIN CarRegistration cr ON cr.driverID = d.id JOIN driverToken dt ON dt.captain_id = d.id WHERE d.id IN ($placeholders) "; $carType = trim($carType); switch ($carType) { case 'Comfort': $sql .= " AND cr.vehicle_category_id = $CAT_CAR AND CAST(TRIM(cr.year) AS UNSIGNED) > 2017 "; break; case 'Mishwar Vip': $sql .= " AND cr.vehicle_category_id = $CAT_CAR AND CAST(TRIM(cr.year) AS UNSIGNED) > 2020 "; break; case 'Scooter': case 'Pink Bike': $sql .= " AND cr.vehicle_category_id = $CAT_BIKE "; break; case 'Electric': $sql .= " AND cr.vehicle_category_id = $CAT_CAR AND cr.fuel_type_id = $FUEL_ELECTRIC "; break; case 'Lady': $femaleHash = 'bQ6yWJ2EVXKZooHdGclvmFiDlZCM8UYeO+ILFjDUvpQ='; $sql .= " AND cr.vehicle_category_id = $CAT_CAR AND d.gender = '$femaleHash' "; break; case 'Van': $sql .= " AND cr.vehicle_category_id = $CAT_VAN "; break; case 'Awfar Car': $sql .= " AND cr.vehicle_category_id = $CAT_CAR AND CAST(TRIM(cr.year) AS UNSIGNED) > 1995 "; break; case 'Fixed Price': case 'Speed': case 'Rayeh Gai': default: $sql .= " AND cr.vehicle_category_id = $CAT_CAR AND CAST(TRIM(cr.year) AS UNSIGNED) > 2000 "; break; } try { $stmt = $con->prepare($sql); $stmt->execute($driverIds); $finalDrivers = $stmt->fetchAll(PDO::FETCH_ASSOC); // دمج البيانات foreach ($finalDrivers as &$driver) { $did = $driver['driver_id']; if (isset($redisMap[$did])) { $driver['distance_km'] = $redisMap[$did]['distance']; $driver['lat'] = $redisMap[$did]['lat']; $driver['lng'] = $redisMap[$did]['lng']; } else { $driver['distance_km'] = 999; } } // الترتيب usort($finalDrivers, function($a, $b) { return $a['distance_km'] <=> $b['distance_km']; }); return array_slice($finalDrivers, 0, 30); } catch (Exception $e) { error_log("FindBestDrivers Error: " . $e->getMessage()); return []; } } // --- دالة مساعدة لمخاطبة سيرفر السائقين (Location Socket) --- function notifyDriversRideTaken($rideId, $winnerDriverId) { // رابط سيرفر السائقين الداخلي (نفس البورت المستخدم في driver_socket.php) $url = getenv('LOCATION_SOCKET_URL'); if (!$url) throw new RuntimeException('LOCATION_SOCKET_URL not configured'); $INTERNAL_KEY = trim(@file_get_contents('/home/siro-api/.internal_socket_key')); $postData = [ 'action' => 'ride_taken_event', // هذا الأكشن الجديد في السوكيت 'ride_id' => $rideId, 'taken_by_driver_id' => $winnerDriverId ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); 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); // نصف ثانية فقط، لا نريد تعطيل الـ API curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $INTERNAL_KEY"]); $response = curl_exec($ch); curl_close($ch); } function notifyDriversOnLocationServer($drivers_ids_array, $payload, $rideId = null) { // رابط سيرفر اللوكيشن الخارجي $url = getenv('LOCATION_SOCKET_URL'); if (!$url) throw new RuntimeException('LOCATION_SOCKET_URL not configured'); $INTERNAL_KEY = trim(@file_get_contents('/home/siro-api/.internal_socket_key')); $postData = [ 'action' => 'dispatch_order', // اسم الحدث المتفق عليه في socket_server.php هناك 'drivers_ids' => json_encode($drivers_ids_array), // نحول المصفوفة لنص JSON 'ride_id' => $rideId ?? '', // ✅ تصحيح اسم المتغير 'payload' => $payload ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); 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, 1000); // لا تنتظر أكثر من ثانية curl_setopt($ch, CURLOPT_HTTPHEADER, [ "x-internal-key: $INTERNAL_KEY" ]); $response = curl_exec($ch); if (curl_errno($ch)) { error_log("Curl Error (Location Socket): " . curl_error($ch)); } curl_close($ch); return $response; } /** * 🚀 دالة إشعار الراكب (تعمل على سيرفر الرحلات) * تخاطب السوكيت الموجود محلياً على نفس السيرفر */ function notifyPassengerOnRideServer($passenger_id, $payload) { // الرابط المحلي لسيرفر سوكيت الركاب $url = getenv('PASSENGER_SOCKET_URL'); if (!$url) { error_log("[FATAL] PASSENGER_SOCKET_URL not configured"); throw new RuntimeException('PASSENGER_SOCKET_URL not configured'); } $INTERNAL_KEY = trim(@file_get_contents('/home/siro-api/.internal_socket_key')); $postData = [ 'action' => 'update_ride_status', 'passenger_id' => $passenger_id, 'payload' => $payload ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); 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, 1000); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "x-internal-key: $INTERNAL_KEY" ]); $response = curl_exec($ch); if (curl_errno($ch)) { error_log("Curl Error (Passenger Socket): " . curl_error($ch)); } curl_close($ch); return $response; } // ============================================================================ // دالة توزيع الطلب (محدثة لاستخدام sendFCM_Internal) // ============================================================================ // ============================================================================ // دالة توزيع الطلب (Dispatch Function) - النسخة المصححة // ============================================================================ function dispatchRideToDrivers($driversData, $rideId, $payloadTemplate, $startNameLoc, $encryptionHelper) { $countDrivers = count($driversData); error_log("🚀 [DISPATCH_START] RideID: $rideId | Drivers Count: $countDrivers"); $socketUrl = getenv('LOCATION_SOCKET_URL'); if (!$socketUrl) throw new RuntimeException('LOCATION_SOCKET_URL not configured'); $internalKeyPath = '/home/siro-api/.internal_socket_key'; $internalKey = file_exists($internalKeyPath) ? trim(file_get_contents($internalKeyPath)) : ''; foreach ($driversData as $driver) { $driverId = $driver['driver_id']; $rawToken = $driver['token'] ?? ''; error_log("--------------------------------------------------"); error_log("👤 [DRIVER_PROCESS] Processing Driver ID: $driverId"); // 1. معالجة التوكن $driverToken = processDriverToken($rawToken, $encryptionHelper); // تجهيز البيانات الخاصة بالسائق $payloadForDriver = $payloadTemplate; $payloadForDriver[6] = (string)$driverId; $payloadForDriver[18] = (string)$driverId; // 2. إرسال السوكيت sendSocketNotification($driverId, $rideId, $payloadForDriver, $socketUrl, $internalKey); // 3. إرسال FCM if (!empty($driverToken)) { $fcmData = [ 'DriverList' => $payloadForDriver, 'order_id' => (string)$rideId ]; $fcmResult = sendFcmNotification( $driverToken, "طلب جديد 🔔", "هناك رحلة جديدة من " . $startNameLoc, $fcmData, "Order", "ding" ); error_log("📲 [FCM_RESULT] " . json_encode($fcmResult)); } else { error_log("⚠️ [FCM_SKIP] No valid token for Driver $driverId"); } } error_log("🏁 [DISPATCH_END] RideID: $rideId"); } /** * معالجة توكن السائق وفك تشفيره */ function processDriverToken($rawToken, $encryptionHelper) { if (empty($rawToken)) { error_log("🚫 [TOKEN_MISSING] No token found."); return ''; } try { $decrypted = $encryptionHelper->decryptData($rawToken); if ($decrypted !== false && !empty($decrypted)) { error_log("✅ [TOKEN_DECRYPT] Success."); return trim($decrypted); } error_log("⚠️ [TOKEN_DECRYPT] Failed. Using Raw."); return $rawToken; } catch (Exception $e) { error_log("❌ [TOKEN_EXCEPTION] Error. Using Raw."); return $rawToken; } } /** * إرسال إشعار السوكيت لسيرفر اللوكيشن */ function sendSocketNotification($driverId, $rideId, $payload, $url, $internalKey) { $postData = [ 'action' => 'dispatch_order', 'drivers_ids' => json_encode([$driverId]), 'ride_id' => $rideId, 'payload' => $payload ]; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); if (!empty($internalKey)) curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $internalKey"]); curl_setopt($ch, CURLOPT_TIMEOUT, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); $res = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); error_log("📡 [SOCKET_SEND] Driver $driverId | HTTP: $httpCode"); } /** * إرسال إشعار FCM الموحد */ function sendFcmNotification($token, $title, $body, $data, $category, $tone) { if (class_exists('FcmService')) { global $redis; $fcmService = new FcmService($redis ?? null); return $fcmService->send($token, $title, $body, $data, $category, $tone); } elseif (function_exists('sendFCM_Internal')) { return sendFCM_Internal($token, $title, $body, $data, $category, false, $tone); } return ['status' => 'error', 'message' => 'FCM service not loaded']; } // ═══════════════════════════════════════════════════════════════ // authenticateJWT() — النسخة النهائية الكاملة // ─────────────────────────────────────────────────────────────── // قائمة allowedFiles مبنية على هيكل الملفات الفعلي: // siro_v1/ ← الجذر // siro_v1/auth/ ← مشترك راكب/سائق // siro_v1/auth/syria/ ← تسجيل سوريا // siro_v1/auth/captin/ ← تسجيل السائق // ═══════════════════════════════════════════════════════════════ function authenticateJWT(): object { $secretKey = trim(file_get_contents('/home/siro-api/.secret_key')); $hmacSecret = getenv('SECRET_KEY_HMAC'); $fpPepper = getenv('FP_PEPPER'); if (!$secretKey || !$hmacSecret) { http_response_code(500); echo json_encode(['error' => 'Internal server configuration error.']); exit; } // ── 1. استخراج الـ JWT من Authorization header ───────────── $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; $token = null; if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) { $token = $matches[1]; } if (!$token) { http_response_code(401); echo json_encode(['error' => 'Authorization token required']); exit; } // ── 2. فك التشفير والتحقق من التوقيع والصلاحية ───────────── try { $decoded = JWT::decode($token, new Key($secretKey, 'HS256')); } catch (ExpiredException $e) { http_response_code(401); echo json_encode(['error' => 'Token expired']); exit; } catch (SignatureInvalidException $e) { http_response_code(401); echo json_encode(['error' => 'Invalid token signature']); exit; } catch (BeforeValidException $e) { http_response_code(401); echo json_encode(['error' => 'Token not yet valid']); exit; } catch (Exception $e) { http_response_code(401); echo json_encode(['error' => 'Invalid token']); exit; } // ── 3. التحقق من الـ Issuer ───────────────────────────────── $expectedIssuer = getenv('APP_ISSUER') ; if (($decoded->iss ?? '') !== $expectedIssuer) { http_response_code(401); echo json_encode(['error' => 'Invalid token issuer']); exit; } // استخراج user_id من الـ payload $userId = $decoded->user_id ?? $decoded->sub ?? null; if (!$userId) { http_response_code(401); echo json_encode(['error' => 'Invalid JWT payload']); exit; } // ── 4. فحص token_type ─────────────────────────────────────── // توكن التسجيل (loginFirstTime) نوعه 'registration' // مدته 150 ثانية فقط ومقيّد بـ endpoints التسجيل // ─────────────────────────────────────────────────────────── // ── 4. فحص token_type ─────────────────────────────────────── $tokenType = $decoded->token_type ?? 'access'; // حل مؤقت: دمج صلاحيات 'registration' و 'new' على نفس القائمة البيضاء if ($tokenType === 'registration' || $tokenType === 'new') { $allowedFiles = [ 'loginFirstTime', 'loginFirstTimeDriver', 'checkPhoneNumberISVerfiedDriver', 'checkPhoneNumberISVerfiedPassenger', 'loginFromGooglePassenger', 'otpmessage', 'signup', 'verifyEmail', 'verifyOtpMessage', 'sendVerifyEmail', 'sendWhatsAppDriver', 'register_passenger', 'sendWhatsOpt', 'verifyOtp', 'auth_proxy', 'addToken', 'loginFromGoogle', 'loginUsingCredentialsWithoutGoogle', 'register', 'sendOtpMessageDriver', 'getTokensPassenger', 'send_otp', 'verify_otp', ]; $currentFile = basename($_SERVER['PHP_SELF'], '.php'); $isAllowed = false; foreach ($allowedFiles as $allowed) { if (strcasecmp($currentFile, $allowed) === 0) { $isAllowed = true; break; } } if (!$isAllowed) { error_log(sprintf( '⚠️ [SECURITY] Auth token blocked | type=%s | file=%s | user=%s | IP=%s', $tokenType, $currentFile, $userId, $_SERVER['REMOTE_ADDR'] ?? 'unknown' )); http_response_code(403); echo json_encode(['error' => 'Token not authorized for this action']); exit; } } // ── 5. التحقق من بصمة الجهاز ─────────────────────────────── // Flutter يرسل fp_encrypted في X-Device-FP header // السيرفر يحسب: sha256(fp_encrypted + FP_PEPPER) // يقارنه مع JWT.fingerPrint المخزن عند تسجيل الدخول // ─────────────────────────────────────────────────────────── // backward compatibility: // توكنات قبل الأبديت ليس فيها fingerPrint → نسمح مؤقتاً // بعد انتهاء كل التوكنات القديمة (15 دقيقة من النشر) // احذف الشرط الداخلي واجعل الفحص إلزامياً دائماً // ─────────────────────────────────────────────────────────── if ($fpPepper) { $fpInToken = $decoded->fingerPrint ?? null; $fpHeader = $_SERVER['HTTP_X_DEVICE_FP'] ?? null; if ($fpInToken === null || $fpHeader === null) { error_log(sprintf('⚠️ [SECURITY] Fingerprint missing | user=%s', $userId)); http_response_code(403); echo json_encode(['error' => 'Device verification required']); exit; } $expectedFp = hash('sha256', $fpHeader . $fpPepper); if (!hash_equals($expectedFp, $fpInToken)) { error_log(sprintf( '⚠️ [SECURITY] Device mismatch | user=%s | IP=%s', $userId, $_SERVER['REMOTE_ADDR'] ?? 'unknown' )); http_response_code(403); echo json_encode(['error' => 'Device mismatch']); exit; } } // ── 6. التحقق من الـ HMAC — للـ wallet فقط ───────────────── // X-HMAC-Auth موجود فقط في طلبات المحفظة // لو موجود → نتحقق منه إلزامياً // ─────────────────────────────────────────────────────────── $hmacHeader = $_SERVER['HTTP_X_HMAC_AUTH'] ?? null; if ($hmacHeader !== null) { $expectedHmac = hash_hmac('sha256', $userId, $hmacSecret); if (!hash_equals($expectedHmac, $hmacHeader)) { error_log(sprintf( '⚠️ [SECURITY] HMAC mismatch | user=%s | IP=%s', $userId, $_SERVER['REMOTE_ADDR'] ?? 'unknown' )); http_response_code(403); echo json_encode(['error' => 'Invalid HMAC']); exit; } } // ✅ كل التحققات نجحت — نرجع الـ payload return $decoded; } define("MB", 1048576); /** * Send WhatsApp message using your server's API * * @param string $to The recipient phone number (e.g., 96279xxxxxxx) * @param string $message The message to send * @return mixed API response object or false on failure */ function sendWhatsAppFromServer($to, $message) { // 1) قائمة السيرفرات المتاحة $servers = [ //"https://botmasa.intaleq.xyz/send",//mayar // "https://botmasa2.intaleq.xyz/send",//shad "https://bot5.intaleq.xyz/send",//ramat bus "https://bot3.intaleq.xyz/send",//shahd //"https://whatsapp.tripz-egypt.com/send"//tripz ]; // 2) محاولة الإرسال (Primary -> Fallback) $response = null; $success = false; foreach ($servers as $url) { $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 3, // مهلة قصيرة للمحاولة CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode([ "to" => $to, "message" => $message ], JSON_UNESCAPED_UNICODE), CURLOPT_HTTPHEADER => ["Content-Type: application/json"], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if (!$err) { $success = true; break; } else { error_log("[sendWhatsAppFromServer] Server $url failed, trying next... Error: $err"); } } if (!$success) return false; return json_decode($response, true); } /* $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => [ 'Content-Type: application/x-www-form-urlencoded' ], ]); // تنفيذ الطلب $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); // التحقق من الأخطاء if ($err) { error_log("[sendWhatsAppFromServer] cURL Error: $err"); return false; } return $response; } */ function debugLog($message) { error_log($message); } // [DELETED] filterRequest and imageUpload moved to core/helpers.php function sendFCM_Internal( $target, $title, $body, $customData = [], $category = 'Order', $isTopic = false, $tone = 'order' ) { // مسار ملف الصلاحيات $serviceAccountFile = __DIR__ . '/service-account.json'; $tokenCacheFile = sys_get_temp_dir() . '/fcm_access_token.json'; // 1. الحصول على Access Token من الكاش أو من جوجل $accessToken = getCachedAccessToken($serviceAccountFile, $tokenCacheFile); if (!$accessToken) { error_log("❌ [FCM] Failed to get Access Token."); return ['status' => 'error', 'message' => 'Auth Failed']; } // 2. جلب project_id وبناء رابط FCM $creds = json_decode(file_get_contents($serviceAccountFile), true); $projectId = $creds['project_id']; $fcmUrl = "https://fcm.googleapis.com/v1/projects/$projectId/messages:send"; // ============================================================ // 3. تجهيز الـ Data Payload الموحد (المهم لـ Flutter) // ============================================================ // نبدأ بالـ customData (مثلاً ride_id, driver_id, ... إلخ) $finalData = is_array($customData) ? $customData : []; // نضيف الحقول القياسية التي سيقرأها Flutter دائماً $finalData['title'] = $title; $finalData['body'] = $body; $finalData['tone'] = $tone; $finalData['category'] = $category; // ✅ الحقل الرسمي الذي يتحقق منه Flutter $finalData['type'] = $category; // (اختياري) للتماشي مع أي كود قديم // تحويل كل القيم إلى نصوص (شرط FCM: data values must be strings) $processedData = []; foreach ($finalData as $key => $val) { if (is_array($val) || is_object($val)) { $processedData[$key] = json_encode($val, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } else { $processedData[$key] = (string)$val; } } // ============================================================ // 4. بناء الرسالة: Data-Only (بدون Notification Block) // ============================================================ $messagePayload = [ 'message' => [ 'data' => $processedData, // ✅ كل شيء داخل data فقط 'android' => [ 'priority' => 'HIGH', ], 'apns' => [ 'headers' => [ 'apns-priority' => '10', 'apns-push-type' => 'background', ], 'payload' => [ 'aps' => [ 'content-available' => 1, // لا نضع alert هنا حتى لا يظهر إشعار نظام تلقائي ], ], ], ], ]; // تحديد المستلم (Token أو Topic) if ($isTopic) { $messagePayload['message']['topic'] = $target; } else { $messagePayload['message']['token'] = $target; } // ============================================================ // 5. الإرسال عبر CURL // ============================================================ $ch = curl_init($fcmUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $accessToken, 'Content-Type: application/json; charset=UTF-8', ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($messagePayload, JSON_UNESCAPED_UNICODE)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch)) { $error_msg = curl_error($ch); curl_close($ch); return ['status' => 'error', 'message' => 'CURL Error: ' . $error_msg]; } curl_close($ch); if ($httpCode == 200) { return ['status' => 'success', 'response' => json_decode($result, true)]; } else { error_log("❌ [FCM Error] Code: $httpCode | Response: $result"); return ['status' => 'error', 'code' => $httpCode, 'response' => $result]; } } // -------------------------------------------------------------------------- // دوال مساعدة (Helper Functions) // -------------------------------------------------------------------------- function getCachedAccessToken($credentialsPath, $cacheFile) { global $redis; // 1. محاولة القراءة من Redis (أسرع وأكثر أماناً) if ($redis) { $token = $redis->get('fcm:access_token'); if ($token) return $token; } // 2. إذا لم يوجد، نطلب واحد جديد $newToken = getGoogleAccessToken($credentialsPath); if ($newToken && $redis) { // حفظ في Redis لمدة ساعة (3500 ثانية) $redis->setex('fcm:access_token', 3500, $newToken); } return $newToken; } function getGoogleAccessToken($credentialsPath) { if (!file_exists($credentialsPath)) return null; $credentials = json_decode(file_get_contents($credentialsPath), true); $clientEmail = $credentials['client_email']; $privateKey = $credentials['private_key']; $now = time(); $header = rtrim(strtr(base64_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT'])), '+/', '-_'), '='); $claim = rtrim(strtr(base64_encode(json_encode([ 'iss' => $clientEmail, 'scope' => 'https://www.googleapis.com/auth/firebase.messaging', 'aud' => 'https://oauth2.googleapis.com/token', 'exp' => $now + 3600, 'iat' => $now ])), '+/', '-_'), '='); $signature = ''; openssl_sign("$header.$claim", $signature, $privateKey, 'SHA256'); $jwt = "$header.$claim." . rtrim(strtr(base64_encode($signature), '+/', '-_'), '='); $ch = curl_init("https://oauth2.googleapis.com/token"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($ch); curl_close($ch); return json_decode($res, true)['access_token'] ?? null; } ////////// function jsonError($message = "none") { echo json_encode(array("status" => "failure", "message" => $message)); } function jsonSuccess($message = "none") { echo json_encode(array("status" => "success", "message" => $message)); } function result($count) { if ($count > 0) { jsonSuccess(); } else { jsonError(); } } function sendEmail($from,$to, $title, $body) { $header = "From: $from" . "\n" . "CC: $from"; mail($to, $title, $body, $header); } ``` ## File: uploadImagePortrate.php ``` enforce(RateLimiter::identifier($user_id ?? null), 'upload'); $driverID = filterRequest("driverID"); appLog("📥 Received driverID: $driverID"); if (empty($driverID)) { jsonError('Driver ID is required.', 400); } // 2. استخدام دالة الرفع الآمنة (MIME check, random name, 5MB limit) $target_dir = __DIR__ . "/portrate_captain_image/"; $uploadResult = uploadImageSecure('image', $target_dir, $driverID); if (!$uploadResult['success']) { securityLog("❌ Image upload failed", ['driverID' => $driverID, 'error' => $uploadResult['error']]); jsonError($uploadResult['error'], 400); } $new_filename = $uploadResult['filename']; appLog("✅ File moved successfully to: " . $uploadResult['path']); // 3. تحديث قاعدة البيانات $linkImage = 'https://intaleq.xyz/portrate_captain_image/' . $new_filename; $uploadDate = date("Y-m-d H:i:s"); // تأكد من أن الاتصال قادم من connect.php أو اجلبه $con = Database::get('main'); // التحقق من وجود السائق $stmt = $con->prepare("SELECT COUNT(*) FROM card_images WHERE driverID = ?"); $stmt->execute([$driverID]); $count = $stmt->fetchColumn(); if ($count > 0) { // تحديث $updateSQL = "UPDATE card_images SET upload_date = ?, image_name = ?, link = ? WHERE driverID = ?"; $updateStmt = $con->prepare($updateSQL); $success = $updateStmt->execute([$uploadDate, $new_filename, $linkImage, $driverID]); } else { // إدخال جديد $insertSQL = "INSERT INTO imageProfileCaptain (driverID, image_name, link) VALUES (?, ?, ?)"; $insertStmt = $con->prepare($insertSQL); $success = $insertStmt->execute([$driverID, $new_filename, $linkImage]); } if ($success) { appLog("✅ Record updated for driverID: $driverID"); jsonSuccess(['file_link' => $linkImage], 'Record updated successfully.'); } else { appLog("❌ Failed to update DB record for driverID: $driverID"); jsonError('Failed to update record.', 500); } } catch (PDOException $e) { securityLog("💥 PDO ERROR in uploadImage", ['error' => $e->getMessage()]); jsonError('Database error.', 500); } catch (Exception $e) { securityLog("💥 GENERAL ERROR in uploadImage", ['error' => $e->getMessage()]); jsonError('Server error.', 500); } ``` ## File: loginAdmin.php ``` enforce(RateLimiter::identifier(), 'login'); try { $id = filterRequest('id') ?? ''; $password = filterRequest('password') ?? ''; $audience = filterRequest('aud') ?? ''; $allowed1 = getenv('allowedDriver1'); $allowed2 = getenv('allowedDriver2'); $allowedAudiences = array_values(array_filter([$allowed1, $allowed2])); if (empty($id) || empty($password) || empty($audience)) { jsonError('ID and password are required.', 400); } if (!in_array($audience, $allowedAudiences, true)) { jsonError('Invalid audience.', 400); } $con = Database::get('main'); // ── جلب بيانات المشرف ──────────────────────────────────── // ملاحظة: جدول admin_users سيتم إنشاؤه في Phase 4 (db_improvements.sql) $stmt = $con->prepare("SELECT id, password, email, role FROM admin_users WHERE username = :id OR email = :id LIMIT 1"); $stmt->execute([':id' => $id]); $admin = $stmt->fetch(); $startTime = microtime(true); if ($admin && password_verify($password, $admin['password'])) { $limiter->reset(RateLimiter::identifier(), 'login'); $jwtService = new JwtService($redis); // استخدام Role المخصص أو 'admin' $role = $admin['role'] ?? 'admin'; $jwt = $jwtService->generateAccessToken($admin['id'], $role, $audience); $refresh = $jwtService->generateRefreshToken($admin['id']); jsonSuccess([ 'jwt' => $jwt, 'refresh_token' => $refresh['token'], 'expires_in' => 900 ]); } else { // حماية من Timing Attack $elapsed = microtime(true) - $startTime; if ($elapsed < 0.1) usleep((int)((0.1 - $elapsed) * 1000000)); jsonError('Invalid ID or password.', 401); } } catch (PDOException $e) { securityLog("Admin Login PDO Error", ['msg' => $e->getMessage()]); jsonError('Login failed: Database error', 500); } catch (Exception $e) { securityLog("Admin Login Error", ['msg' => $e->getMessage()]); jsonError('Login failed: Server error', 500); } ``` ## File: schema_primary.sql ``` -- MySQL dump 10.13 Distrib 8.0.43, for Linux (x86_64) -- -- Host: localhost Database: intaleqDB1 -- ------------------------------------------------------ -- Server version 8.0.43-0ubuntu0.22.04.2 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `CarRegistration` -- DROP TABLE IF EXISTS `CarRegistration`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `CarRegistration` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `vin` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `car_plate` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `make` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `model` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `year` int NOT NULL, `expiration_date` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `color` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `owner` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `color_hex` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fuel` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `isDefault` tinyint(1) NOT NULL DEFAULT '0', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'yet', `vehicle_category_id` tinyint(1) DEFAULT '1', `fuel_type_id` tinyint DEFAULT '1', PRIMARY KEY (`id`), KEY `idx_driverID` (`driverID`) ) ENGINE=InnoDB AUTO_INCREMENT=1796 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `adminUser` -- DROP TABLE IF EXISTS `adminUser`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `adminUser` ( `id` int NOT NULL AUTO_INCREMENT, `device_number` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `api_keys` -- DROP TABLE IF EXISTS `api_keys`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `api_keys` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `hashed_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `blacklist_driver` -- DROP TABLE IF EXISTS `blacklist_driver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `blacklist_driver` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `phone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'Violation', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `canecl` -- DROP TABLE IF EXISTS `canecl`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `canecl` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(111) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(111) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideID` varchar(111) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `note` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'nothing', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `captains_car` -- DROP TABLE IF EXISTS `captains_car`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `captains_car` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `vin` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `car_plate` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `make` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `year` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `expiration_date` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `owner` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color_hex` char(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `displacement` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `fuel` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `registration_date` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `isDefault` tinyint(1) NOT NULL DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `car_plate` (`car_plate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `carPlateEdit` -- DROP TABLE IF EXISTS `carPlateEdit`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `carPlateEdit` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `carPlate` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `color` varchar(20) NOT NULL, `make` varchar(50) NOT NULL, `model` varchar(20) NOT NULL, `expiration_date` varchar(50) NOT NULL, `owner` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `year` int NOT NULL, `isEdit` tinyint(1) NOT NULL DEFAULT '0', `employee` varchar(30) NOT NULL DEFAULT 'any', `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `driverId` (`driverId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `car_locations` -- DROP TABLE IF EXISTS `car_locations`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `car_locations` ( `driver_id` varchar(100) NOT NULL, `latitude` decimal(10,7) NOT NULL, `longitude` decimal(10,7) NOT NULL, `heading` decimal(10,2) NOT NULL, `speed` double(10,3) NOT NULL, `distance` decimal(10,2) NOT NULL, `status` varchar(6) NOT NULL DEFAULT 'off', `carType` varchar(100) NOT NULL DEFAULT 'Awfar', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `location_point` point NOT NULL /*!80003 SRID 4326 */, PRIMARY KEY (`driver_id`), KEY `idx_loc_status_time` (`status`,`updated_at`,`latitude`,`longitude`), SPATIAL KEY `idx_location_point` (`location_point`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; /*!50003 SET character_set_client = utf8mb4 */ ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_0900_ai_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`siroUserDB1`@`%`*/ /*!50003 TRIGGER `trg_before_insert_car_locations` BEFORE INSERT ON `car_locations` FOR EACH ROW BEGIN SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; /*!50003 SET character_set_client = utf8mb4 */ ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_0900_ai_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`siroUserDB1`@`%`*/ /*!50003 TRIGGER `trg_before_update_car_locations` BEFORE UPDATE ON `car_locations` FOR EACH ROW BEGIN IF NEW.latitude <> OLD.latitude OR NEW.longitude <> OLD.longitude THEN SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); END IF; END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -- -- Table structure for table `car_tracks` -- DROP TABLE IF EXISTS `car_tracks`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `car_tracks` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(100) NOT NULL, `latitude` decimal(10,7) NOT NULL, `longitude` decimal(10,7) NOT NULL, `heading` float DEFAULT NULL, `speed` float DEFAULT NULL, `distance` float DEFAULT NULL, `status` enum('on','off') DEFAULT 'off', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10484 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `card_images` -- DROP TABLE IF EXISTS `card_images`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `card_images` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `image_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `upload_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `link` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `carsToWork` -- DROP TABLE IF EXISTS `carsToWork`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `carsToWork` ( `id` int NOT NULL AUTO_INCREMENT, `owner_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `car_number` varchar(77) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `manufacture_year` year DEFAULT NULL, `car_model` varchar(77) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `car_type` varchar(77) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `site` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `registration_date` date NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `complaint` -- DROP TABLE IF EXISTS `complaint`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `complaint` ( `id` int NOT NULL AUTO_INCREMENT, `ride_id` varchar(255) NOT NULL, `passenger_id` varchar(255) DEFAULT NULL, `driver_id` varchar(255) DEFAULT NULL, `complaint_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `description` text, `date_filed` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `statusComplaint` enum('Open','In Progress','Resolved') NOT NULL DEFAULT 'Open', `resolution` text, `passenger_report` text, `driver_report` text, `cs_solutions` text, `fault_determination` varchar(255) DEFAULT NULL, `complaint_nature` varchar(255) DEFAULT NULL, `date_resolved` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `contactEgypt` -- DROP TABLE IF EXISTS `contactEgypt`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `contactEgypt` ( `id` int NOT NULL AUTO_INCREMENT, `phones` varchar(20) NOT NULL, `name` varchar(100) NOT NULL, `phones2` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `contactSyria` -- DROP TABLE IF EXISTS `contactSyria`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `contactSyria` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(255) NOT NULL COMMENT 'معرّف السائق الذي قام بمزامنة جهة الاتصال', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'اسم جهة الاتصال', `phone` varchar(50) NOT NULL COMMENT 'رقم هاتف جهة الاتصال', `sync_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'وقت المزامنة', PRIMARY KEY (`id`), UNIQUE KEY `driver_contact_unique` (`driverId`,`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=83699 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `criminalDocuments` -- DROP TABLE IF EXISTS `criminalDocuments`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `criminalDocuments` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `IssueDate` varchar(20) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `InspectionResult` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `driverId` (`driverId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver` -- DROP TABLE IF EXISTS `driver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver` ( `idn` int NOT NULL AUTO_INCREMENT, `id` varchar(100) NOT NULL, `phone` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, `gender` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'Male', `license_type` varchar(255) DEFAULT NULL, `national_number` varchar(255) DEFAULT NULL, `name_arabic` varchar(255) DEFAULT NULL, `issue_date` date DEFAULT NULL, `expiry_date` date DEFAULT NULL, `license_categories` varchar(255) DEFAULT NULL, `address` text, `licenseIssueDate` varchar(50) DEFAULT NULL, `status` varchar(20) NOT NULL DEFAULT 'notDeleted', `birthdate` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `site` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `accountBank` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'yet', `bankCode` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'CIB', `employmentType` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `maritalStatus` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `fullNameMaritial` varchar(255) DEFAULT NULL, `expirationDate` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`idn`), UNIQUE KEY `national_number` (`national_number`) ) ENGINE=InnoDB AUTO_INCREMENT=2085 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driverToken` -- DROP TABLE IF EXISTS `driverToken`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driverToken` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `captain_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fingerPrint` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_captain_id` (`captain_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1460 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driverWallet` -- DROP TABLE IF EXISTS `driverWallet`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driverWallet` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `paymentID` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `amount` varchar(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `paymentMethod` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `dateUpdated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_behavior` -- DROP TABLE IF EXISTS `driver_behavior`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_behavior` ( `id` int NOT NULL, `driver_id` varchar(255) NOT NULL, `trip_id` varchar(255) NOT NULL, `max_speed` double DEFAULT '0', `avg_speed` double DEFAULT '0', `hard_brakes` int DEFAULT '0', `total_distance` double DEFAULT '0', `behavior_score` double DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_documents` -- DROP TABLE IF EXISTS `driver_documents`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_documents` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(64) NOT NULL, `doc_type` varchar(64) NOT NULL, `image_name` varchar(255) NOT NULL, `link` varchar(512) NOT NULL, `upload_date` datetime NOT NULL, PRIMARY KEY (`id`), KEY `driverID` (`driverID`) ) ENGINE=InnoDB AUTO_INCREMENT=5089 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_gifts` -- DROP TABLE IF EXISTS `driver_gifts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_gifts` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `gift_description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `gift_date` datetime DEFAULT CURRENT_TIMESTAMP, `is_claimed` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `driver_id` (`driver_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1377 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_health_assurance` -- DROP TABLE IF EXISTS `driver_health_assurance`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_health_assurance` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `assured` tinyint(1) DEFAULT '0', `date_created` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `health_insurance_provider` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `driver_id` (`driver_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_orders` -- DROP TABLE IF EXISTS `driver_orders`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_orders` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `order_id` varchar(99) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `notes` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'nothing', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'applied', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=286 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_ride_scam` -- DROP TABLE IF EXISTS `driver_ride_scam`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_ride_scam` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideID` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `isDriverCallPassenger` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driversWantWork` -- DROP TABLE IF EXISTS `driversWantWork`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driversWantWork` ( `id` int NOT NULL AUTO_INCREMENT, `driver_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(77) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `national_id` varchar(77) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `birth_date` varchar(77) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `license_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `site` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `national_id` (`national_id`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `email_verifications` -- DROP TABLE IF EXISTS `email_verifications`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `email_verifications` ( `id` int NOT NULL AUTO_INCREMENT, `email` varchar(255) NOT NULL, `token` varchar(255) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `verified` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `employee` -- DROP TABLE IF EXISTS `employee`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `employee` ( `id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `education` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `site` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `error` -- DROP TABLE IF EXISTS `error`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `error` ( `id` int NOT NULL AUTO_INCREMENT, `error` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userType` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `device` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `details` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'new', PRIMARY KEY (`id`), KEY `idx_error_created_at` (`created_at`), KEY `idx_error_phone` (`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=115339 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `feedBack` -- DROP TABLE IF EXISTS `feedBack`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `feedBack` ( `id` int NOT NULL AUTO_INCREMENT, `passengerId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `feedBack` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `datecreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `helpCenter` -- DROP TABLE IF EXISTS `helpCenter`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `helpCenter` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(89) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `helpQuestion` varchar(300) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `replay` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'not yet', `datecreated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=72 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `hotels` -- DROP TABLE IF EXISTS `hotels`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `hotels` ( `id` int NOT NULL, `nameEnglish` varchar(255) DEFAULT NULL, `nameArabic` varchar(255) DEFAULT NULL, `phone` varchar(20) DEFAULT NULL, `countReview` int DEFAULT NULL, `rate` float DEFAULT NULL, `stars` varchar(50) DEFAULT NULL, `address` text, `website` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `PlusCode` varchar(50) DEFAULT NULL, `closeTime` varchar(50) DEFAULT NULL, `latitude` decimal(10,6) DEFAULT NULL, `longitude` decimal(10,6) DEFAULT NULL, `instagram` varchar(255) DEFAULT NULL, `facebook` varchar(255) DEFAULT NULL, `linkedin` varchar(255) DEFAULT NULL, `twitter` varchar(255) DEFAULT NULL, `photo` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `imageProfileCaptain` -- DROP TABLE IF EXISTS `imageProfileCaptain`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `imageProfileCaptain` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `image_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `upload_date` datetime DEFAULT CURRENT_TIMESTAMP, `link` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=552 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invites` -- DROP TABLE IF EXISTS `invites`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invites` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `inviterDriverPhone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `inviteCode` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `isInstall` tinyint(1) NOT NULL DEFAULT '0', `isGiftToken` tinyint(1) NOT NULL DEFAULT '0', `expirationTime` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `inviterDriverId` (`inviterDriverPhone`), UNIQUE KEY `inviteCode` (`inviteCode`) ) ENGINE=InnoDB AUTO_INCREMENT=129 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invitesToPassengers` -- DROP TABLE IF EXISTS `invitesToPassengers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invitesToPassengers` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'yet', `inviterPassengerPhone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `inviteCode` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expirationTime` datetime NOT NULL, `createdAt` datetime DEFAULT CURRENT_TIMESTAMP, `isInstall` tinyint(1) DEFAULT '0', `isGiftToken` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `inviteCode` (`inviteCode`) ) ENGINE=InnoDB AUTO_INCREMENT=143 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invoice_records` -- DROP TABLE IF EXISTS `invoice_records`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invoice_records` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` int NOT NULL, `invoice_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `amount` decimal(10,2) DEFAULT NULL, `date` date DEFAULT NULL, `image_link` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `created_at` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invoicesAdmin` -- DROP TABLE IF EXISTS `invoicesAdmin`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invoicesAdmin` ( `id` int NOT NULL AUTO_INCREMENT, `item_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `amount` decimal(10,2) NOT NULL, `image_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `kazan` -- DROP TABLE IF EXISTS `kazan`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `kazan` ( `id` int NOT NULL AUTO_INCREMENT, `country` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `kazan` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `comfortPrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `speedPrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `familyPrice` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `deliveryPrice` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `freePrice` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `latePrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `heavyPrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `adminId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `naturePrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fuelPrice` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `lisenceDetails` -- DROP TABLE IF EXISTS `lisenceDetails`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `lisenceDetails` ( `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `driverID` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `licenseClass` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `documentNo` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `height` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `postalCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `stateCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `expireDate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `dateOfBirth` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `documentNo` (`documentNo`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `login_attempts` -- DROP TABLE IF EXISTS `login_attempts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `login_attempts` ( `id` int NOT NULL AUTO_INCREMENT, `ip_address` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `attempt_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `login_attempts_drivers` -- DROP TABLE IF EXISTS `login_attempts_drivers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `login_attempts_drivers` ( `id` int NOT NULL AUTO_INCREMENT, `ip_address` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `attempt_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `mishwaritrips` -- DROP TABLE IF EXISTS `mishwaritrips`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `mishwaritrips` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `gender` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name_english` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `religion` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `age` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `startNameAddress` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none', `locationCoordinate` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none', `education` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `license_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `national_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `car_plate` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `make` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color_hex` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `rating` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `countRide` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `passengerId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `timeSelected` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'pending', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notesForDriverService` -- DROP TABLE IF EXISTS `notesForDriverService`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notesForDriverService` ( `id` int NOT NULL AUTO_INCREMENT, `phone` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `note` varchar(250) NOT NULL, `editor` varchar(50) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=1814 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notesForPassengerService` -- DROP TABLE IF EXISTS `notesForPassengerService`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notesForPassengerService` ( `id` int NOT NULL AUTO_INCREMENT, `phone` int NOT NULL, `note` varchar(250) NOT NULL, `editor` varchar(50) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notificationCaptain` -- DROP TABLE IF EXISTS `notificationCaptain`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notificationCaptain` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `title` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `body` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `isShown` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'false', `isPin` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'unPin', `dateCreated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notifications` -- DROP TABLE IF EXISTS `notifications`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notifications` ( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(111) NOT NULL, `body` varchar(265) NOT NULL, `passenger_id` varchar(111) NOT NULL, `isShown` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'false', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `otp_verification_fingerPrint` -- DROP TABLE IF EXISTS `otp_verification_fingerPrint`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `otp_verification_fingerPrint` ( `id` int NOT NULL, `phone` varchar(20) NOT NULL, `otp` varchar(6) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `packageInfo` -- DROP TABLE IF EXISTS `packageInfo`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `packageInfo` ( `id` int NOT NULL AUTO_INCREMENT, `platform` varchar(50) NOT NULL, `appName` varchar(20) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `version` varchar(10) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `palces11` -- DROP TABLE IF EXISTS `palces11`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `palces11` ( `id` int NOT NULL AUTO_INCREMENT, `latitude` varchar(50) NOT NULL, `longitude` varchar(50) NOT NULL, `name` varchar(180) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `name_ar` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `name_en` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `address` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `category` varchar(55) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `location` point DEFAULT NULL, PRIMARY KEY (`id`), FULLTEXT KEY `idx_fulltext_search` (`name`,`name_ar`,`name_en`,`address`,`category`) ) ENGINE=InnoDB AUTO_INCREMENT=37946 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passengerWallet` -- DROP TABLE IF EXISTS `passengerWallet`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passengerWallet` ( `id` int NOT NULL AUTO_INCREMENT, `passenger_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `balance` decimal(10,2) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `passenger_id` (`passenger_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passenger_blacklist` -- DROP TABLE IF EXISTS `passenger_blacklist`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passenger_blacklist` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `phone` varchar(150) NOT NULL, `phone_normalized` varchar(64) NOT NULL, `reason` varchar(255) DEFAULT NULL, `expires_at` datetime DEFAULT CURRENT_TIMESTAMP, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uq_phone_norm` (`phone_normalized`), KEY `idx_expires` (`expires_at`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passengerlocation` -- DROP TABLE IF EXISTS `passengerlocation`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passengerlocation` ( `id` int NOT NULL AUTO_INCREMENT, `passengerId` varchar(60) NOT NULL, `lat` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `lng` varchar(20) NOT NULL, `rideId` varchar(10) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=725 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passengers` -- DROP TABLE IF EXISTS `passengers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passengers` ( `id` varchar(100) NOT NULL, `phone` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(100) NOT NULL, `gender` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `status` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'notDeleted', `birthdate` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `site` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `sosPhone` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'sos', `education` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'none', `employmentType` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'none', `maritalStatus` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'none', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`,`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `payment_tokens` -- DROP TABLE IF EXISTS `payment_tokens`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `payment_tokens` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(255) NOT NULL, `driverID` varchar(255) NOT NULL, `dateCreated` datetime NOT NULL, `amount` decimal(10,2) NOT NULL, `isUsed` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `payment_tokens_passenger` -- DROP TABLE IF EXISTS `payment_tokens_passenger`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `payment_tokens_passenger` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(255) NOT NULL, `passengerId` varchar(255) NOT NULL, `dateCreated` datetime NOT NULL, `amount` decimal(10,2) NOT NULL, `isUsed` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `payments` -- DROP TABLE IF EXISTS `payments`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `payments` ( `id` varchar(111) NOT NULL, `amount` decimal(10,2) NOT NULL, `payment_method` varchar(255) NOT NULL, `passengerID` varchar(100) NOT NULL, `rideId` varchar(100) NOT NULL, `driverID` varchar(100) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `isGiven` varchar(20) NOT NULL DEFAULT 'waiting', PRIMARY KEY (`id`), UNIQUE KEY `rideId` (`rideId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `paymentsDriverPoints` -- DROP TABLE IF EXISTS `paymentsDriverPoints`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `paymentsDriverPoints` ( `id` int NOT NULL AUTO_INCREMENT, `amount` decimal(10,2) NOT NULL, `payment_method` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `driverID` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` datetime DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `phone_verification` -- DROP TABLE IF EXISTS `phone_verification`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `phone_verification` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `driverId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'yet', `email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'yet', `token_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `expiration_time` datetime DEFAULT NULL, `is_verified` tinyint(1) DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10531 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `phone_verification_passenger` -- DROP TABLE IF EXISTS `phone_verification_passenger`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `phone_verification_passenger` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `token` varchar(255) DEFAULT NULL, `expiration_time` varchar(255) DEFAULT NULL, `verified` tinyint(1) DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(22) NOT NULL DEFAULT 'yet', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7304 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `places` -- DROP TABLE IF EXISTS `places`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `places` ( `id` int NOT NULL AUTO_INCREMENT, `latitude` double NOT NULL, `longitude` double NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `name_ar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=70783 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `placesEgypt` -- DROP TABLE IF EXISTS `placesEgypt`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `placesEgypt` ( `id` int NOT NULL, `nameEnglish` varchar(255) DEFAULT NULL, `nameArabic` varchar(255) DEFAULT NULL, `phone` varchar(20) DEFAULT NULL, `countReview` int DEFAULT NULL, `rate` float DEFAULT NULL, `stars` varchar(50) DEFAULT NULL, `address` text, `website` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `PlusCode` varchar(50) DEFAULT NULL, `closeTime` varchar(50) DEFAULT NULL, `latitude` decimal(10,6) DEFAULT NULL, `longitude` decimal(10,6) DEFAULT NULL, `instagram` varchar(255) DEFAULT NULL, `facebook` varchar(255) DEFAULT NULL, `linkedin` varchar(255) DEFAULT NULL, `twitter` varchar(255) DEFAULT NULL, `photo` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `promos` -- DROP TABLE IF EXISTS `promos`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `promos` ( `id` int NOT NULL AUTO_INCREMENT, `promo_code` varchar(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `amount` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0', `description` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `passengerID` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none', `validity_start_date` date DEFAULT NULL, `validity_end_date` date DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `passengerID` (`passengerID`) ) ENGINE=InnoDB AUTO_INCREMENT=637 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `promptDriverIDEgypt` -- DROP TABLE IF EXISTS `promptDriverIDEgypt`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `promptDriverIDEgypt` ( `id` int NOT NULL AUTO_INCREMENT, `type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `prompt` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ratingApp` -- DROP TABLE IF EXISTS `ratingApp`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ratingApp` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `email` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userType` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rating` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `comment` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=118 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ratingDriver` -- DROP TABLE IF EXISTS `ratingDriver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ratingDriver` ( `id` int NOT NULL AUTO_INCREMENT, `passenger_id` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `driver_id` varchar(33) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `ride_id` int DEFAULT NULL, `rating` float DEFAULT NULL, `comment` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `ride_id` (`ride_id`), KEY `idx_driver_id` (`driver_id`) ) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ratingPassenger` -- DROP TABLE IF EXISTS `ratingPassenger`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ratingPassenger` ( `id` int NOT NULL AUTO_INCREMENT, `passenger_id` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideId` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rating` float NOT NULL, `comment` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `rideId` (`rideId`) ) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ride` -- DROP TABLE IF EXISTS `ride`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ride` ( `id` int NOT NULL AUTO_INCREMENT, `start_location` varchar(255) NOT NULL, `end_location` varchar(255) NOT NULL, `date` date NOT NULL, `time` time NOT NULL, `endtime` time NOT NULL, `price` decimal(10,2) NOT NULL DEFAULT '0.00', `passenger_id` varchar(111) NOT NULL, `driver_id` varchar(111) NOT NULL, `status` varchar(200) NOT NULL DEFAULT 'nothing', `paymentMethod` varchar(20) NOT NULL DEFAULT 'Cash', `carType` varchar(20) NOT NULL DEFAULT 'Speed', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `DriverIsGoingToPassenger` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `rideTimeStart` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `rideTimeFinish` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `price_for_driver` decimal(10,2) NOT NULL DEFAULT '0.00', `price_for_passenger` decimal(10,2) NOT NULL DEFAULT '0.00', `distance` float DEFAULT '0', PRIMARY KEY (`id`), KEY `passengerfk` (`passenger_id`), KEY `driverfk` (`driver_id`) ) ENGINE=InnoDB AUTO_INCREMENT=831 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `seferWallet` -- DROP TABLE IF EXISTS `seferWallet`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `seferWallet` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(100) NOT NULL, `passengerId` varchar(100) NOT NULL, `amount` varchar(10) NOT NULL, `paymentMethod` varchar(50) NOT NULL, `token` varchar(100) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `server_locations` -- DROP TABLE IF EXISTS `server_locations`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `server_locations` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `min_latitude` decimal(10,6) NOT NULL, `max_latitude` decimal(10,6) NOT NULL, `min_longitude` decimal(10,6) NOT NULL, `max_longitude` decimal(10,6) NOT NULL, `server_link` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `smsSender` -- DROP TABLE IF EXISTS `smsSender`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `smsSender` ( `id` int NOT NULL AUTO_INCREMENT, `senderId` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `test` -- DROP TABLE IF EXISTS `test`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `test` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `testApp` -- DROP TABLE IF EXISTS `testApp`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `testApp` ( `id` int NOT NULL AUTO_INCREMENT, `isTest` tinyint(1) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `appPlatform` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `tips` -- DROP TABLE IF EXISTS `tips`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `tips` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `tipAmount` decimal(10,2) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `token_verification` -- DROP TABLE IF EXISTS `token_verification`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `token_verification` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expiration_time` datetime NOT NULL, `verified` tinyint(1) DEFAULT '0', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=88 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `token_verification_admin` -- DROP TABLE IF EXISTS `token_verification_admin`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `token_verification_admin` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `token` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expiration_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `phone_number` (`phone_number`) ) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `token_verification_driver` -- DROP TABLE IF EXISTS `token_verification_driver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `token_verification_driver` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expiration_time` datetime NOT NULL, `verified` tinyint(1) NOT NULL DEFAULT '0', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2210 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `tokens` -- DROP TABLE IF EXISTS `tokens`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `tokens` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(333) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fingerPrint` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `status` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'yet', PRIMARY KEY (`id`), UNIQUE KEY `passengerID` (`passengerID`) ) ENGINE=InnoDB AUTO_INCREMENT=2604 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `users` -- DROP TABLE IF EXISTS `users`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `users` ( `id` varchar(111) NOT NULL, `phone` varchar(15) NOT NULL, `email` varchar(255) NOT NULL, `gender` varchar(10) NOT NULL, `password` varchar(100) NOT NULL, `birthdate` date NOT NULL, `site` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_type` varchar(44) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `vehicles` -- DROP TABLE IF EXISTS `vehicles`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `vehicles` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) NOT NULL, `make` varchar(255) NOT NULL, `model` varchar(255) NOT NULL, `license_plate` varchar(255) NOT NULL, `seats` int NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `license_plate` (`license_plate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `videos` -- DROP TABLE IF EXISTS `videos`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `videos` ( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `description` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `url` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `waitingRides` -- DROP TABLE IF EXISTS `waitingRides`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `waitingRides` ( `id` varchar(100) NOT NULL, `start_location` varchar(255) NOT NULL, `start_lat` decimal(10,7) DEFAULT NULL, `start_lng` decimal(10,7) DEFAULT NULL, `end_location` varchar(255) NOT NULL, `end_lat` decimal(10,7) DEFAULT NULL, `end_lng` decimal(10,7) DEFAULT NULL, `date` date NOT NULL, `time` time NOT NULL, `price` decimal(10,2) NOT NULL DEFAULT '0.00', `passenger_id` varchar(111) NOT NULL, `status` varchar(200) NOT NULL DEFAULT 'nothing', `carType` varchar(19) NOT NULL, `passengerRate` decimal(10,2) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `price_for_passenger` decimal(10,2) NOT NULL DEFAULT '0.00', `distance` varchar(255) NOT NULL, `duration` varchar(10) NOT NULL DEFAULT '0', `payment_method` varchar(10) NOT NULL DEFAULT 'cash', `passenger_wallet` varchar(6) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `idx_location_status` (`start_lat`,`start_lng`,`status`,`created_at`), KEY `idx_status_created` (`status`,`created_at`), KEY `idx_passenger` (`passenger_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `welcomeDriverCall` -- DROP TABLE IF EXISTS `welcomeDriverCall`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `welcomeDriverCall` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `isCall` tinyint(1) NOT NULL DEFAULT '0', `notes` varchar(255) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1648 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `write_argument_after_applied_from_background` -- DROP TABLE IF EXISTS `write_argument_after_applied_from_background`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `write_argument_after_applied_from_background` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `ride_id` varchar(50) NOT NULL, `driver_id` varchar(50) NOT NULL, `passenger_id` varchar(50) NOT NULL, `passenger_location` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `passenger_destination` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `duration` varchar(255) NOT NULL, `duration_to_passenger` varchar(255) NOT NULL, `duration_of_ride` varchar(255) NOT NULL, `distance` varchar(255) NOT NULL, `total_cost` varchar(255) NOT NULL, `payment_amount` varchar(255) NOT NULL, `payment_method` enum('visa','cash') NOT NULL, `wallet_checked` varchar(255) NOT NULL, `has_steps` varchar(255) NOT NULL, `step0` varchar(255) DEFAULT NULL, `step1` varchar(255) DEFAULT NULL, `step2` varchar(255) DEFAULT NULL, `step3` varchar(255) DEFAULT NULL, `step4` varchar(255) DEFAULT NULL, `passenger_wallet_burc` varchar(33) NOT NULL, `token_passenger` varchar(255) NOT NULL, `name` varchar(100) NOT NULL, `phone` varchar(20) NOT NULL, `email` varchar(150) NOT NULL, `start_name_location` varchar(255) NOT NULL, `end_name_location` varchar(255) NOT NULL, `car_type` varchar(50) NOT NULL, `kazan` varchar(255) NOT NULL, `direction_url` text NOT NULL, `time_of_order` datetime NOT NULL, `total_passenger` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping events for database 'intaleqDB1' -- -- -- Dumping routines for database 'intaleqDB1' -- /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2026-04-22 19:40:54 ``` ## File: login.php ``` enforce(RateLimiter::identifier(), 'login'); $passengerId = filterRequest('id'); $fingerprint = filterRequest('fingerPrint') ?? filterRequest('fingerprint'); $audience = filterRequest('aud'); if (empty($passengerId) || empty($fingerprint) || empty($audience)) { jsonError('Missing required parameters', 400); } $con = Database::get('main'); // التحقق من الجهاز من خلال البصمة $stmt = $con->prepare(' SELECT passengerID, fingerprint FROM tokens WHERE passengerID = :pid LIMIT 1 '); $stmt->execute([':pid' => $passengerId]); $row = $stmt->fetch(); $fpVerified = false; if ($row) { $fpPepper = getenv('FP_PEPPER') ?: ''; $storedFp = $row['fingerprint']; // دعم الطريقة الجديدة (hash) والقديمة (مباشر) if ($fpPepper) { $expectedHash = hash('sha256', $fingerprint . $fpPepper); $fpVerified = hash_equals($storedFp, $expectedHash); if (!$fpVerified) { $fpVerified = hash_equals($storedFp, $fingerprint); } } else { $fpVerified = hash_equals($storedFp, $fingerprint); } } // وقت رد ثابت لمنع Timing Attack $elapsed = microtime(true) - $startTime; if ($elapsed < 0.1) usleep((int)((0.1 - $elapsed) * 1000000)); if (!$fpVerified) { securityLog("Invalid login fingerprint", ['passengerId' => $passengerId]); jsonError('Invalid credentials', 401); } $limiter->reset(RateLimiter::identifier(), 'login'); $jwtService = new JwtService($redis); $jwt = $jwtService->generateAccessToken($passengerId, 'passenger', $audience, $fingerprint); $refresh = $jwtService->generateRefreshToken($passengerId); jsonSuccess([ 'jwt' => $jwt, 'refresh_token' => $refresh['token'], 'expires_in' => 900 ]); } catch (PDOException $e) { securityLog("Login PDO Error", ['msg' => $e->getMessage()]); jsonError('Database error', 500); } catch (Exception $e) { securityLog("Login Error", ['msg' => $e->getMessage()]); jsonError('Server error', 500); } ``` ## File: privacy_policy1.php ``` سياسة الخصوصية وشروط الخدمة – Siro Driver

سياسة الخصوصية وشروط الخدمة – تطبيق Siro Driver

آخر تحديث: 14-08-2025

المشغّل/المتحكم بالبيانات: سيرو لنقل الركاب

البريد للتواصل: support@intaleqapp.com

إفصاح بارز عن البيانات الحساسة – الموقع الجغرافي

يجمع تطبيق Siro Driver بيانات الموقع الدقيقة من جهاز السائق أثناء فتح التطبيق وأيضًا أثناء عمله في الخلفية/وعند إغلاقه، لغايات إسناد الرحلات القريبة، وتتبع الرحلة حيًا، واحتساب المسافة والأجرة بدقة.

يمكنك إدارة إذن الموقع من إعدادات النظام. تعطيل الإذن سيمنع الوظائف الأساسية للتطبيق.

1) الفئات الكاملة للبيانات التي نجمعها

أ. بيانات يقدّمها السائق

  • هوية: الاسم الكامل، رقم الهاتف، صورة الملف.
  • مركبة: النوع/الطراز، رقم اللوحة، صور المركبة.
  • وثائق قانونية: رخصة القيادة، رخصة المركبة، وأي مستندات مطلوبة للامتثال.
  • إعدادات الحساب والتفضيلات.

ب. بيانات تُجمع تلقائيًا

  • الموقع: دقيق/تقريبي، في الواجهة والخلفية كما ورد أعلاه.
  • بيانات الرحلات والاستخدام: سجل الرحلات، نقاط الانطلاق/الوصول، المدد والمسافات، التقييمات.
  • بيانات الجهاز والمعرّفات: طراز الجهاز، نظام التشغيل، معرّفات إشعارات (FCM token)، عنوان IP، سجلات الأداء والأعطال.
  • بيانات الدفع والعوائد (إن وُجدت): المبالغ المستحقة، سجلات السحب/التسوية.

2) الأغراض القانونية لاستخدام البيانات

الأساس القانوني: تنفيذ العقد، المصلحة المشروعة (السلامة/منع الاحتيال/التحسين)، والموافقة للأذونات الحساسة مثل الموقع في الخلفية.

3) المشاركة والجهات المتلقّية

لا نبيع بياناتك الشخصية. وأي مشاركة مقيّدة باتفاقيات ومعايير أمان مناسبة.

4) الاحتفاظ بالبيانات

5) أمان المعلومات

لا توجد وسيلة نقل/تخزين إلكترونية آمنة تمامًا، لكننا نطبّق أفضل الممارسات المناسبة للخدمة.

6) القاصرون

خدمتنا موجّهة للسائقين البالغين قانونيًا فقط. لا نستهدف القاصرين ولا نجمع عن علم بيانات لمن هم دون السن القانوني المناسب لسوقنا. إن علمنا بذلك سنحذف البيانات ونعطّل الحساب.

7) حقوقك

لممارسة أي من هذه الحقوق أو لتقديم شكوى، تواصل معنا عبر: support@intaleqapp.com.

8) النقل الدولي للبيانات

قد تُعالَج البيانات على خوادم/مزودين خارج بلدك. نتخذ تدابير تعاقدية وفنية مع شركائنا لضمان مستوى حماية مناسب.

9) ملفات تعريف الارتباط (Cookies) والمواقع

قد يستخدم موقعنا الإلكتروني كوكيز ضرورية للتشغيل و/أو تحليلات أساسية. يمكنك التحكم بها عبر إعدادات المتصفح. تطبيق الهاتف لا يعتمد على كوكيز، لكنه قد يستخدم معرّفات أجهزة لأغراض إشعارات/تحليلات.

10) أذونات أخرى قد يطلبها التطبيق

11) إدارة الأذونات

على Android: الإعدادات > التطبيقات > Siro Driver > الأذونات (الموقع/الكاميرا/الصور/الإشعارات…). تعطيل بعض الأذونات قد يوقف الميزات الأساسية كاستلام الطلبات.

12) التعديلات على هذه السياسة

قد نحدّث هذه السياسة من وقت لآخر. سنغيّر تاريخ "آخر تحديث" أعلاه، وقد نرسل إشعارًا داخل التطبيق عند التغييرات الجوهرية.

13) حذف الحساب والتواصل

يمكنك طلب حذف حسابك وبياناتك عبر البريد: support@intaleqapp.com. نعالج الطلب خلال 30 يومًا ما لم تمنعنا متطلبات قانونية من ذلك.


Privacy Policy (English)

Last Updated: 14 Aug 2025 – Data Controller: Siro for Passenger Transport – Contact: support@intaleqapp.com

Prominent Disclosure – Location

The Siro Driver app collects precise location data while the app is in the foreground and also in the background/when closed, to dispatch nearby jobs, enable live trip tracking, and accurately compute distance and fares.

Permissions can be managed in system settings; disabling location prevents core functionality.

Data We Collect

Purposes & Legal Bases

Sharing

Retention

Security

TLS in transit, restricted access, audit logs, and reasonable technical/organizational measures.

Minors

Service is intended for legally adult drivers only. We do not knowingly collect data from minors; if identified, we will delete data and disable the account.

Your Rights

International Transfers

Data may be processed on servers/providers outside your country; we use contractual and technical safeguards with partners.

Cookies & Websites

Our website may use essential/analytics cookies; you can control them in your browser. The mobile app uses device identifiers instead of cookies.

Other Permissions

Push notifications; camera/photos for document/vehicle images; storage for saving/reading such images.

Changes

We may update this policy and will adjust the “Last Updated” date; material changes may be notified in-app.

Account Deletion & Contact

Email us at support@intaleqapp.com. We aim to fulfill deletion requests within 30 days unless legal obligations prevent immediate deletion.


شروط الخدمة المختصرة

``` ## File: migrate_driver_passwords.php ``` false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8", ]; $pdo = new PDO($dsn, $dbUser, $dbPass, $options); // نجلب الحقول التي نحتاجها لبناء السر $sql = "SELECT id, phone, birthdate, national_number FROM driver"; $stmt = $pdo->query($sql); $update = $pdo->prepare("UPDATE driver SET password = :pwd WHERE id = :id"); $count = 0; $skipped = 0; $startTime = microtime(true); while ($row = $stmt->fetch()) { $id = $row['id']; $encPhone = $row['phone']; $encBirth = $row['birthdate'] ?? null; $encNat = $row['national_number'] ?? null; // نفك التشفير – قد يرجع null لو الحقل فاضي $phone = $encPhone ? $encryptionHelper->decryptData($encPhone) : null; $birth = $encBirth ? $encryptionHelper->decryptData($encBirth) : null; $nat = $encNat ? $encryptionHelper->decryptData($encNat) : null; if (empty($id) || empty($phone)) { // لو ناقصين، نتجاوز السطر مع تسجيل في اللوج error_log("[MIGRATE] Skip driver id={$id}: missing phone or id."); $skipped++; continue; } // في الوضع المثالي عندك nat + birthdate لكل السائقين // لو حاب تجبرهم يكونوا موجودين: /* if (empty($nat) || empty($birth)) { error_log("[MIGRATE] Skip driver id={$id}: missing nat or birthdate."); $skipped++; continue; } */ // phone مفروض يكون أصلاً مطبّع (9639...) من سكربت التسجيل $normalizedPhone = trim($phone); // نبني baseString: الأساس id + phone $parts = [$id, $normalizedPhone]; // نضيف رقم وطني أو سنة الميلاد (حسب الموجود) if (!empty($nat)) { $parts[] = trim($nat); } elseif (!empty($birth)) { // birthdate متوقعة بصيغة YYYY-01-01 -> نأخذ السنة فقط $year = substr($birth, 0, 4); if (preg_match('/^\d{4}$/', $year)) { $parts[] = $year; } } $baseString = implode('|', $parts); // اشتقاق السر النهائي (HEX string، بدون باينري) $hmacHex = hash_hmac('sha256', $baseString, $pepper, false); // نخزن فقط الهاش باستخدام password_hash $pwdHash = password_hash($hmacHex, PASSWORD_DEFAULT); $update->execute([ ':pwd' => $pwdHash, ':id' => $id, ]); $count++; // لوج بسيط كل 100 سائق if ($count % 100 === 0) { $elapsed = round(microtime(true) - $startTime, 2); error_log("[MIGRATE] Progress: updated {$count} drivers, skipped {$skipped}, elapsed {$elapsed}s"); } } $totalTime = round(microtime(true) - $startTime, 2); error_log("[MIGRATE] Done. Updated {$count} driver passwords, skipped {$skipped}. Total time: {$totalTime}s"); echo "Migration finished. Updated {$count} drivers, skipped {$skipped}. Time: {$totalTime}s\n"; } catch (PDOException $e) { error_log("[MIGRATE][PDO] " . $e->getMessage()); echo "Migration failed (DB error).\n"; exit(1); } catch (Exception $e) { error_log("[MIGRATE][GENERAL] " . $e->getMessage()); echo "Migration failed (general error).\n"; exit(1); } ``` ## File: loginJwtWalletDriver.php ``` enforce(RateLimiter::identifier(), 'login'); $id = filterRequest('id'); $password = filterRequest('password'); $audience = filterRequest('aud'); $fingerPrint = filterRequest('fingerPrint') ?? filterRequest('fingerprint'); $allowed1 = getenv('allowedWallet1'); $allowed2 = getenv('allowedWallet2'); $allowedAudiences = array_values(array_filter([$allowed1, $allowed2])); $passwordnewpassenger = getenv('passwordnewpassenger'); $fpPepper = getenv('FP_PEPPER') ?: ''; if (empty($id) || empty($password) || empty($audience) || empty($fingerPrint)) { jsonError('Missing required parameters', 400); } if (!in_array($audience, $allowedAudiences, true)) { jsonError('Invalid audience', 400); } if (!password_verify($password, $passwordnewpassenger)) { securityLog("WalletDriver login failed (password)", ['id' => $id]); jsonError('Invalid credentials', 401); } $con = Database::get('main'); $stmt = $con->prepare(' SELECT captain_id, fingerPrint FROM driverToken WHERE captain_id = :captain_id LIMIT 1 '); $stmt->execute([':captain_id' => $id]); $tokenData = $stmt->fetch(); $storedFp = $tokenData['fingerPrint'] ?? ''; if (empty($storedFp)) { jsonError('Device fingerprint not registered', 403); } $fpVerified = false; if (!empty($fpPepper)) { $expectedHash = hash('sha256', $fingerPrint . $fpPepper); $fpVerified = hash_equals($storedFp, $expectedHash); if (!$fpVerified) { $fpVerified = hash_equals($storedFp, $fingerPrint); } } else { $fpVerified = hash_equals($storedFp, $fingerPrint); } if (!$fpVerified) { securityLog("WalletDriver FP mismatch", ['id' => $id]); jsonError('Device verification failed', 403); } $limiter->reset(RateLimiter::identifier(), 'login'); $fpHash = hash('sha256', $fingerPrint . $fpPepper); $payload = [ 'user_id' => $id, 'fingerPrint' => $fpHash, 'exp' => time() + 300, // 5 دقائق تم إصلاحه (كان 60) 'iat' => time(), 'iss' => 'Tripz-Wallet', 'aud' => $audience, 'jti' => bin2hex(random_bytes(16)), ]; $secretKey = trim(file_get_contents('/home/siro-api/.secret_key_pay')); $jwt = Firebase\JWT\JWT::encode($payload, $secretKey, 'HS256'); $hmac = hash_hmac('sha256', $id, getenv('SECRET_KEY_HMAC')); jsonSuccess([ 'status' => 'success', 'jwt' => $jwt, 'hmac' => $hmac, 'expires_in' => 300, // تم التعديل ]); } catch (PDOException $e) { securityLog("LoginWalletDriver PDO Error", ['msg' => $e->getMessage()]); jsonError('Database error', 500); } catch (Exception $e) { securityLog("LoginWalletDriver Error", ['msg' => $e->getMessage()]); jsonError('Server error', 500); } ``` ## File: loginFirstTimeDriver.php ``` enforce(RateLimiter::identifier(), 'register'); $id = filterRequest('id'); $password = filterRequest('password'); $audience = filterRequest('aud'); $fingerprint = filterRequest('fingerprint') ?? filterRequest('fingerPrint'); $allowed1 = getenv('allowedDriver1'); $allowed2 = getenv('allowedDriver2'); $allowedAudiences = array_values(array_filter([$allowed1, $allowed2])); $passwordnewpassenger = getenv('passwordnewpassenger'); if (empty($id) || empty($password) || empty($audience)) { jsonError('Missing input fields.', 400); } if (!in_array($audience, $allowedAudiences, true)) { jsonError('Invalid audience', 400); } if (!password_verify($password, $passwordnewpassenger)) { securityLog("FirstTimeDriver login failed (password)", ['id' => $id]); jsonError('Invalid credentials.', 401); } $fpPepper = getenv('FP_PEPPER') ?: ''; $fpHash = (!empty($fingerprint) && !empty($fpPepper)) ? hash('sha256', $fingerprint . $fpPepper) : null; $payload = [ 'user_id' => 'new', 'sub' => $id, 'token_type' => 'registration', 'exp' => time() + 450, 'iat' => time(), 'iss' => 'Tripz', 'aud' => $audience, 'jti' => bin2hex(random_bytes(16)), ]; if ($fpHash !== null) { $payload['fingerPrint'] = $fpHash; } $secretKey = trim(file_get_contents('/home/siro-api/.secret_key')); $jwt = Firebase\JWT\JWT::encode($payload, $secretKey, 'HS256'); jsonSuccess([ 'jwt' => $jwt, 'expires_in' => 450, ]); } catch (Exception $e) { securityLog("LoginFirstTimeDriver Error", ['msg' => $e->getMessage()]); jsonError('Server error', 500); } ``` ## File: loginWallet.php ``` enforce(RateLimiter::identifier(), 'login'); $id = filterRequest('id'); $password = filterRequest('password'); $audience = filterRequest('aud'); $fingerPrint = filterRequest('fingerPrint') ?? filterRequest('fingerprint'); $allowed1 = getenv('allowed1'); $allowed2 = getenv('allowed2'); $allowedAudiences = array_values(array_filter([$allowed1, $allowed2])); $passwordnewpassenger = getenv('passwordnewpassenger'); if (empty($id) || empty($password) || empty($audience) || empty($fingerPrint)) { jsonError('Missing required parameters', 400); } if (!in_array($audience, $allowedAudiences, true)) { jsonError('Invalid audience', 400); } if (!password_verify($password, $passwordnewpassenger)) { securityLog("Wallet login failed (password)", ['id' => $id]); jsonError('Invalid credentials', 401); } $con = Database::get('main'); $stmt = $con->prepare(' SELECT passengerID, fingerPrint FROM tokens WHERE passengerID = :pid LIMIT 1 '); $stmt->execute([':pid' => $id]); $tokenData = $stmt->fetch(); if (!$tokenData || !hash_equals($tokenData['fingerPrint'], $fingerPrint)) { securityLog("Wallet FP mismatch", ['id' => $id]); jsonError('Device verification failed', 403); } $limiter->reset(RateLimiter::identifier(), 'login'); $jwtService = new JwtService($redis); $fpPepper = getenv('FP_PEPPER') ?: ''; $fpHash = hash('sha256', $fingerPrint . $fpPepper); $payload = [ 'user_id' => $id, 'sub' => $id, 'fingerPrint' => $fpHash, 'exp' => time() + 300, // 5 دقائق تم إصلاحه 'iat' => time(), 'iss' => 'Tripz-Wallet', 'aud' => $audience, 'jti' => bin2hex(random_bytes(16)), ]; $secretKey = trim(file_get_contents('/home/siro-api/.secret_key')); $jwt = Firebase\JWT\JWT::encode($payload, $secretKey, 'HS256'); $hmac = hash_hmac('sha256', $id, getenv('SECRET_KEY_HMAC')); jsonSuccess([ 'jwt' => $jwt, 'hmac' => $hmac, 'expires_in' => 300, ]); } catch (PDOException $e) { securityLog("LoginWallet PDO Error", ['msg' => $e->getMessage()]); jsonError('Database error', 500); } catch (Exception $e) { securityLog("LoginWallet Error", ['msg' => $e->getMessage()]); jsonError('Server error', 500); } ``` ## File: logout.php ``` authenticate(); $jti = $decoded->jti ?? null; $exp = $decoded->exp ?? 0; $remaining = $exp - time(); if ($jti && $remaining > 0) { $jwtService->revokeToken($jti, $remaining); securityLog("User logged out and token revoked", ['user_id' => $decoded->user_id, 'jti' => $jti]); } jsonSuccess(null, "Logged out successfully"); } catch (Exception $e) { jsonError("Logout failed", 500); } ``` ## File: load_env.php ``` enforce(RateLimiter::identifier(), 'api'); // 2. JWT Authentication $jwtService = new JwtService($redis); $decoded = $jwtService->authenticate(); // متغيرات مساعدة للمطور $user_id = $decoded->user_id ?? null; $role = $decoded->role ?? 'passenger'; // 3. Database Connection try { $con = Database::get('main'); } catch (Exception $e) { http_response_code(500); exit(json_encode(['error' => 'Database connection failed'])); } ``` ## File: loginFirstTime.php ``` enforce(RateLimiter::identifier(), 'register'); $id = filterRequest('id'); $password = filterRequest('password'); $audience = filterRequest('aud'); $fingerprint = filterRequest('fingerprint') ?? filterRequest('fingerPrint'); $allowed1 = getenv('allowed1'); $allowed2 = getenv('allowed2'); $allowedAudiences = array_values(array_filter([$allowed1, $allowed2])); $passwordnewpassenger = getenv('passwordnewpassenger'); if (empty($id) || empty($password) || empty($audience)) { jsonError('Missing input fields.', 400); } if (!in_array($audience, $allowedAudiences, true)) { jsonError('Invalid audience', 400); } if (!password_verify($password, $passwordnewpassenger)) { securityLog("FirstTime login failed (password)", ['id' => $id]); jsonError('Invalid password.', 401); } $jwtService = new JwtService($redis); // استخدام override للـ TTL في الـ Access Token (نحتاج 150 ثانية فقط) // لتوليد التوكن بتفاصيل خاصة، نستخدم الدالة generateAccessToken لكن بتعديل إن لزم، // أو نولد التوكن يدوياً هنا للسرعة كما كان: $fpPepper = getenv('FP_PEPPER') ?: ''; $fpHash = (!empty($fingerprint) && !empty($fpPepper)) ? hash('sha256', $fingerprint . $fpPepper) : null; $payload = [ 'user_id' => 'new', 'sub' => $id, 'token_type' => 'registration', 'exp' => time() + 150, // 150 ثانية 'iat' => time(), 'iss' => 'Tripz', 'aud' => $audience, 'jti' => bin2hex(random_bytes(16)), ]; if ($fpHash !== null) { $payload['fingerPrint'] = $fpHash; } $secretKey = trim(file_get_contents('/home/siro-api/.secret_key')); $jwt = Firebase\JWT\JWT::encode($payload, $secretKey, 'HS256'); jsonSuccess([ 'jwt' => $jwt, 'expires_in' => 150, ]); } catch (Exception $e) { securityLog("LoginFirstTime Error", ['msg' => $e->getMessage()]); jsonError('Server error', 500); } ``` ## File: privacy_policy.php ``` Siro - Privacy Policy & Terms

الشروط والخصوصية

تاريخ النفاذ: 09/08/2025     آخر تحديث: 14/08/2025

1. شروط الاستخدام والتعريفات

شروط الاستخدام

عند تحميل أو تصفح أو استخدام تطبيق إنطلق ("التطبيق")، فإنك توافق على الالتزام بهذه الشروط والأحكام. يحق لإنطلق تعديل هذه الشروط في أي وقت. إذا لم توافق على أي جزء من هذه الشروط، يجب عليك التوقف فورًا عن استخدام التطبيق. استمرارك في الاستخدام يعني موافقتك على الشروط وأي تعديلات لاحقة.

التعريفات

  • "إنطلق" أو "التطبيق": يشير إلى تطبيق الهاتف الذكي الذي يسهل خدمات النقل بين الركاب ("المستخدمين") والسائقين ("مقدمو الخدمة"). وهو منصة حجز رحلات تعمل كوسيط ولا توظف السائقين مباشرة.
  • "مقدمو الخدمة" (السائقون): الأفراد أو الكيانات المسجلة لتقديم خدمات النقل عبر إنطلق. يدفعون رسوم عمولة عن كل رحلة مكتملة.
  • "المستخدمون" (الركاب): الأفراد الذين يحجزون الرحلات عبر التطبيق.
  • "الخدمات": جميع خدمات النقل المقدمة من قبل مقدمي الخدمة عبر التطبيق.

2. سياسة الخصوصية

نحن نؤمن بالشفافية الكاملة فيما يتعلق ببياناتك. نوضح أدناه ما نجمعه، ولماذا، وكيف نحميه. يُعد استخدامنا لبيانات الموقع أمراً بالغ الأهمية لخدمتنا، ولذلك يتم شرحه أولاً.

إفصاح بارز: استخدام بيانات الموقع

لتوفير خدماتنا الأساسية لتوصيل الركاب، يقوم تطبيق إنطلق بجمع بيانات الموقع الدقيقة من جهازك المحمول. الوصول إلى موقعك ضروري لكي يعمل التطبيق.

نقوم بجمع هذه البيانات في الأوقات التالية:

  • عندما يكون التطبيق مفتوحاً على الشاشة (يعمل في الواجهة): لتحديد موقع الانطلاق الخاص بك، وعرضه على الخريطة، وإظهار السائقين القريبين منك.
  • عندما يعمل التطبيق في الخلفية (بعد منحك الإذن): هذا الأمر حاسم لإيجاد رحلة لك أثناء استخدامك لتطبيقات أخرى، ولتتبع مسار الرحلة لضمان السلامة ودقة حساب الأجرة، ولتمكين مزايا الأمان مثل مشاركة حالة رحلتك.

الغرض من الاستخدام: ببساطة، بدون بيانات موقعك، لا يمكننا إيجاد سائقين لك، أو توجيههم إلى نقطة انطلاقك، أو حساب أجرة رحلتك. يمكنك إدارة أو تعطيل خدمات الموقع من خلال إعدادات جهازك، ولكن يرجى العلم أن القيام بذلك سيمنع تطبيق إنطلق من تقديم خدماته.

البيانات التي تقدمها بنفسك

  • بيانات الهوية (للسائقين): الاسم الكامل، رقم الهاتف، صورة شخصية، ومعلومات الثبوتيات الشخصية للتحقق من الأهلية.
  • بيانات الدفع: نحن لا نجمع أو نحتفظ بأي بيانات دفع. بدلاً من ذلك، نربطك مع مزودي خدمات دفع محليين مرخصين.

بيانات أخرى يتم جمعها تلقائياً

  • بيانات الجهاز والاتصال: طراز جهازك، نظام التشغيل، معرفات الجهاز الفريدة، وعنوان IP لأمان الحساب والتحقق منه.
  • بيانات الاستخدام: معلومات حول كيفية تفاعلك مع التطبيق، مثل الميزات التي تستخدمها، وسجل رحلاتك، وتقييماتك، وذلك لتحسين خدماتنا.

3. التزامات المستخدم والسلوكيات

معلومات دقيقة

يجب على المستخدمين تقديم معلومات صحيحة وكاملة وحديثة أثناء التسجيل. سيؤدي استخدام حسابات مزيفة أو أنشطة احتيالية إلى تعليق الحساب.

السلوكيات المحظورة

يمنع على المستخدمين:

  • استخدام التطبيق في أنشطة غير قانونية.
  • مضايقة السائقين أو الركاب الآخرين.
  • إلحاق الضرر بالمركبة.

4. حقوق وواجبات الشركة

واجباتنا

  • حماية بياناتك الشخصية.
  • إبلاغك بأي تغييرات جوهرية في هذه السياسة.
  • توفير آليات واضحة لك لممارسة حقوقك المتعلقة بالبيانات.

حقوقنا

  • تحديث التطبيق وشروط الخدمة.
  • اتخاذ الإجراءات اللازمة في حال مخالفة المستخدم للسياسة.
  • رفض تقديم الخدمة لأي سبب مشروع.

5. سياسات الرحلات والسلامة

سياسة منع التدخين

يُحظر التدخين منعاً باتاً في جميع المركبات.

إجراءات السلامة لكوفيد-19

نحث جميع المستخدمين والسائقين على اتباع الإرشادات الصحية المحلية.

6. إخلاء المسؤولية

يقدم التطبيق والخدمات "كما هي" دون أي ضمانات. إنطلق هي منصة وسيطة ولا تتحمل المسؤولية عن أفعال السائقين أو المستخدمين.

7. التعديل على السياسة

في حال قمنا بإجراء تعديلات جوهرية على هذه الشروط، سنتعهد بإبلاغك بشكل واضح داخل التطبيق. سيُطلب منك قبول الشروط الجديدة لمواصلة استخدام الخدمة.

8. حذف الحساب والتواصل معنا

لحذف حسابك أو بياناتك، يرجى مراسلتنا على البريد الإلكتروني. يتم الرد على الطلبات خلال 30 يومًا.

لأي استفسارات، يرجى التواصل عبر: support@intaleqapp.com

Policy & Terms

Effective Date: 09/08/2025     Last Updated: 14/08/2025

1. Terms of Use & Definitions

Terms of Use

By downloading, browsing, or using the Siro application ("the App"), you agree to be bound by these Terms and Conditions. Siro reserves the right to modify these terms at any time. Continued use constitutes acceptance of the terms.

Definitions

  • "Siro" or "the App": Refers to the smartphone application that facilitates ride-hailing services.
  • "Service Providers" (Drivers): Individuals or entities registered to provide transportation services through Siro.
  • "Users" (Passengers): Individuals who book rides through the App.
  • "Services": All transportation services provided by Service Providers via the App.

2. Privacy Policy

We believe in full transparency regarding your data. Our use of location data is critical to our service and is explained first.

Prominent Disclosure: Use of Location Data

To provide our core ride-hailing services, the Siro app collects precise location data from your mobile device. Access to your location is essential for the app to function.

We collect this data:

  • When the app is open and visible (in the foreground): To determine your pickup location and show you nearby drivers.
  • When the app is running in the background (after you grant permission): This is crucial to connect you with a ride, track the trip's progress for safety and fare calculation.

Purpose of Use: Without your location data, we cannot find drivers for you, guide them to your pickup point, or calculate your fare. Disabling location services will prevent the app from providing its services.

Data You Provide Yourself

  • Identity Data (for Drivers): Full name, phone number, profile picture, and personal identification to verify eligibility.
  • Payment Data: We do not collect or store any payment data like card numbers. We connect you with licensed local payment providers.

Other Automatically Collected Data

  • Device & Connection Data: Your device's model, OS, unique identifiers, and IP address for security.
  • Usage Data: Information about how you interact with the app, such as trip history and ratings, to improve our services.

3. User Obligations & Conduct

Accurate Information

Users must provide true, complete, and up-to-date information. Fake accounts will result in account suspension.

Prohibited Conduct

Users must not:

  • Use the App for illegal activities.
  • Harass drivers or other passengers.
  • Damage the vehicle.

4. Company Rights and Duties

Our Duties

  • To protect your personal data.
  • To inform you of material changes to this policy.
  • To provide clear mechanisms to exercise your data rights.

Our Rights

  • To update the application and terms of service.
  • To take necessary actions in case of user violation.
  • To refuse service for any legitimate reason.

5. Ride & Safety Policies

No-Smoking Policy

Smoking is strictly prohibited in all vehicles.

COVID-19 Safety

We urge all users and drivers to follow local health guidelines.

6. Disclaimer of Liability

The App and services are provided "as is". Siro is an intermediary platform and is not liable for the acts of any user or driver.

7. Policy Modifications

If we make material changes, we will inform you clearly within the app. You will be required to accept the new terms to continue using the service.

8. Account Deletion & Contact Us

To delete your account or data, please email us. Requests are processed within 30 days.

For any questions, contact us at: support@intaleqapp.com

``` ## File: schema_tracking.sql ``` -- MySQL dump 10.13 Distrib 8.0.36-28, for Linux (x86_64) -- -- Host: 188.68.36.205 Database: locationDB -- ------------------------------------------------------ -- Server version 8.0.36-28 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!50717 SELECT COUNT(*) INTO @rocksdb_has_p_s_session_variables FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'performance_schema' AND TABLE_NAME = 'session_variables' */; /*!50717 SET @rocksdb_get_is_supported = IF (@rocksdb_has_p_s_session_variables, 'SELECT COUNT(*) INTO @rocksdb_is_supported FROM performance_schema.session_variables WHERE VARIABLE_NAME=\'rocksdb_bulk_load\'', 'SELECT 0') */; /*!50717 PREPARE s FROM @rocksdb_get_is_supported */; /*!50717 EXECUTE s */; /*!50717 DEALLOCATE PREPARE s */; /*!50717 SET @rocksdb_enable_bulk_load = IF (@rocksdb_is_supported, 'SET SESSION rocksdb_bulk_load = 1', 'SET @rocksdb_dummy_bulk_load = 0') */; /*!50717 PREPARE s FROM @rocksdb_enable_bulk_load */; /*!50717 EXECUTE s */; /*!50717 DEALLOCATE PREPARE s */; -- -- Table structure for table `CarRegistration` -- DROP TABLE IF EXISTS `CarRegistration`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `CarRegistration` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `vin` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `car_plate` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `make` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `model` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `year` varchar(10) CHARACTER SET utf32 COLLATE utf32_general_ci NOT NULL, `expiration_date` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `color` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `owner` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `color_hex` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fuel` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `isDefault` tinyint(1) NOT NULL DEFAULT '0', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'yet', PRIMARY KEY (`id`), UNIQUE KEY `car_plate` (`car_plate`), KEY `idx_driverID` (`driverID`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `adminUser` -- DROP TABLE IF EXISTS `adminUser`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `adminUser` ( `id` int NOT NULL AUTO_INCREMENT, `device_number` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `api_keys` -- DROP TABLE IF EXISTS `api_keys`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `api_keys` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `hashed_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `blacklist_driver` -- DROP TABLE IF EXISTS `blacklist_driver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `blacklist_driver` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `phone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'Violation', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `canecl` -- DROP TABLE IF EXISTS `canecl`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `canecl` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(111) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(111) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideID` varchar(111) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `note` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'nothing', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `captains_car` -- DROP TABLE IF EXISTS `captains_car`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `captains_car` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `vin` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `car_plate` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `make` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `year` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `expiration_date` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `owner` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color_hex` char(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `displacement` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `fuel` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `registration_date` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `isDefault` tinyint(1) NOT NULL DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `car_plate` (`car_plate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `carPlateEdit` -- DROP TABLE IF EXISTS `carPlateEdit`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `carPlateEdit` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `carPlate` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `color` varchar(20) NOT NULL, `make` varchar(50) NOT NULL, `model` varchar(20) NOT NULL, `expiration_date` varchar(50) NOT NULL, `owner` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `year` int NOT NULL, `isEdit` tinyint(1) NOT NULL DEFAULT '0', `employee` varchar(30) NOT NULL DEFAULT 'any', `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `driverId` (`driverId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `car_locations` -- DROP TABLE IF EXISTS `car_locations`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `car_locations` ( `driver_id` varchar(100) NOT NULL, `latitude` decimal(10,7) NOT NULL, `longitude` decimal(10,7) NOT NULL, `heading` decimal(10,2) NOT NULL, `speed` double(10,3) NOT NULL, `distance` decimal(10,2) NOT NULL, `status` varchar(6) NOT NULL DEFAULT 'off', `carType` varchar(100) NOT NULL DEFAULT 'Awfar', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `location_point` point NOT NULL /*!80003 SRID 4326 */, PRIMARY KEY (`driver_id`), KEY `idx_loc_status_time` (`status`,`updated_at`,`latitude`,`longitude`), SPATIAL KEY `idx_location_point` (`location_point`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; /*!50003 SET character_set_client = utf8mb4 */ ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_0900_ai_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`siroLocation`@`%`*/ /*!50003 TRIGGER `trg_before_insert_car_locations` BEFORE INSERT ON `car_locations` FOR EACH ROW BEGIN SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; /*!50003 SET character_set_client = utf8mb4 */ ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_0900_ai_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`siroLocation`@`%`*/ /*!50003 TRIGGER `trg_before_update_car_locations` BEFORE UPDATE ON `car_locations` FOR EACH ROW BEGIN IF NEW.latitude <> OLD.latitude OR NEW.longitude <> OLD.longitude THEN SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); END IF; END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -- -- Table structure for table `car_tracks` -- DROP TABLE IF EXISTS `car_tracks`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `car_tracks` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(100) NOT NULL, `latitude` decimal(10,7) NOT NULL, `longitude` decimal(10,7) NOT NULL, `heading` float DEFAULT NULL, `speed` float DEFAULT NULL, `distance` float DEFAULT NULL, `status` enum('on','off') DEFAULT 'off', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_driver_time` (`driver_id`,`created_at`) ) ENGINE=InnoDB AUTO_INCREMENT=2559370 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `card_images` -- DROP TABLE IF EXISTS `card_images`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `card_images` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `image_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `upload_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `link` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `carsToWork` -- DROP TABLE IF EXISTS `carsToWork`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `carsToWork` ( `id` int NOT NULL AUTO_INCREMENT, `owner_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `car_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `manufacture_year` year NOT NULL, `car_model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `car_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `site` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `registration_date` date NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `complaint` -- DROP TABLE IF EXISTS `complaint`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `complaint` ( `id` int NOT NULL AUTO_INCREMENT, `ride_id` varchar(255) NOT NULL, `passenger_id` varchar(255) DEFAULT NULL, `driver_id` varchar(255) DEFAULT NULL, `complaint_type` enum('Driver','Passenger','Both') NOT NULL, `description` text, `date_filed` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `statusComplaint` enum('Open','In Progress','Resolved') NOT NULL DEFAULT 'Open', `resolution` text, `passenger_report` text, `driver_report` text, `cs_solutions` text, `fault_determination` varchar(255) DEFAULT NULL, `complaint_nature` varchar(255) DEFAULT NULL, `date_resolved` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `contactEgypt` -- DROP TABLE IF EXISTS `contactEgypt`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `contactEgypt` ( `id` int NOT NULL AUTO_INCREMENT, `phones` varchar(20) NOT NULL, `name` varchar(100) NOT NULL, `phones2` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `contactSyria` -- DROP TABLE IF EXISTS `contactSyria`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `contactSyria` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(255) NOT NULL COMMENT 'معرّف السائق الذي قام بمزامنة جهة الاتصال', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'اسم جهة الاتصال', `phone` varchar(50) NOT NULL COMMENT 'رقم هاتف جهة الاتصال', `sync_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'وقت المزامنة', PRIMARY KEY (`id`), UNIQUE KEY `driver_contact_unique` (`driverId`,`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `criminalDocuments` -- DROP TABLE IF EXISTS `criminalDocuments`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `criminalDocuments` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `IssueDate` varchar(20) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `InspectionResult` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `driverId` (`driverId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver` -- DROP TABLE IF EXISTS `driver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver` ( `idn` int NOT NULL AUTO_INCREMENT, `id` varchar(100) NOT NULL, `phone` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, `gender` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'Male', `license_type` varchar(255) DEFAULT NULL, `national_number` varchar(255) DEFAULT NULL, `name_arabic` varchar(255) DEFAULT NULL, `issue_date` date DEFAULT NULL, `expiry_date` date DEFAULT NULL, `license_categories` varchar(255) DEFAULT NULL, `address` text, `licenseIssueDate` varchar(50) DEFAULT NULL, `status` varchar(20) NOT NULL DEFAULT 'notDeleted', `birthdate` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `site` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `accountBank` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'yet', `bankCode` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'CIB', `employmentType` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `maritalStatus` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `fullNameMaritial` varchar(255) DEFAULT NULL, `expirationDate` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`idn`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driverToken` -- DROP TABLE IF EXISTS `driverToken`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driverToken` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `captain_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fingerPrint` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_captain_id` (`captain_id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driverWallet` -- DROP TABLE IF EXISTS `driverWallet`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driverWallet` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `paymentID` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `amount` varchar(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `paymentMethod` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `dateUpdated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_behavior` -- DROP TABLE IF EXISTS `driver_behavior`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_behavior` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(255) NOT NULL, `trip_id` varchar(255) NOT NULL, `max_speed` double DEFAULT '0', `avg_speed` double DEFAULT '0', `hard_brakes` int DEFAULT '0', `total_distance` double DEFAULT '0', `behavior_score` double DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_daily_summary` -- DROP TABLE IF EXISTS `driver_daily_summary`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_daily_summary` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(33) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `date` date NOT NULL, `total_seconds` int DEFAULT '0', `last_updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `unique_driver_date` (`driver_id`,`date`) ) ENGINE=InnoDB AUTO_INCREMENT=308443 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_daily_work` -- DROP TABLE IF EXISTS `driver_daily_work`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_daily_work` ( `driver_id` int NOT NULL, `work_date` date NOT NULL, `total_seconds` int NOT NULL DEFAULT '0', `last_point_at` datetime DEFAULT NULL, `last_status` enum('on','off') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'off', `updated_at` datetime NOT NULL, PRIMARY KEY (`driver_id`,`work_date`), KEY `idx_driver_date` (`driver_id`,`work_date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_documents` -- DROP TABLE IF EXISTS `driver_documents`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_documents` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(64) NOT NULL, `doc_type` varchar(64) NOT NULL, `image_name` varchar(255) NOT NULL, `link` varchar(512) NOT NULL, `upload_date` datetime NOT NULL, PRIMARY KEY (`id`), KEY `driverID` (`driverID`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_gifts` -- DROP TABLE IF EXISTS `driver_gifts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_gifts` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `gift_description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `gift_date` datetime DEFAULT CURRENT_TIMESTAMP, `is_claimed` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `driver_id` (`driver_id`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_health_assurance` -- DROP TABLE IF EXISTS `driver_health_assurance`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_health_assurance` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `assured` tinyint(1) DEFAULT '0', `date_created` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `health_insurance_provider` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `driver_id` (`driver_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_orders` -- DROP TABLE IF EXISTS `driver_orders`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_orders` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `order_id` varchar(99) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `notes` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'nothing', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'applied', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_ride_scam` -- DROP TABLE IF EXISTS `driver_ride_scam`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_ride_scam` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passendgerID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideID` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `isDriverCallPassenger` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driversWantWork` -- DROP TABLE IF EXISTS `driversWantWork`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driversWantWork` ( `id` int NOT NULL AUTO_INCREMENT, `driver_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `national_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `birth_date` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `license_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `site` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `national_id` (`national_id`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `email_verifications` -- DROP TABLE IF EXISTS `email_verifications`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `email_verifications` ( `id` int NOT NULL AUTO_INCREMENT, `email` varchar(255) NOT NULL, `token` varchar(255) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `verified` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `employee` -- DROP TABLE IF EXISTS `employee`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `employee` ( `id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `education` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `site` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `error` -- DROP TABLE IF EXISTS `error`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `error` ( `id` int NOT NULL AUTO_INCREMENT, `error` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userType` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `device` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `details` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'new', PRIMARY KEY (`id`), KEY `idx_error_created_at` (`created_at`), KEY `idx_error_phone` (`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=14316 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `feedBack` -- DROP TABLE IF EXISTS `feedBack`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `feedBack` ( `id` int NOT NULL AUTO_INCREMENT, `passengerId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `feedBack` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `datecreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `helpCenter` -- DROP TABLE IF EXISTS `helpCenter`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `helpCenter` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(89) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `helpQuestion` varchar(300) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `replay` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'not yet', `datecreated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `hotels` -- DROP TABLE IF EXISTS `hotels`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `hotels` ( `id` int NOT NULL, `nameEnglish` varchar(255) DEFAULT NULL, `nameArabic` varchar(255) DEFAULT NULL, `phone` varchar(20) DEFAULT NULL, `countReview` int DEFAULT NULL, `rate` float DEFAULT NULL, `stars` varchar(50) DEFAULT NULL, `address` text, `website` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `PlusCode` varchar(50) DEFAULT NULL, `closeTime` varchar(50) DEFAULT NULL, `latitude` decimal(10,6) DEFAULT NULL, `longitude` decimal(10,6) DEFAULT NULL, `instagram` varchar(255) DEFAULT NULL, `facebook` varchar(255) DEFAULT NULL, `linkedin` varchar(255) DEFAULT NULL, `twitter` varchar(255) DEFAULT NULL, `photo` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `imageProfileCaptain` -- DROP TABLE IF EXISTS `imageProfileCaptain`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `imageProfileCaptain` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `image_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `upload_date` datetime DEFAULT CURRENT_TIMESTAMP, `link` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invites` -- DROP TABLE IF EXISTS `invites`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invites` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `inviterDriverPhone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `inviteCode` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `isInstall` tinyint(1) NOT NULL DEFAULT '0', `isGiftToken` tinyint(1) NOT NULL DEFAULT '0', `expirationTime` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `inviterDriverId` (`inviterDriverPhone`), UNIQUE KEY `inviteCode` (`inviteCode`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invitesToPassengers` -- DROP TABLE IF EXISTS `invitesToPassengers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invitesToPassengers` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'yet', `inviterPassengerPhone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `inviteCode` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expirationTime` datetime NOT NULL, `createdAt` datetime DEFAULT CURRENT_TIMESTAMP, `isInstall` tinyint(1) DEFAULT '0', `isGiftToken` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `inviteCode` (`inviteCode`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invoice_records` -- DROP TABLE IF EXISTS `invoice_records`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invoice_records` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` int NOT NULL, `invoice_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `amount` decimal(10,2) DEFAULT NULL, `date` date DEFAULT NULL, `image_link` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `created_at` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invoicesAdmin` -- DROP TABLE IF EXISTS `invoicesAdmin`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invoicesAdmin` ( `id` int NOT NULL AUTO_INCREMENT, `item_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `amount` decimal(10,2) NOT NULL, `image_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `kazan` -- DROP TABLE IF EXISTS `kazan`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `kazan` ( `id` int NOT NULL AUTO_INCREMENT, `country` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `kazan` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `comfortPrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `speedPrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `familyPrice` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `deliveryPrice` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `freePrice` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `latePrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `heavyPrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `adminId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `naturePrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fuelPrice` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `lisenceDetails` -- DROP TABLE IF EXISTS `lisenceDetails`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `lisenceDetails` ( `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `driverID` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `licenseClass` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `documentNo` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `height` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `postalCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `stateCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `expireDate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `dateOfBirth` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `documentNo` (`documentNo`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `login_attempts` -- DROP TABLE IF EXISTS `login_attempts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `login_attempts` ( `id` int NOT NULL AUTO_INCREMENT, `ip_address` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `attempt_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `login_attempts_drivers` -- DROP TABLE IF EXISTS `login_attempts_drivers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `login_attempts_drivers` ( `id` int NOT NULL AUTO_INCREMENT, `ip_address` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `attempt_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `mishwaritrips` -- DROP TABLE IF EXISTS `mishwaritrips`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `mishwaritrips` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `gender` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name_english` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `religion` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `age` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `startNameAddress` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none', `locationCoordinate` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none', `education` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `license_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `national_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `car_plate` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `make` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color_hex` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `rating` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `countRide` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `passengerId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `timeSelected` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'pending', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notesForDriverService` -- DROP TABLE IF EXISTS `notesForDriverService`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notesForDriverService` ( `id` int NOT NULL AUTO_INCREMENT, `phone` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `note` varchar(250) NOT NULL, `editor` varchar(50) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notesForPassengerService` -- DROP TABLE IF EXISTS `notesForPassengerService`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notesForPassengerService` ( `id` int NOT NULL AUTO_INCREMENT, `phone` int NOT NULL, `note` varchar(250) NOT NULL, `editor` varchar(50) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notificationCaptain` -- DROP TABLE IF EXISTS `notificationCaptain`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notificationCaptain` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `title` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `body` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `isShown` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'false', `isPin` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'unPin', `dateCreated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notifications` -- DROP TABLE IF EXISTS `notifications`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notifications` ( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(111) NOT NULL, `body` varchar(265) NOT NULL, `passenger_id` varchar(111) NOT NULL, `isShown` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'false', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `otp_verification_fingerPrint` -- DROP TABLE IF EXISTS `otp_verification_fingerPrint`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `otp_verification_fingerPrint` ( `id` int NOT NULL, `phone` varchar(20) NOT NULL, `otp` varchar(6) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `packageInfo` -- DROP TABLE IF EXISTS `packageInfo`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `packageInfo` ( `id` int NOT NULL AUTO_INCREMENT, `platform` varchar(50) NOT NULL, `appName` varchar(20) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `version` varchar(10) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `palces11` -- DROP TABLE IF EXISTS `palces11`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `palces11` ( `id` int NOT NULL AUTO_INCREMENT, `latitude` varchar(50) NOT NULL, `longitude` varchar(50) NOT NULL, `name` varchar(180) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `name_ar` varchar(200) NOT NULL, `name_en` varchar(200) NOT NULL, `address` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `category` varchar(55) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `location` point NOT NULL, PRIMARY KEY (`id`), SPATIAL KEY `idx_spatial_location` (`location`), FULLTEXT KEY `idx_fulltext_search` (`name`,`name_ar`,`name_en`,`address`,`category`) ) ENGINE=InnoDB AUTO_INCREMENT=28951 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passengerWallet` -- DROP TABLE IF EXISTS `passengerWallet`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passengerWallet` ( `id` int NOT NULL AUTO_INCREMENT, `passenger_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `balance` decimal(10,2) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `passenger_id` (`passenger_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passenger_blacklist` -- DROP TABLE IF EXISTS `passenger_blacklist`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passenger_blacklist` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `phone` varchar(150) NOT NULL, `phone_normalized` varchar(64) NOT NULL, `reason` varchar(255) DEFAULT NULL, `expires_at` datetime DEFAULT CURRENT_TIMESTAMP, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uq_phone_norm` (`phone_normalized`), KEY `idx_expires` (`expires_at`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passengerlocation` -- DROP TABLE IF EXISTS `passengerlocation`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passengerlocation` ( `id` int NOT NULL AUTO_INCREMENT, `passengerId` varchar(60) NOT NULL, `lat` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `lng` varchar(20) NOT NULL, `rideId` varchar(10) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3172 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passengers` -- DROP TABLE IF EXISTS `passengers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passengers` ( `id` varchar(100) NOT NULL, `phone` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(100) NOT NULL, `gender` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `status` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'notDeleted', `birthdate` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `site` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `sosPhone` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'sos', `education` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'none', `employmentType` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'none', `maritalStatus` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'none', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`,`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `payment_tokens` -- DROP TABLE IF EXISTS `payment_tokens`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `payment_tokens` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(255) NOT NULL, `driverID` varchar(255) NOT NULL, `dateCreated` datetime NOT NULL, `amount` decimal(10,2) NOT NULL, `isUsed` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `payment_tokens_passenger` -- DROP TABLE IF EXISTS `payment_tokens_passenger`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `payment_tokens_passenger` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(255) NOT NULL, `passengerId` varchar(255) NOT NULL, `dateCreated` datetime NOT NULL, `amount` decimal(10,2) NOT NULL, `isUsed` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `payments` -- DROP TABLE IF EXISTS `payments`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `payments` ( `id` varchar(111) NOT NULL, `amount` decimal(10,2) NOT NULL, `payment_method` varchar(255) NOT NULL, `passengerID` varchar(100) NOT NULL, `rideId` varchar(100) NOT NULL, `driverID` varchar(100) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `isGiven` varchar(20) NOT NULL DEFAULT 'waiting', PRIMARY KEY (`id`), UNIQUE KEY `rideId` (`rideId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `paymentsDriverPoints` -- DROP TABLE IF EXISTS `paymentsDriverPoints`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `paymentsDriverPoints` ( `id` int NOT NULL AUTO_INCREMENT, `amount` decimal(10,2) NOT NULL, `payment_method` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `driverID` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` datetime DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `phone_verification` -- DROP TABLE IF EXISTS `phone_verification`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `phone_verification` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `driverId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'yet', `email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'yet', `token_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `expiration_time` datetime NOT NULL, `is_verified` tinyint(1) DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=111 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `phone_verification_passenger` -- DROP TABLE IF EXISTS `phone_verification_passenger`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `phone_verification_passenger` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `token` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `expiration_time` datetime NOT NULL, `verified` tinyint(1) DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(22) NOT NULL DEFAULT 'yet', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `places` -- DROP TABLE IF EXISTS `places`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `places` ( `id` int NOT NULL AUTO_INCREMENT, `latitude` double NOT NULL, `longitude` double NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `name_ar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8996 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `placesEgypt` -- DROP TABLE IF EXISTS `placesEgypt`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `placesEgypt` ( `id` int NOT NULL, `nameEnglish` varchar(255) DEFAULT NULL, `nameArabic` varchar(255) DEFAULT NULL, `phone` varchar(20) DEFAULT NULL, `countReview` int DEFAULT NULL, `rate` float DEFAULT NULL, `stars` varchar(50) DEFAULT NULL, `address` text, `website` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `PlusCode` varchar(50) DEFAULT NULL, `closeTime` varchar(50) DEFAULT NULL, `latitude` decimal(10,6) DEFAULT NULL, `longitude` decimal(10,6) DEFAULT NULL, `instagram` varchar(255) DEFAULT NULL, `facebook` varchar(255) DEFAULT NULL, `linkedin` varchar(255) DEFAULT NULL, `twitter` varchar(255) DEFAULT NULL, `photo` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `promos` -- DROP TABLE IF EXISTS `promos`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `promos` ( `id` int NOT NULL AUTO_INCREMENT, `promo_code` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `amount` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0', `description` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `passengerID` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none', `validity_start_date` date DEFAULT NULL, `validity_end_date` date DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `passengerID` (`passengerID`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `promptDriverIDEgypt` -- DROP TABLE IF EXISTS `promptDriverIDEgypt`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `promptDriverIDEgypt` ( `id` int NOT NULL AUTO_INCREMENT, `type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `prompt` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ratingApp` -- DROP TABLE IF EXISTS `ratingApp`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ratingApp` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `email` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userType` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rating` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `comment` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ratingDriver` -- DROP TABLE IF EXISTS `ratingDriver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ratingDriver` ( `id` int NOT NULL AUTO_INCREMENT, `passenger_id` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `driver_id` varchar(33) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `ride_id` int DEFAULT NULL, `rating` float DEFAULT NULL, `comment` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `ride_id` (`ride_id`), KEY `idx_driver_id` (`driver_id`) ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ratingPassenger` -- DROP TABLE IF EXISTS `ratingPassenger`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ratingPassenger` ( `id` int NOT NULL AUTO_INCREMENT, `passenger_id` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideId` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rating` float NOT NULL, `comment` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `rideId` (`rideId`) ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ride` -- DROP TABLE IF EXISTS `ride`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ride` ( `id` int NOT NULL AUTO_INCREMENT, `start_location` varchar(255) NOT NULL, `end_location` varchar(255) NOT NULL, `date` date NOT NULL, `time` time NOT NULL, `endtime` time NOT NULL, `price` decimal(10,2) NOT NULL DEFAULT '0.00', `passenger_id` varchar(111) NOT NULL, `driver_id` varchar(111) NOT NULL, `status` varchar(200) NOT NULL DEFAULT 'nothing', `paymentMethod` varchar(20) NOT NULL DEFAULT 'Cash', `carType` varchar(20) NOT NULL DEFAULT 'Speed', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `DriverIsGoingToPassenger` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `rideTimeStart` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `rideTimeFinish` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `price_for_driver` decimal(10,2) NOT NULL DEFAULT '0.00', `price_for_passenger` decimal(10,2) NOT NULL DEFAULT '0.00', `distance` float DEFAULT '0', PRIMARY KEY (`id`), KEY `passengerfk` (`passenger_id`), KEY `driverfk` (`driver_id`) ) ENGINE=InnoDB AUTO_INCREMENT=94 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `seferWallet` -- DROP TABLE IF EXISTS `seferWallet`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `seferWallet` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(100) NOT NULL, `passengerId` varchar(100) NOT NULL, `amount` varchar(10) NOT NULL, `paymentMethod` varchar(50) NOT NULL, `token` varchar(100) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `server_locations` -- DROP TABLE IF EXISTS `server_locations`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `server_locations` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `min_latitude` decimal(10,6) NOT NULL, `max_latitude` decimal(10,6) NOT NULL, `min_longitude` decimal(10,6) NOT NULL, `max_longitude` decimal(10,6) NOT NULL, `server_link` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `smsSender` -- DROP TABLE IF EXISTS `smsSender`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `smsSender` ( `id` int NOT NULL AUTO_INCREMENT, `senderId` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `test` -- DROP TABLE IF EXISTS `test`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `test` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `testApp` -- DROP TABLE IF EXISTS `testApp`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `testApp` ( `id` int NOT NULL AUTO_INCREMENT, `isTest` tinyint(1) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `appPlatform` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `tips` -- DROP TABLE IF EXISTS `tips`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `tips` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `tipAmount` decimal(10,2) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `token_verification` -- DROP TABLE IF EXISTS `token_verification`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `token_verification` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expiration_time` datetime NOT NULL, `verified` tinyint(1) DEFAULT '0', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `token_verification_admin` -- DROP TABLE IF EXISTS `token_verification_admin`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `token_verification_admin` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `token` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expiration_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `phone_number` (`phone_number`) ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `token_verification_driver` -- DROP TABLE IF EXISTS `token_verification_driver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `token_verification_driver` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expiration_time` datetime NOT NULL, `verified` tinyint(1) NOT NULL DEFAULT '0', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `tokens` -- DROP TABLE IF EXISTS `tokens`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `tokens` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(333) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fingerPrint` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `status` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'yet', PRIMARY KEY (`id`), UNIQUE KEY `passengerID` (`passengerID`) ) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `users` -- DROP TABLE IF EXISTS `users`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `users` ( `id` varchar(111) NOT NULL, `phone` varchar(15) NOT NULL, `email` varchar(255) NOT NULL, `gender` varchar(10) NOT NULL, `password` varchar(100) NOT NULL, `birthdate` date NOT NULL, `site` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_type` varchar(44) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `vehicles` -- DROP TABLE IF EXISTS `vehicles`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `vehicles` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) NOT NULL, `make` varchar(255) NOT NULL, `model` varchar(255) NOT NULL, `license_plate` varchar(255) NOT NULL, `seats` int NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `license_plate` (`license_plate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `videos` -- DROP TABLE IF EXISTS `videos`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `videos` ( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `description` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `url` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `waitingRides` -- DROP TABLE IF EXISTS `waitingRides`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `waitingRides` ( `id` varchar(100) NOT NULL, `start_location` varchar(255) NOT NULL, `end_location` varchar(255) NOT NULL, `date` date NOT NULL, `time` time NOT NULL, `price` decimal(10,2) NOT NULL DEFAULT '0.00', `passenger_id` varchar(111) NOT NULL, `status` varchar(200) NOT NULL DEFAULT 'nothing', `carType` varchar(19) NOT NULL, `passengerRate` decimal(10,2) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `price_for_passenger` decimal(10,2) NOT NULL DEFAULT '0.00', `distance` varchar(255) NOT NULL, `duration` varchar(10) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `welcomeDriverCall` -- DROP TABLE IF EXISTS `welcomeDriverCall`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `welcomeDriverCall` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `isCall` tinyint(1) NOT NULL DEFAULT '0', `notes` varchar(255) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `write_argument_after_applied_from_background` -- DROP TABLE IF EXISTS `write_argument_after_applied_from_background`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `write_argument_after_applied_from_background` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `ride_id` varchar(50) NOT NULL, `driver_id` varchar(50) NOT NULL, `passenger_id` varchar(50) NOT NULL, `passenger_location` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `passenger_destination` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `duration` varchar(255) NOT NULL, `duration_to_passenger` varchar(255) NOT NULL, `duration_of_ride` varchar(255) NOT NULL, `distance` varchar(255) NOT NULL, `total_cost` varchar(255) NOT NULL, `payment_amount` varchar(255) NOT NULL, `payment_method` enum('visa','cash') NOT NULL, `wallet_checked` varchar(255) NOT NULL, `has_steps` varchar(255) NOT NULL, `step0` varchar(255) DEFAULT NULL, `step1` varchar(255) DEFAULT NULL, `step2` varchar(255) DEFAULT NULL, `step3` varchar(255) DEFAULT NULL, `step4` varchar(255) DEFAULT NULL, `passenger_wallet_burc` varchar(33) NOT NULL, `token_passenger` varchar(255) NOT NULL, `name` varchar(100) NOT NULL, `phone` varchar(20) NOT NULL, `email` varchar(150) NOT NULL, `start_name_location` varchar(255) NOT NULL, `end_name_location` varchar(255) NOT NULL, `car_type` varchar(50) NOT NULL, `kazan` varchar(255) NOT NULL, `direction_url` text NOT NULL, `time_of_order` datetime NOT NULL, `total_passenger` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping events for database 'locationDB' -- -- -- Dumping routines for database 'locationDB' -- /*!50112 SET @disable_bulk_load = IF (@is_rocksdb_supported, 'SET SESSION rocksdb_bulk_load = @old_rocksdb_bulk_load', 'SET @dummy_rocksdb_bulk_load = 0') */; /*!50112 PREPARE s FROM @disable_bulk_load */; /*!50112 EXECUTE s */; /*!50112 DEALLOCATE PREPARE s */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2026-04-22 20:48:59 ``` ## File: loginJwtDriver.php ``` enforce(RateLimiter::identifier(), 'login'); $id = filterRequest('id'); $audience = filterRequest('aud'); $fingerprint = filterRequest('fingerPrint') ?? filterRequest('fingerprint'); $aud1 = getenv('allowedDriver1'); $aud2 = getenv('allowedDriver2'); $allowedAudiences = array_values(array_filter([$aud1, $aud2])); if (empty($id) || empty($audience)) { jsonError('Missing required fields', 400); } if (!in_array($audience, $allowedAudiences, true)) { jsonError('Invalid audience', 400); } $con = Database::get('main'); $pepper = getenv('SECRET_KEY_HMAC'); $stmt = $con->prepare(' SELECT id, phone, national_number, email, password FROM driver WHERE id = :id LIMIT 1 '); $stmt->execute([':id' => $id]); $driver = $stmt->fetch(); if (!$driver || empty($driver['password'])) { unauthorizedDriver(); } $decPhone = !empty($driver['phone']) ? $encryptionHelper->decryptData($driver['phone']) : null; $decNat = !empty($driver['national_number']) ? $encryptionHelper->decryptData($driver['national_number']) : null; if (empty($decPhone) || empty($decNat)) { unauthorizedDriver(); } $baseString = $driver['id'] . '|' . trim($decPhone) . '|' . trim($decNat); $hmacHex = hash_hmac('sha256', $baseString, $pepper, false); if (!password_verify($hmacHex, $driver['password'])) { unauthorizedDriver(); } $limiter->reset(RateLimiter::identifier(), 'login'); $jwtService = new JwtService($redis); $jwt = $jwtService->generateAccessToken($driver['id'], 'driver', $audience, $fingerprint); $refresh = $jwtService->generateRefreshToken($driver['id']); jsonSuccess([ 'jwt' => $jwt, 'refresh_token' => $refresh['token'], 'expires_in' => 900 ]); } catch (PDOException $e) { securityLog("LoginDriver PDO Error", ['msg' => $e->getMessage()]); jsonError('Database error', 500); } catch (Exception $e) { securityLog("LoginDriver Error", ['msg' => $e->getMessage()]); jsonError('Server error', 500); } ``` ## File: get_connect.php ``` enforce(RateLimiter::identifier(), 'api'); // 3. الاتصال الافتراضي بقاعدة البيانات (Lazy Load) try { $con = Database::get('main'); } catch (Exception $e) { http_response_code(500); exit(json_encode(['error' => 'Database connection failed'])); } ``` ## File: composer.json ``` { "require": { "vlucas/phpdotenv": "^5.6" } } ``` ## File: upload_audio.php ``` 'The audio file was not uploaded successfully.')); exit; } // Get the file name and extension of the audio file $audio_name = $audio_file['name']; $audio_extension = pathinfo($audio_name, PATHINFO_EXTENSION); // Check if the audio file is a valid audio format if (!in_array($audio_extension, array('m4a', 'mp3', 'wav'))) { echo json_encode(array('status' => 'The audio file is not a valid format.')); exit; } // Generate a new filename using the passenger ID to avoid conflicts $new_filename = $audio_name . '.' . $audio_extension; // Move the audio file to the uploads directory with the new filename $target_dir = "audio_uploads/"; if (!is_dir($target_dir)) { mkdir($target_dir, 0755, true); // Create directory if it doesn't exist } $target_file = $target_dir . $new_filename; if (!move_uploaded_file($audio_file['tmp_name'], $target_file)) { error_log("Failed to move file to target directory: " . print_r($audio_file, true)); echo json_encode(array('status' => 'Failed to move the audio file.')); exit; } // Construct the link to the uploaded audio file $base_url = 'https://sefer.click/sefer/audio_uploads/'; // Replace with your actual domain $linkAudio = $base_url . $new_filename; // Respond with success and the audio file link echo json_encode(array('status' => 'Audio file uploaded successfully.', 'link' => $linkAudio)); // Close the database connection if it was established if (isset($conn)) { mysqli_close($conn); } ?> ``` ## File: schema_ride.sql ``` -- MySQL dump 10.13 Distrib 8.0.36-28, for Linux (x86_64) -- -- Host: localhost Database: intaleq-ridesDB -- ------------------------------------------------------ -- Server version 8.0.36-28 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!50503 SET NAMES utf8mb4 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!50717 SELECT COUNT(*) INTO @rocksdb_has_p_s_session_variables FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'performance_schema' AND TABLE_NAME = 'session_variables' */; /*!50717 SET @rocksdb_get_is_supported = IF (@rocksdb_has_p_s_session_variables, 'SELECT COUNT(*) INTO @rocksdb_is_supported FROM performance_schema.session_variables WHERE VARIABLE_NAME=\'rocksdb_bulk_load\'', 'SELECT 0') */; /*!50717 PREPARE s FROM @rocksdb_get_is_supported */; /*!50717 EXECUTE s */; /*!50717 DEALLOCATE PREPARE s */; /*!50717 SET @rocksdb_enable_bulk_load = IF (@rocksdb_is_supported, 'SET SESSION rocksdb_bulk_load = 1', 'SET @rocksdb_dummy_bulk_load = 0') */; /*!50717 PREPARE s FROM @rocksdb_enable_bulk_load */; /*!50717 EXECUTE s */; /*!50717 DEALLOCATE PREPARE s */; -- -- Table structure for table `CarRegistration` -- DROP TABLE IF EXISTS `CarRegistration`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `CarRegistration` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `vin` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `car_plate` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `make` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `model` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `year` varchar(10) CHARACTER SET utf32 COLLATE utf32_general_ci NOT NULL, `expiration_date` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `color` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `owner` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `color_hex` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fuel` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `isDefault` tinyint(1) NOT NULL DEFAULT '0', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'yet', PRIMARY KEY (`id`), UNIQUE KEY `car_plate` (`car_plate`), KEY `idx_driverID` (`driverID`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `adminUser` -- DROP TABLE IF EXISTS `adminUser`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `adminUser` ( `id` int NOT NULL AUTO_INCREMENT, `device_number` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `api_keys` -- DROP TABLE IF EXISTS `api_keys`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `api_keys` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `hashed_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `blacklist_driver` -- DROP TABLE IF EXISTS `blacklist_driver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `blacklist_driver` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `phone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'Violation', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `canecl` -- DROP TABLE IF EXISTS `canecl`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `canecl` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(111) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(111) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideID` varchar(111) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `note` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'nothing', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `captains_car` -- DROP TABLE IF EXISTS `captains_car`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `captains_car` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `vin` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `car_plate` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `make` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `year` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `expiration_date` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `owner` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color_hex` char(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `displacement` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `fuel` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `registration_date` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `isDefault` tinyint(1) NOT NULL DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `car_plate` (`car_plate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `carPlateEdit` -- DROP TABLE IF EXISTS `carPlateEdit`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `carPlateEdit` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `carPlate` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `color` varchar(20) NOT NULL, `make` varchar(50) NOT NULL, `model` varchar(20) NOT NULL, `expiration_date` varchar(50) NOT NULL, `owner` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `year` int NOT NULL, `isEdit` tinyint(1) NOT NULL DEFAULT '0', `employee` varchar(30) NOT NULL DEFAULT 'any', `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `driverId` (`driverId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `car_locations` -- DROP TABLE IF EXISTS `car_locations`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `car_locations` ( `driver_id` varchar(100) NOT NULL, `latitude` decimal(10,7) NOT NULL, `longitude` decimal(10,7) NOT NULL, `heading` decimal(10,2) NOT NULL, `speed` double(10,3) NOT NULL, `distance` decimal(10,2) NOT NULL, `status` varchar(6) NOT NULL DEFAULT 'off', `carType` varchar(100) NOT NULL DEFAULT 'Awfar', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `location_point` point NOT NULL /*!80003 SRID 4326 */, PRIMARY KEY (`driver_id`), KEY `idx_loc_status_time` (`status`,`updated_at`,`latitude`,`longitude`), SPATIAL KEY `idx_location_point` (`location_point`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; /*!50003 SET character_set_client = utf8mb4 */ ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_0900_ai_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`intaleq-rides`@`%`*/ /*!50003 TRIGGER `trg_before_insert_car_locations` BEFORE INSERT ON `car_locations` FOR EACH ROW BEGIN SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; /*!50003 SET character_set_client = utf8mb4 */ ; /*!50003 SET character_set_results = utf8mb4 */ ; /*!50003 SET collation_connection = utf8mb4_0900_ai_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; DELIMITER ;; /*!50003 CREATE*/ /*!50017 DEFINER=`intaleq-rides`@`%`*/ /*!50003 TRIGGER `trg_before_update_car_locations` BEFORE UPDATE ON `car_locations` FOR EACH ROW BEGIN IF NEW.latitude <> OLD.latitude OR NEW.longitude <> OLD.longitude THEN SET NEW.location_point = ST_PointFromText(CONCAT('POINT(', NEW.longitude, ' ', NEW.latitude, ')'), 4326); END IF; END */;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; -- -- Table structure for table `car_tracks` -- DROP TABLE IF EXISTS `car_tracks`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `car_tracks` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(100) NOT NULL, `latitude` decimal(10,7) NOT NULL, `longitude` decimal(10,7) NOT NULL, `heading` float DEFAULT NULL, `speed` float DEFAULT NULL, `distance` float DEFAULT NULL, `status` enum('on','off') DEFAULT 'off', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `card_images` -- DROP TABLE IF EXISTS `card_images`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `card_images` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `image_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `upload_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `link` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `carsToWork` -- DROP TABLE IF EXISTS `carsToWork`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `carsToWork` ( `id` int NOT NULL AUTO_INCREMENT, `owner_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `car_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `manufacture_year` year NOT NULL, `car_model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `car_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `site` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `registration_date` date NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `complaint` -- DROP TABLE IF EXISTS `complaint`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `complaint` ( `id` int NOT NULL AUTO_INCREMENT, `ride_id` varchar(255) NOT NULL, `passenger_id` varchar(255) DEFAULT NULL, `driver_id` varchar(255) DEFAULT NULL, `complaint_type` enum('Driver','Passenger','Both') NOT NULL, `description` text, `date_filed` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `statusComplaint` enum('Open','In Progress','Resolved') NOT NULL DEFAULT 'Open', `resolution` text, `passenger_report` text, `driver_report` text, `cs_solutions` text, `fault_determination` varchar(255) DEFAULT NULL, `complaint_nature` varchar(255) DEFAULT NULL, `date_resolved` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `contactEgypt` -- DROP TABLE IF EXISTS `contactEgypt`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `contactEgypt` ( `id` int NOT NULL AUTO_INCREMENT, `phones` varchar(20) NOT NULL, `name` varchar(100) NOT NULL, `phones2` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `contactSyria` -- DROP TABLE IF EXISTS `contactSyria`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `contactSyria` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(255) NOT NULL COMMENT 'معرّف السائق الذي قام بمزامنة جهة الاتصال', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'اسم جهة الاتصال', `phone` varchar(50) NOT NULL COMMENT 'رقم هاتف جهة الاتصال', `sync_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'وقت المزامنة', PRIMARY KEY (`id`), UNIQUE KEY `driver_contact_unique` (`driverId`,`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `criminalDocuments` -- DROP TABLE IF EXISTS `criminalDocuments`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `criminalDocuments` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `IssueDate` varchar(20) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `InspectionResult` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `driverId` (`driverId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver` -- DROP TABLE IF EXISTS `driver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver` ( `idn` int NOT NULL AUTO_INCREMENT, `id` varchar(100) NOT NULL, `phone` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, `gender` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'Male', `license_type` varchar(255) DEFAULT NULL, `national_number` varchar(255) DEFAULT NULL, `name_arabic` varchar(255) DEFAULT NULL, `issue_date` date DEFAULT NULL, `expiry_date` date DEFAULT NULL, `license_categories` varchar(255) DEFAULT NULL, `address` text, `licenseIssueDate` varchar(50) DEFAULT NULL, `status` varchar(20) NOT NULL DEFAULT 'notDeleted', `birthdate` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `site` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `accountBank` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'yet', `bankCode` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'CIB', `employmentType` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `maritalStatus` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `fullNameMaritial` varchar(255) DEFAULT NULL, `expirationDate` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`idn`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driverToken` -- DROP TABLE IF EXISTS `driverToken`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driverToken` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `captain_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fingerPrint` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_captain_id` (`captain_id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driverWallet` -- DROP TABLE IF EXISTS `driverWallet`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driverWallet` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `paymentID` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `amount` varchar(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `paymentMethod` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `dateUpdated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_behavior` -- DROP TABLE IF EXISTS `driver_behavior`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_behavior` ( `id` int NOT NULL, `driver_id` varchar(255) NOT NULL, `trip_id` varchar(255) NOT NULL, `max_speed` double DEFAULT '0', `avg_speed` double DEFAULT '0', `hard_brakes` int DEFAULT '0', `total_distance` double DEFAULT '0', `behavior_score` double DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_documents` -- DROP TABLE IF EXISTS `driver_documents`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_documents` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(64) NOT NULL, `doc_type` varchar(64) NOT NULL, `image_name` varchar(255) NOT NULL, `link` varchar(512) NOT NULL, `upload_date` datetime NOT NULL, PRIMARY KEY (`id`), KEY `driverID` (`driverID`) ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_gifts` -- DROP TABLE IF EXISTS `driver_gifts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_gifts` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `gift_description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `gift_date` datetime DEFAULT CURRENT_TIMESTAMP, `is_claimed` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `driver_id` (`driver_id`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_health_assurance` -- DROP TABLE IF EXISTS `driver_health_assurance`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_health_assurance` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(155) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `assured` tinyint(1) DEFAULT '0', `date_created` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `health_insurance_provider` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `driver_id` (`driver_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_orders` -- DROP TABLE IF EXISTS `driver_orders`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_orders` ( `id` int NOT NULL AUTO_INCREMENT, `driver_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `order_id` varchar(99) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `notes` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'nothing', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'applied', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driver_ride_scam` -- DROP TABLE IF EXISTS `driver_ride_scam`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driver_ride_scam` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passendgerID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideID` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `isDriverCallPassenger` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `driversWantWork` -- DROP TABLE IF EXISTS `driversWantWork`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `driversWantWork` ( `id` int NOT NULL AUTO_INCREMENT, `driver_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `national_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `birth_date` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `license_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `site` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `national_id` (`national_id`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `email_verifications` -- DROP TABLE IF EXISTS `email_verifications`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `email_verifications` ( `id` int NOT NULL AUTO_INCREMENT, `email` varchar(255) NOT NULL, `token` varchar(255) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `verified` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `employee` -- DROP TABLE IF EXISTS `employee`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `employee` ( `id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `education` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `site` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `error` -- DROP TABLE IF EXISTS `error`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `error` ( `id` int NOT NULL AUTO_INCREMENT, `error` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userType` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `device` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `details` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'new', PRIMARY KEY (`id`), KEY `idx_error_created_at` (`created_at`), KEY `idx_error_phone` (`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=14316 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `feedBack` -- DROP TABLE IF EXISTS `feedBack`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `feedBack` ( `id` int NOT NULL AUTO_INCREMENT, `passengerId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `feedBack` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `datecreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `helpCenter` -- DROP TABLE IF EXISTS `helpCenter`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `helpCenter` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(89) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `helpQuestion` varchar(300) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `replay` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'not yet', `datecreated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `hotels` -- DROP TABLE IF EXISTS `hotels`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `hotels` ( `id` int NOT NULL, `nameEnglish` varchar(255) DEFAULT NULL, `nameArabic` varchar(255) DEFAULT NULL, `phone` varchar(20) DEFAULT NULL, `countReview` int DEFAULT NULL, `rate` float DEFAULT NULL, `stars` varchar(50) DEFAULT NULL, `address` text, `website` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `PlusCode` varchar(50) DEFAULT NULL, `closeTime` varchar(50) DEFAULT NULL, `latitude` decimal(10,6) DEFAULT NULL, `longitude` decimal(10,6) DEFAULT NULL, `instagram` varchar(255) DEFAULT NULL, `facebook` varchar(255) DEFAULT NULL, `linkedin` varchar(255) DEFAULT NULL, `twitter` varchar(255) DEFAULT NULL, `photo` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `imageProfileCaptain` -- DROP TABLE IF EXISTS `imageProfileCaptain`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `imageProfileCaptain` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `image_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `upload_date` datetime DEFAULT CURRENT_TIMESTAMP, `link` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invites` -- DROP TABLE IF EXISTS `invites`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invites` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `inviterDriverPhone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `inviteCode` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `isInstall` tinyint(1) NOT NULL DEFAULT '0', `isGiftToken` tinyint(1) NOT NULL DEFAULT '0', `expirationTime` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `inviterDriverId` (`inviterDriverPhone`), UNIQUE KEY `inviteCode` (`inviteCode`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invitesToPassengers` -- DROP TABLE IF EXISTS `invitesToPassengers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invitesToPassengers` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'yet', `inviterPassengerPhone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `inviteCode` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expirationTime` datetime NOT NULL, `createdAt` datetime DEFAULT CURRENT_TIMESTAMP, `isInstall` tinyint(1) DEFAULT '0', `isGiftToken` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `inviteCode` (`inviteCode`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invoice_records` -- DROP TABLE IF EXISTS `invoice_records`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invoice_records` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` int NOT NULL, `invoice_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `amount` decimal(10,2) DEFAULT NULL, `date` date DEFAULT NULL, `image_link` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `created_at` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `invoicesAdmin` -- DROP TABLE IF EXISTS `invoicesAdmin`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `invoicesAdmin` ( `id` int NOT NULL AUTO_INCREMENT, `item_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `amount` decimal(10,2) NOT NULL, `image_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `kazan` -- DROP TABLE IF EXISTS `kazan`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `kazan` ( `id` int NOT NULL AUTO_INCREMENT, `country` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `kazan` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `comfortPrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `speedPrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `familyPrice` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `deliveryPrice` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `freePrice` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `latePrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `heavyPrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `adminId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `naturePrice` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fuelPrice` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `lisenceDetails` -- DROP TABLE IF EXISTS `lisenceDetails`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `lisenceDetails` ( `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `driverID` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `licenseClass` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `documentNo` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `height` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `postalCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `stateCode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `expireDate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `dateOfBirth` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `documentNo` (`documentNo`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `login_attempts` -- DROP TABLE IF EXISTS `login_attempts`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `login_attempts` ( `id` int NOT NULL AUTO_INCREMENT, `ip_address` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `attempt_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `login_attempts_drivers` -- DROP TABLE IF EXISTS `login_attempts_drivers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `login_attempts_drivers` ( `id` int NOT NULL AUTO_INCREMENT, `ip_address` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `attempt_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `mishwaritrips` -- DROP TABLE IF EXISTS `mishwaritrips`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `mishwaritrips` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `gender` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name_english` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `religion` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `age` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `startNameAddress` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none', `locationCoordinate` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none', `education` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `license_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `national_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `car_plate` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `make` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `color_hex` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `token` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `rating` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `countRide` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `passengerId` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `timeSelected` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'pending', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notesForDriverService` -- DROP TABLE IF EXISTS `notesForDriverService`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notesForDriverService` ( `id` int NOT NULL AUTO_INCREMENT, `phone` varchar(70) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `note` varchar(250) NOT NULL, `editor` varchar(50) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notesForPassengerService` -- DROP TABLE IF EXISTS `notesForPassengerService`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notesForPassengerService` ( `id` int NOT NULL AUTO_INCREMENT, `phone` int NOT NULL, `note` varchar(250) NOT NULL, `editor` varchar(50) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notificationCaptain` -- DROP TABLE IF EXISTS `notificationCaptain`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notificationCaptain` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `title` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `body` varchar(200) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `isShown` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'false', `isPin` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'unPin', `dateCreated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `notifications` -- DROP TABLE IF EXISTS `notifications`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `notifications` ( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(111) NOT NULL, `body` varchar(265) NOT NULL, `passenger_id` varchar(111) NOT NULL, `isShown` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'false', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `otp_verification_fingerPrint` -- DROP TABLE IF EXISTS `otp_verification_fingerPrint`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `otp_verification_fingerPrint` ( `id` int NOT NULL, `phone` varchar(20) NOT NULL, `otp` varchar(6) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `packageInfo` -- DROP TABLE IF EXISTS `packageInfo`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `packageInfo` ( `id` int NOT NULL AUTO_INCREMENT, `platform` varchar(50) NOT NULL, `appName` varchar(20) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `version` varchar(10) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `palces11` -- DROP TABLE IF EXISTS `palces11`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `palces11` ( `id` int NOT NULL AUTO_INCREMENT, `latitude` varchar(50) NOT NULL, `longitude` varchar(50) NOT NULL, `name` varchar(180) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `name_ar` varchar(200) NOT NULL, `name_en` varchar(200) NOT NULL, `address` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `category` varchar(55) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `location` point NOT NULL, PRIMARY KEY (`id`), SPATIAL KEY `idx_spatial_location` (`location`), FULLTEXT KEY `idx_fulltext_search` (`name`,`name_ar`,`name_en`,`address`,`category`) ) ENGINE=InnoDB AUTO_INCREMENT=28951 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passengerWallet` -- DROP TABLE IF EXISTS `passengerWallet`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passengerWallet` ( `id` int NOT NULL AUTO_INCREMENT, `passenger_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `balance` decimal(10,2) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `passenger_id` (`passenger_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passenger_blacklist` -- DROP TABLE IF EXISTS `passenger_blacklist`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passenger_blacklist` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `phone` varchar(150) NOT NULL, `phone_normalized` varchar(64) NOT NULL, `reason` varchar(255) DEFAULT NULL, `expires_at` datetime DEFAULT CURRENT_TIMESTAMP, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uq_phone_norm` (`phone_normalized`), KEY `idx_expires` (`expires_at`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passengerlocation` -- DROP TABLE IF EXISTS `passengerlocation`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passengerlocation` ( `id` int NOT NULL AUTO_INCREMENT, `passengerId` varchar(60) NOT NULL, `lat` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `lng` varchar(20) NOT NULL, `rideId` varchar(10) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `passengers` -- DROP TABLE IF EXISTS `passengers`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `passengers` ( `id` varchar(100) NOT NULL, `phone` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `email` varchar(255) NOT NULL, `password` varchar(100) NOT NULL, `gender` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `status` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'notDeleted', `birthdate` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL, `site` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `sosPhone` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'sos', `education` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'none', `employmentType` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'none', `maritalStatus` varchar(150) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'none', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `phone` (`phone`,`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `payment_tokens` -- DROP TABLE IF EXISTS `payment_tokens`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `payment_tokens` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(255) NOT NULL, `driverID` varchar(255) NOT NULL, `dateCreated` datetime NOT NULL, `amount` decimal(10,2) NOT NULL, `isUsed` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `payment_tokens_passenger` -- DROP TABLE IF EXISTS `payment_tokens_passenger`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `payment_tokens_passenger` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(255) NOT NULL, `passengerId` varchar(255) NOT NULL, `dateCreated` datetime NOT NULL, `amount` decimal(10,2) NOT NULL, `isUsed` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `payments` -- DROP TABLE IF EXISTS `payments`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `payments` ( `id` varchar(111) NOT NULL, `amount` decimal(10,2) NOT NULL, `payment_method` varchar(255) NOT NULL, `passengerID` varchar(100) NOT NULL, `rideId` varchar(100) NOT NULL, `driverID` varchar(100) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `isGiven` varchar(20) NOT NULL DEFAULT 'waiting', PRIMARY KEY (`id`), UNIQUE KEY `rideId` (`rideId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `paymentsDriverPoints` -- DROP TABLE IF EXISTS `paymentsDriverPoints`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `paymentsDriverPoints` ( `id` int NOT NULL AUTO_INCREMENT, `amount` decimal(10,2) NOT NULL, `payment_method` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `driverID` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` datetime DEFAULT CURRENT_TIMESTAMP, `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `phone_verification` -- DROP TABLE IF EXISTS `phone_verification`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `phone_verification` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `driverId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'yet', `email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'yet', `token_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `expiration_time` datetime NOT NULL, `is_verified` tinyint(1) DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=111 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `phone_verification_passenger` -- DROP TABLE IF EXISTS `phone_verification_passenger`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `phone_verification_passenger` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `token` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `expiration_time` datetime NOT NULL, `verified` tinyint(1) DEFAULT '0', `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `status` varchar(22) NOT NULL DEFAULT 'yet', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `places` -- DROP TABLE IF EXISTS `places`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `places` ( `id` int NOT NULL AUTO_INCREMENT, `latitude` double NOT NULL, `longitude` double NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `name_ar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `name_en` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=58830 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `placesEgypt` -- DROP TABLE IF EXISTS `placesEgypt`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `placesEgypt` ( `id` int NOT NULL, `nameEnglish` varchar(255) DEFAULT NULL, `nameArabic` varchar(255) DEFAULT NULL, `phone` varchar(20) DEFAULT NULL, `countReview` int DEFAULT NULL, `rate` float DEFAULT NULL, `stars` varchar(50) DEFAULT NULL, `address` text, `website` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `PlusCode` varchar(50) DEFAULT NULL, `closeTime` varchar(50) DEFAULT NULL, `latitude` decimal(10,6) DEFAULT NULL, `longitude` decimal(10,6) DEFAULT NULL, `instagram` varchar(255) DEFAULT NULL, `facebook` varchar(255) DEFAULT NULL, `linkedin` varchar(255) DEFAULT NULL, `twitter` varchar(255) DEFAULT NULL, `photo` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `promos` -- DROP TABLE IF EXISTS `promos`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `promos` ( `id` int NOT NULL AUTO_INCREMENT, `promo_code` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `amount` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0', `description` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL, `passengerID` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'none', `validity_start_date` date DEFAULT NULL, `validity_end_date` date DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `passengerID` (`passengerID`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `promptDriverIDEgypt` -- DROP TABLE IF EXISTS `promptDriverIDEgypt`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `promptDriverIDEgypt` ( `id` int NOT NULL AUTO_INCREMENT, `type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `prompt` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ratingApp` -- DROP TABLE IF EXISTS `ratingApp`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ratingApp` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `email` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `phone` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `userType` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rating` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `comment` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ratingDriver` -- DROP TABLE IF EXISTS `ratingDriver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ratingDriver` ( `id` int NOT NULL AUTO_INCREMENT, `passenger_id` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci, `driver_id` varchar(33) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `ride_id` int DEFAULT NULL, `rating` float DEFAULT NULL, `comment` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `ride_id` (`ride_id`), KEY `idx_driver_id` (`driver_id`) ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ratingPassenger` -- DROP TABLE IF EXISTS `ratingPassenger`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ratingPassenger` ( `id` int NOT NULL AUTO_INCREMENT, `passenger_id` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideId` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rating` float NOT NULL, `comment` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `rideId` (`rideId`) ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `ride` -- DROP TABLE IF EXISTS `ride`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `ride` ( `id` int NOT NULL AUTO_INCREMENT, `start_location` varchar(255) NOT NULL, `end_location` varchar(255) NOT NULL, `date` date NOT NULL, `time` time NOT NULL, `endtime` time NOT NULL, `price` decimal(10,2) NOT NULL DEFAULT '0.00', `passenger_id` varchar(111) NOT NULL, `driver_id` varchar(111) NOT NULL, `status` varchar(200) NOT NULL DEFAULT 'nothing', `paymentMethod` varchar(20) NOT NULL DEFAULT 'Cash', `carType` varchar(20) NOT NULL DEFAULT 'Speed', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `DriverIsGoingToPassenger` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `rideTimeStart` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `rideTimeFinish` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `price_for_driver` decimal(10,2) NOT NULL DEFAULT '0.00', `price_for_passenger` decimal(10,2) NOT NULL DEFAULT '0.00', `distance` float DEFAULT '0', PRIMARY KEY (`id`), KEY `passengerfk` (`passenger_id`), KEY `driverfk` (`driver_id`) ) ENGINE=InnoDB AUTO_INCREMENT=831 DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `seferWallet` -- DROP TABLE IF EXISTS `seferWallet`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `seferWallet` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(100) NOT NULL, `passengerId` varchar(100) NOT NULL, `amount` varchar(10) NOT NULL, `paymentMethod` varchar(50) NOT NULL, `token` varchar(100) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `server_locations` -- DROP TABLE IF EXISTS `server_locations`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `server_locations` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `min_latitude` decimal(10,6) NOT NULL, `max_latitude` decimal(10,6) NOT NULL, `min_longitude` decimal(10,6) NOT NULL, `max_longitude` decimal(10,6) NOT NULL, `server_link` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `smsSender` -- DROP TABLE IF EXISTS `smsSender`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `smsSender` ( `id` int NOT NULL AUTO_INCREMENT, `senderId` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `test` -- DROP TABLE IF EXISTS `test`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `test` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `testApp` -- DROP TABLE IF EXISTS `testApp`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `testApp` ( `id` int NOT NULL AUTO_INCREMENT, `isTest` tinyint(1) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `appPlatform` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `tips` -- DROP TABLE IF EXISTS `tips`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `tips` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `rideID` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `tipAmount` decimal(10,2) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `token_verification` -- DROP TABLE IF EXISTS `token_verification`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `token_verification` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expiration_time` datetime NOT NULL, `verified` tinyint(1) DEFAULT '0', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `token_verification_admin` -- DROP TABLE IF EXISTS `token_verification_admin`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `token_verification_admin` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `token` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expiration_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `phone_number` (`phone_number`) ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `token_verification_driver` -- DROP TABLE IF EXISTS `token_verification_driver`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `token_verification_driver` ( `id` int NOT NULL AUTO_INCREMENT, `phone_number` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `token` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `expiration_time` datetime NOT NULL, `verified` tinyint(1) NOT NULL DEFAULT '0', `created_at` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `tokens` -- DROP TABLE IF EXISTS `tokens`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `tokens` ( `id` int NOT NULL AUTO_INCREMENT, `token` varchar(333) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `passengerID` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `fingerPrint` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `status` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'yet', PRIMARY KEY (`id`), UNIQUE KEY `passengerID` (`passengerID`) ) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `users` -- DROP TABLE IF EXISTS `users`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `users` ( `id` varchar(111) NOT NULL, `phone` varchar(15) NOT NULL, `email` varchar(255) NOT NULL, `gender` varchar(10) NOT NULL, `password` varchar(100) NOT NULL, `birthdate` date NOT NULL, `site` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, `last_name` varchar(255) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_type` varchar(44) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`), UNIQUE KEY `phone` (`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `vehicles` -- DROP TABLE IF EXISTS `vehicles`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `vehicles` ( `id` int NOT NULL AUTO_INCREMENT, `driverID` varchar(100) NOT NULL, `make` varchar(255) NOT NULL, `model` varchar(255) NOT NULL, `license_plate` varchar(255) NOT NULL, `seats` int NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `license_plate` (`license_plate`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `videos` -- DROP TABLE IF EXISTS `videos`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `videos` ( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `description` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `url` varchar(150) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `waitingRides` -- DROP TABLE IF EXISTS `waitingRides`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `waitingRides` ( `id` varchar(100) NOT NULL, `start_location` varchar(255) NOT NULL, `end_location` varchar(255) NOT NULL, `date` date NOT NULL, `time` time NOT NULL, `price` decimal(10,2) NOT NULL DEFAULT '0.00', `passenger_id` varchar(111) NOT NULL, `status` varchar(200) NOT NULL DEFAULT 'nothing', `carType` varchar(19) NOT NULL, `passengerRate` decimal(10,2) NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `price_for_passenger` decimal(10,2) NOT NULL DEFAULT '0.00', `distance` varchar(255) NOT NULL, `duration` varchar(10) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `welcomeDriverCall` -- DROP TABLE IF EXISTS `welcomeDriverCall`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `welcomeDriverCall` ( `id` int NOT NULL AUTO_INCREMENT, `driverId` varchar(50) NOT NULL, `isCall` tinyint(1) NOT NULL DEFAULT '0', `notes` varchar(255) NOT NULL, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Table structure for table `write_argument_after_applied_from_background` -- DROP TABLE IF EXISTS `write_argument_after_applied_from_background`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `write_argument_after_applied_from_background` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `ride_id` varchar(50) NOT NULL, `driver_id` varchar(50) NOT NULL, `passenger_id` varchar(50) NOT NULL, `passenger_location` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `passenger_destination` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `duration` varchar(255) NOT NULL, `duration_to_passenger` varchar(255) NOT NULL, `duration_of_ride` varchar(255) NOT NULL, `distance` varchar(255) NOT NULL, `total_cost` varchar(255) NOT NULL, `payment_amount` varchar(255) NOT NULL, `payment_method` enum('visa','cash') NOT NULL, `wallet_checked` varchar(255) NOT NULL, `has_steps` varchar(255) NOT NULL, `step0` varchar(255) DEFAULT NULL, `step1` varchar(255) DEFAULT NULL, `step2` varchar(255) DEFAULT NULL, `step3` varchar(255) DEFAULT NULL, `step4` varchar(255) DEFAULT NULL, `passenger_wallet_burc` varchar(33) NOT NULL, `token_passenger` varchar(255) NOT NULL, `name` varchar(100) NOT NULL, `phone` varchar(20) NOT NULL, `email` varchar(150) NOT NULL, `start_name_location` varchar(255) NOT NULL, `end_name_location` varchar(255) NOT NULL, `car_type` varchar(50) NOT NULL, `kazan` varchar(255) NOT NULL, `direction_url` text NOT NULL, `time_of_order` datetime NOT NULL, `total_passenger` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping events for database 'intaleq-ridesDB' -- -- -- Dumping routines for database 'intaleq-ridesDB' -- /*!50112 SET @disable_bulk_load = IF (@is_rocksdb_supported, 'SET SESSION rocksdb_bulk_load = @old_rocksdb_bulk_load', 'SET @dummy_rocksdb_bulk_load = 0') */; /*!50112 PREPARE s FROM @disable_bulk_load */; /*!50112 EXECUTE s */; /*!50112 DEALLOCATE PREPARE s */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2026-04-22 20:58:51 ``` ## File: encrypt_decrypt.php ``` key = $key; $this->iv = $iv; } // --------- النصوص ---------- private function addPadding($data, $blockSize = 16) { $pad = $blockSize - (strlen($data) % $blockSize); return $data . str_repeat(chr($pad), $pad); } private function removePadding($data) { $pad = ord($data[strlen($data) - 1]); return substr($data, 0, -$pad); } public function encryptData($plainText) { $plainText = mb_convert_encoding($plainText, 'UTF-8'); $paddedText = $this->addPadding($plainText); $encrypted = openssl_encrypt($paddedText, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv); return base64_encode($encrypted); } public function decryptData($encryptedText) { $decoded = base64_decode($encryptedText, true); if ($decoded === false) { error_log("[ERROR] base64_decode failed for input: $encryptedText"); return false; } $decrypted = openssl_decrypt($decoded, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv); if ($decrypted === false) { error_log("[ERROR] openssl_decrypt failed for input: $encryptedText"); return false; } // Verify padding is valid before removal $pad = ord($decrypted[strlen($decrypted) - 1]); if ($pad < 1 || $pad > 16) { error_log("[ERROR] Invalid padding value ($pad) for decrypted input: $encryptedText"); return false; } return substr($decrypted, 0, -$pad); } public function decryptFile($encryptedFilePath, $destinationPath) { if (!file_exists($encryptedFilePath)) { throw new Exception("❌ الملف المشفر غير موجود: $encryptedFilePath"); } $encryptedData = file_get_contents($encryptedFilePath); $decryptedData = openssl_decrypt($encryptedData, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv); file_put_contents($destinationPath, $decryptedData); return true; } public function encryptBinary($data) { $encrypted = openssl_encrypt($data, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv); return $encrypted; } public function decryptBinary($data) { $decrypted = openssl_decrypt($data, 'AES-256-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv); return $decrypted; } } // ✅ Load the key and IV from .env or use default values // ✅ Ensure the lengths are correct //echo "Key Length: " . $key . PHP_EOL; //echo "IV Length: " . $iv . PHP_EOL; try { $encryptionHelper = new EncryptionHelper($key, $iv); } catch (Exception $e) { echo "Error: " . $e->getMessage() . PHP_EOL; } ?> ``` ## File: core/bootstrap.php ``` connect($redisHost, $redisPort, 1.5)) { if ($redisPass) $redis->auth($redisPass); $redis->setOption(Redis::OPT_PREFIX, 'siro:'); } else { $redis = null; } } } catch (Exception $e) { error_log("[REDIS] Connection failed: " . $e->getMessage()); $redis = null; } // 5. تحميل الـ Services الأساسية require_once __DIR__ . '/Security/EncryptionHelper.php'; require_once __DIR__ . '/Database/Database.php'; require_once __DIR__ . '/Auth/RateLimiter.php'; require_once __DIR__ . '/Auth/JwtService.php'; // لا نحمّل OtpService و FcmService إلا عند الحاجة (Lazy) // 6. تهيئة Encryption Helper العام (للتوافقية) $secretKey = trim(@file_get_contents('/home/siro-api/.secret_key')) ?: getenv('SECRET_KEY'); if (!$secretKey) { error_log("[FATAL] Secret key is missing."); http_response_code(500); exit(json_encode(['error' => 'Server configuration error'])); } $encryptionHelper = new EncryptionHelper($secretKey); ``` ## File: core/helpers.php ``` filter_var($value, FILTER_VALIDATE_INT) !== false ? (int)$value : null, 'float' => filter_var($value, FILTER_VALIDATE_FLOAT) !== false ? (float)$value : null, 'email' => filter_var($value, FILTER_VALIDATE_EMAIL) ?: null, 'url' => filter_var($value, FILTER_VALIDATE_URL) ?: null, 'bool' => filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), default => $value, // string — بدون htmlspecialchars (نتركه لـ PDO) }; } // ── ردود JSON موحدة ───────────────────────────────────────── function jsonSuccess(mixed $data = null, string $message = 'success', int $code = 200): never { http_response_code($code); $response = ['status' => 'success']; if ($message !== 'success') $response['message'] = $message; if ($data !== null) $response['data'] = $data; echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } function jsonError(string $message, int $code = 400, mixed $extra = null): never { http_response_code($code); $response = ['status' => 'error', 'message' => $message]; if ($extra !== null) $response['details'] = $extra; echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } // (للتوافق مع الكود القديم) function printSuccess(string $message = 'success'): void { echo json_encode(['status' => 'success', 'message' => $message], JSON_UNESCAPED_UNICODE); } function printFailure(string $message = 'failure'): void { echo json_encode(['status' => 'failure', 'message' => $message], JSON_UNESCAPED_UNICODE); } function result(int $count): void { if ($count > 0) { printSuccess(); } else { printFailure(); } } function sendEmail(string $from, string $to, string $title, string $body): void { $header = "From: $from\nCC: $from"; mail($to, $title, $body, $header); } // ── رفع صورة آمن ────────────────────────────────────────────── function uploadImageSecure( string $fileKey, string $targetDir, string $prefix = '', array $allowedMimes = ['image/jpeg', 'image/png', 'image/webp'] ): array { if (!isset($_FILES[$fileKey]) || $_FILES[$fileKey]['error'] !== UPLOAD_ERR_OK) { return ['success' => false, 'error' => 'File upload error']; } $file = $_FILES[$fileKey]; $maxSize = 5 * 1024 * 1024; // 5MB // حجم الملف if ($file['size'] > $maxSize) { return ['success' => false, 'error' => 'File too large (max 5MB)']; } // MIME validation حقيقي (ليس extension فقط) $finfo = new finfo(FILEINFO_MIME_TYPE); $mimeType = $finfo->file($file['tmp_name']); if (!in_array($mimeType, $allowedMimes, true)) { return ['success' => false, 'error' => "Invalid file type: $mimeType"]; } // اسم ملف آمن وعشوائي $ext = match ($mimeType) { 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp', default => 'bin', }; $filename = ($prefix ? "{$prefix}_" : '') . bin2hex(random_bytes(8)) . ".$ext"; if (!is_dir($targetDir)) { mkdir($targetDir, 0750, true); } $targetPath = rtrim($targetDir, '/') . '/' . $filename; if (!move_uploaded_file($file['tmp_name'], $targetPath)) { return ['success' => false, 'error' => 'Failed to move uploaded file']; } return ['success' => true, 'filename' => $filename, 'path' => $targetPath]; } // ── تحميل ملف .env ─────────────────────────────────────────── function loadEnvironment(string $path): void { if (!file_exists($path)) { error_log("[ENV] File not found: $path"); return; } $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line) { if (str_starts_with(trim($line), '#')) continue; if (!str_contains($line, '=')) continue; [$key, $value] = explode('=', $line, 2); $key = trim($key); $value = trim($value, " \t\n\r\0\x0B\"'"); if ($key && !getenv($key)) { putenv("$key=$value"); $_ENV[$key] = $value; } } } // ── Logging منظم ────────────────────────────────────────────── function securityLog(string $message, array $context = []): void { $entry = date('Y-m-d H:i:s') . ' [SECURITY] ' . $message; if ($context) $entry .= ' | ' . json_encode($context, JSON_UNESCAPED_UNICODE); error_log($entry, 3, '/home/siro-api/logs/security.log'); } function appLog(string $message, string $level = 'INFO'): void { $entry = date('Y-m-d H:i:s') . " [$level] " . $message; error_log($entry, 3, '/home/siro-api/logs/app.log'); } function debugLog(string $message): void { appLog($message, 'DEBUG'); } ``` ## File: core/Database/Database.php ``` 'dbname', // متغير ENV لاسم DB الرئيسي 'tracking' => 'dbname_track', // متغير ENV لقاعدة التتبع 'ride' => 'dbname_ride', // متغير ENV لقاعدة الرحلات ]; public static function get(string $name = 'main'): PDO { if (!isset(self::$instances[$name])) { self::$instances[$name] = self::connect($name); } return self::$instances[$name]; } private static function connect(string $name): PDO { if (!isset(self::$map[$name])) { throw new InvalidArgumentException("Unknown database: $name"); } $dbEnvKey = self::$map[$name]; $dbname = getenv($dbEnvKey); $user = getenv('USER'); $pass = getenv('PASS'); $host = getenv('DB_HOST') ?: 'localhost'; if (!$dbname || !$user) { throw new RuntimeException("Database config missing for: $name"); } $dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4"; $options = [ PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_PERSISTENT => true, // connection reuse PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci", PDO::ATTR_TIMEOUT => 10, ]; try { return new PDO($dsn, $user, $pass, $options); } catch (PDOException $e) { error_log("[DB] Connection failed ($name): " . $e->getMessage()); throw $e; } } // منع الاستنساخ private function __construct() {} private function __clone() {} } ``` ## File: core/Security/EncryptionHelper.php ``` key = $key; // IV القديم للتوافقية أثناء مرحلة المايغريشن $this->cbcIv = $cbcIv ?: getenv('initializationVector') ?: str_repeat('0', 16); } // ─── تشفير نص (CBC مؤقتاً للتوافق التام كما طلب المستخدم) ── // سيتم تغييره لاحقاً لـ GCM بعد تفريغ قاعدة البيانات القديمة public function encryptData(string $plainText): string { // بناءً على طلب المستخدم: إبقاء التشفير الحالي CBC حتى نقوم بالترحيل لاحقاً $plainText = mb_convert_encoding($plainText, 'UTF-8'); $paddedText = $this->addPadding($plainText); $encrypted = openssl_encrypt($paddedText, self::ALGO_CBC, $this->key, OPENSSL_RAW_DATA, $this->cbcIv); return base64_encode($encrypted); } // ─── فك تشفير نص (يدعم CBC والـ GCM المستقبلي) ─────────── public function decryptData(string $cipherText): string|false { // تحقق إن كان مشفر بالنظام الجديد if (str_starts_with($cipherText, self::PREFIX_GCM)) { $raw = base64_decode(substr($cipherText, strlen(self::PREFIX_GCM)), true); if ($raw === false || strlen($raw) < self::IV_LEN_GCM + self::TAG_LEN) return false; $iv = substr($raw, 0, self::IV_LEN_GCM); $tag = substr($raw, self::IV_LEN_GCM, self::TAG_LEN); $cipher = substr($raw, self::IV_LEN_GCM + self::TAG_LEN); $plain = openssl_decrypt($cipher, self::ALGO_GCM, $this->key, OPENSSL_RAW_DATA, $iv, $tag); return $plain !== false ? $plain : false; } // وإلا استخدم CBC القديم $decoded = base64_decode($cipherText, true); if ($decoded === false) return false; $decrypted = openssl_decrypt($decoded, self::ALGO_CBC, $this->key, OPENSSL_RAW_DATA, $this->cbcIv); if ($decrypted === false) return false; $pad = ord($decrypted[strlen($decrypted) - 1]); if ($pad < 1 || $pad > 16) return false; return substr($decrypted, 0, -$pad); } // ─── تشفير/فك تشفير Binary (صور، ملفات) ─────────────── public function encryptBinary(string $data): string { return openssl_encrypt($data, self::ALGO_CBC, $this->key, OPENSSL_RAW_DATA, $this->cbcIv); } public function decryptBinary(string $data): string|false { return openssl_decrypt($data, self::ALGO_CBC, $this->key, OPENSSL_RAW_DATA, $this->cbcIv); } // --------- دوال الـ Padding للـ CBC ---------- private function addPadding($data, $blockSize = 16) { $pad = $blockSize - (strlen($data) % $blockSize); return $data . str_repeat(chr($pad), $pad); } private function removePadding($data) { $pad = ord($data[strlen($data) - 1]); return substr($data, 0, -$pad); } } ``` ## File: core/Auth/JwtService.php ``` secretKey = trim(file_get_contents('/home/siro-api/.secret_key')); $this->hmacSecret = getenv('SECRET_KEY_HMAC') ?: ''; $this->fpPepper = getenv('FP_PEPPER') ?: ''; $this->issuer = getenv('APP_ISSUER') ; $this->redis = $redis; } // ── توليد Access Token ────────────────────────────────── public function generateAccessToken( int|string $userId, string $role, string $audience, ?string $fingerprint = null ): string { $jti = bin2hex(random_bytes(16)); $payload = [ 'iss' => $this->issuer, 'aud' => $audience, 'user_id' => $userId, 'role' => $role, 'token_type' => 'access', 'jti' => $jti, 'iat' => time(), 'exp' => time() + self::ACCESS_TTL, ]; if ($fingerprint && $this->fpPepper) { $payload['fingerPrint'] = hash('sha256', $fingerprint . $this->fpPepper); } return JWT::encode($payload, $this->secretKey, self::ALGO); } // ── توليد Refresh Token ───────────────────────────────── public function generateRefreshToken(int|string $userId): array { $token = bin2hex(random_bytes(32)); $exp = time() + self::REFRESH_TTL; // تخزين في Redis if ($this->redis) { $this->redis->setex( "refresh:{$userId}:{$token}", self::REFRESH_TTL, json_encode(['user_id' => $userId, 'created_at' => time()]) ); } return ['token' => $token, 'expires_at' => $exp]; } // ── التحقق الكامل من التوكن ──────────────────────────── public function authenticate(): object { // 1. استخراج التوكن $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; $token = null; if (preg_match('/Bearer\s(\S+)/', $authHeader, $m)) { $token = $m[1]; } if (!$token) { self::abort(401, 'Authorization token required'); } // 2. Decode try { $decoded = JWT::decode($token, new Key($this->secretKey, self::ALGO)); } catch (ExpiredException $e) { self::abort(401, 'Token expired'); } catch (SignatureInvalidException $e) { self::abort(401, 'Invalid token signature'); } catch (BeforeValidException $e) { self::abort(401, 'Token not yet valid'); } catch (Exception $e) { self::abort(401, 'Invalid token'); } // 3. Issuer if (($decoded->iss ?? '') !== $this->issuer) { self::abort(401, 'Invalid token issuer'); } // 4. User ID $userId = $decoded->user_id ?? $decoded->sub ?? null; if (!$userId) { self::abort(401, 'Invalid JWT payload'); } // 5. JTI Blacklist (تحقق من توكنات ملغاة) $jti = $decoded->jti ?? null; if ($jti && $this->redis) { if ($this->redis->exists("jwt:blacklist:$jti")) { self::abort(401, 'Token has been revoked'); } } // 6. token_type — قيّد registration endpoints $tokenType = $decoded->token_type ?? 'access'; if ($tokenType === 'registration' || $tokenType === 'new') { $currentFile = basename($_SERVER['PHP_SELF'], '.php'); $allowed = false; foreach (self::REGISTRATION_ENDPOINTS as $ep) { if (strcasecmp($currentFile, $ep) === 0) { $allowed = true; break; } } if (!$allowed) { error_log("[SECURITY] Registration token blocked on: $currentFile | user: $userId"); self::abort(403, 'Token not authorized for this action'); } } // 7. Device Fingerprint (إلزامي للـ Access Tokens) if ($this->fpPepper && $tokenType === 'access') { $fpInToken = $decoded->fingerPrint ?? null; $fpHeader = $_SERVER['HTTP_X_DEVICE_FP'] ?? null; if ($fpInToken === null || $fpHeader === null) { error_log("[SECURITY] Fingerprint missing | user: $userId"); self::abort(403, 'Device verification required'); } $expected = hash('sha256', $fpHeader . $this->fpPepper); if (!hash_equals($expected, $fpInToken)) { error_log("[SECURITY] Device mismatch | user: $userId | IP: " . ($_SERVER['REMOTE_ADDR'] ?? '?')); self::abort(403, 'Device mismatch'); } } // 8. HMAC — مطلوب للعمليات الحساسة (Wallet/Logout) $hmacHeader = $_SERVER['HTTP_X_HMAC_AUTH'] ?? null; if ($hmacHeader !== null) { $timestamp = $_SERVER['HTTP_X_TIMESTAMP'] ?? ''; $nonce = $_SERVER['HTTP_X_NONCE'] ?? ''; $body = file_get_contents('php://input') ?: ''; // التوقيع يضم الـ Body + Timestamp + Nonce لمنع التكرار والتلاعب $payloadToSign = $body . $timestamp . $nonce; $expectedHmac = hash_hmac('sha256', $payloadToSign, $this->hmacSecret); if (!hash_equals($expectedHmac, $hmacHeader)) { error_log("[SECURITY] HMAC mismatch | user: $userId | IP: " . ($_SERVER['REMOTE_ADDR'] ?? '?')); self::abort(403, 'Invalid HMAC signature'); } } return $decoded; } // ── إلغاء توكن (Logout / Password Change) ────────────── public function revokeToken(string $jti, int $remainingTTL = 900): void { if ($this->redis && $jti) { $this->redis->setex("jwt:blacklist:$jti", $remainingTTL + 60, '1'); } } // ── Internal API Key — للـ get_connect.php ───────────── public static function validateInternalKey(): void { $keyPath = '/home/siro-api/.internal_socket_key'; $sent = $_SERVER['HTTP_X_INTERNAL_KEY'] ?? ''; $expected = file_exists($keyPath) ? trim(file_get_contents($keyPath)) : ''; if (!$expected || !hash_equals($expected, $sent)) { error_log('[SECURITY] Invalid internal key from: ' . ($_SERVER['REMOTE_ADDR'] ?? '?')); http_response_code(403); echo json_encode(['error' => 'Unauthorized internal request']); exit; } } private static function abort(int $code, string $message): never { http_response_code($code); echo json_encode(['error' => $message]); exit; } } ``` ## File: core/Auth/RateLimiter.php ``` ['requests' => 5, 'window' => 60], // 5 محاولات / دقيقة 'otp' => ['requests' => 3, 'window' => 300], // 3 محاولات / 5 دقائق 'register' => ['requests' => 3, 'window' => 3600], // 3 محاولات / ساعة 'api' => ['requests' => 120, 'window' => 60], // 120 طلب / دقيقة 'ride' => ['requests' => 30, 'window' => 60], // 30 طلب / دقيقة 'upload' => ['requests' => 10, 'window' => 300], // 10 رفع / 5 دقائق ]; public function __construct(?Redis $redis) { $this->redis = $redis; } // ── فحص الحد ───────────────────────────────────────────── // $identifier: IP:userId أو IP فقط // $type: login | otp | api | ride | upload public function check(string $identifier, string $type = 'api'): bool { if (!$this->redis) { return true; // بدون Redis نمرر (fallback) } $limit = self::LIMITS[$type] ?? self::LIMITS['api']; $window = $limit['window']; $max = $limit['requests']; $key = "rate:{$type}:{$identifier}"; $current = $this->redis->incr($key); if ($current === 1) { $this->redis->expire($key, $window); } return $current <= $max; } // ── تطبيق الحد وإيقاف الطلب إن تجاوز ───────────────────── public function enforce(string $identifier, string $type = 'api'): void { if (!$this->check($identifier, $type)) { $limit = self::LIMITS[$type] ?? self::LIMITS['api']; $window = $limit['window']; error_log("[RATE_LIMIT] Blocked: $identifier | type: $type"); http_response_code(429); header("Retry-After: $window"); echo json_encode([ 'error' => 'Too many requests. Please slow down.', 'retry_after' => $window, ]); exit; } } // ── بناء معرّف المستخدم ──────────────────────────────────── public static function identifier(?string $userId = null): string { $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; return $userId ? "{$ip}:{$userId}" : $ip; } // ── إعادة تعيين عداد (مثلاً بعد تسجيل دخول ناجح) ─────────── public function reset(string $identifier, string $type = 'login'): void { if ($this->redis) { $this->redis->del("rate:{$type}:{$identifier}"); } } } ``` ## File: core/Services/OtpService.php ``` redis = $redis; } // ── توليد وحفظ OTP ───────────────────────────────────── public function generate(string $phone): string { // OTP آمن (6 أرقام عشوائية) $otp = str_pad((string)random_int(100000, 999999), 6, '0', STR_PAD_LEFT); if ($this->redis) { $key = "otp:{$phone}"; $this->redis->setex($key, self::OTP_TTL, password_hash($otp, PASSWORD_BCRYPT)); // إعادة تعيين عداد المحاولات $this->redis->del("otp:attempts:{$phone}"); } return $otp; } // ── التحقق من OTP ─────────────────────────────────────── public function verify(string $phone, string $inputOtp): bool { if (!$this->redis) return false; // فحص الـ lockout if ($this->redis->exists("otp:locked:{$phone}")) { return false; } $key = "otp:{$phone}"; $stored = $this->redis->get($key); if (!$stored) { return false; // انتهت صلاحية الـ OTP } $attemptsKey = "otp:attempts:{$phone}"; if (!password_verify($inputOtp, $stored)) { $attempts = $this->redis->incr($attemptsKey); $this->redis->expire($attemptsKey, self::OTP_TTL); if ($attempts >= self::MAX_ATTEMPTS) { // قفل لمدة 30 دقيقة $this->redis->setex("otp:locked:{$phone}", self::LOCKOUT_TTL, '1'); $this->redis->del($key); } return false; } // نجح التحقق — احذف الـ OTP $this->redis->del($key); $this->redis->del($attemptsKey); return true; } // ── فحص هل الرقم مقفل ────────────────────────────────── public function isLocked(string $phone): bool { return $this->redis && (bool)$this->redis->exists("otp:locked:{$phone}"); } } ``` ## File: core/Services/FcmService.php ``` redis = $redis; // المسار بناء على بنية المشروع $this->serviceAccountFile = __DIR__ . '/../../service-account.json'; } // ── إرسال إشعار ──────────────────────────────────────── public function send( string $token, string $title, string $body, array $data = [], string $category = 'Order', string $tone = 'ding' ): array { $accessToken = $this->getAccessToken(); if (!$accessToken) { return ['status' => 'error', 'message' => 'No access token']; } if (!file_exists($this->serviceAccountFile)) { return ['status' => 'error', 'message' => 'Service account file missing']; } $creds = json_decode(file_get_contents($this->serviceAccountFile), true); $projectId = $creds['project_id']; $fcmUrl = "https://fcm.googleapis.com/v1/projects/$projectId/messages:send"; $finalData = array_merge($data, [ 'title' => $title, 'body' => $body, 'tone' => $tone, 'category' => $category, 'type' => $category, ]); // FCM يشترط أن تكون كل القيم strings $processedData = array_map( fn($v) => is_array($v) || is_object($v) ? json_encode($v, JSON_UNESCAPED_UNICODE) : (string)$v, $finalData ); $payload = [ 'message' => [ 'token' => $token, 'data' => $processedData, 'android' => ['priority' => 'HIGH'], 'apns' => [ 'headers' => ['apns-priority' => '10', 'apns-push-type' => 'background'], 'payload' => ['aps' => ['content-available' => 1]], ], ], ]; $ch = curl_init($fcmUrl); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer $accessToken", 'Content-Type: application/json; charset=UTF-8', ], CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, CURLOPT_CONNECTTIMEOUT => 3, CURLOPT_FRESH_CONNECT => false, // إعادة استخدام الاتصال CURLOPT_FORBID_REUSE => false, CURLOPT_TCP_KEEPALIVE => 1, ]); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlErr = curl_errno($ch); curl_close($ch); if ($curlErr) { return ['status' => 'error', 'message' => 'CURL error']; } return $httpCode === 200 ? ['status' => 'success'] : ['status' => 'error', 'code' => $httpCode, 'response' => $result]; } // ── Access Token مع Redis Cache ───────────────────────── private function getAccessToken(): ?string { // 1. من Redis if ($this->redis) { $cached = $this->redis->get('google_fcm_access_token'); if ($cached) return $cached; } // 2. طلب جديد $token = $this->fetchGoogleToken(); if ($token && $this->redis) { $this->redis->setex('google_fcm_access_token', 3500, $token); } return $token; } private function fetchGoogleToken(): ?string { if (!file_exists($this->serviceAccountFile)) return null; $creds = json_decode(file_get_contents($this->serviceAccountFile), true); $clientEmail = $creds['client_email']; $privateKey = $creds['private_key']; $now = time(); $header = rtrim(strtr(base64_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT'])), '+/', '-_'), '='); $claim = rtrim(strtr(base64_encode(json_encode([ 'iss' => $clientEmail, 'scope' => 'https://www.googleapis.com/auth/firebase.messaging', 'aud' => 'https://oauth2.googleapis.com/token', 'exp' => $now + 3600, 'iat' => $now, ])), '+/', '-_'), '='); $signature = ''; openssl_sign("$header.$claim", $signature, $privateKey, 'SHA256'); $jwt = "$header.$claim." . rtrim(strtr(base64_encode($signature), '+/', '-_'), '='); $ch = curl_init('https://oauth2.googleapis.com/token'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query([ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt, ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, ]); $res = curl_exec($ch); curl_close($ch); return json_decode($res, true)['access_token'] ?? null; } } ``` ## File: webhook_sms/webhook.php ``` 'error', 'message' => 'Unauthorized Access']); exit(); } // --- 2. قراءة البيانات المرسلة --- $json_data = file_get_contents('php://input'); $data = json_decode($json_data, true); if ($data === null || !isset($data['sender']) || !isset($data['message'])) { http_response_code(400); echo json_encode(['status' => 'error', 'message' => 'Invalid data received']); exit(); } // --- 3. استخراج البيانات والتحضير للمعالجة --- $sender = $data['sender']; $message_body = $data['message']; $received_at = date('Y-m-d H:i:s'); $log_entry = "[$received_at] From: $sender | Message: $message_body"; // --- 4. تحليل الرسالة (يركز على Orange Money فقط حالياً) --- // تعريف المتغيرات التي سنستخرجها $amount = 0; $payer_phone = null; $currency = null; // النمط الوحيد الفعّال حالياً: لرسائل Orange Money الأردنية $pattern_orangemoney_jo = '/تم استقبال حوالة مالية من (\d+)\s+من مزود الخدمة:\s+Orange Money إلى محفظتك بمبلغ ([\d,.]+)\s+دينار/'; /* // أنماط أخرى يمكن تفعيلها لاحقاً // $pattern_chambank = '/حوالة واردة خارجية بمبلغ\s+([\d,.]+)\s+ليرة سورية/'; // $pattern_wallet_syr = '/تم استلام مبلغ ([\d,.]+) ل\.س من الرقم (09\d{8})/'; */ if (preg_match($pattern_orangemoney_jo, $message_body, $matches)) { // --- تطابق نمط Orange Money الأردني --- $payer_phone = $matches[1]; $amount_str = $matches[2]; $amount = (float) str_replace(',', '', $amount_str); $currency = 'JOD'; // دينار أردني $log_entry .= " | MATCH: Orange Money JO | SUCCESS: Parsed Amount = $amount, Payer Phone = $payer_phone, Currency = $currency" . PHP_EOL; // TODO: اكتب منطق قاعدة البيانات هنا /* - ابحث عن معاملة "pending" تطابق المبلغ $amount ورقم الهاتف $payer_phone. - $sql = "UPDATE transactions SET status = 'completed' WHERE amount = ? AND phone_number = ? AND currency = 'JOD' AND status = 'pending' LIMIT 1"; */ } else { // إذا لم تتطابق الرسالة مع نمط Orange Money $log_entry .= " | INFO: Message did not match the Orange Money pattern. Ignored." . PHP_EOL; } // كتابة كل شيء في ملف السجل file_put_contents('sms_log.txt', $log_entry, FILE_APPEND); // --- 5. إرسال رد إلى تطبيق الأندرويد --- http_response_code(200); echo json_encode(['status' => 'success', 'message' => 'Data received and processed.']); ?> ``` ## File: auth/sendEmail.php ``` Verify your email address

Hi [$email],

We recently received a request to verify your email address for your account on SEFER App.

To verify your email address, please write this to app .

$token

If you did not request to verify your email address, please ignore this email.

Thank you,

SEFER Team. "; mail($email, $subject, $bodyEmail, $headers); ``` ## File: auth/login.php ``` prepare($sql); $stmt->bindParam(':email', $email); $stmt->bindParam(':phone', $phone); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); $count = $stmt->rowCount(); if ($count > 0) { $stored_password = $data[0]['password']; if (password_verify($password, $stored_password)) { unset($data[0]['password']); echo json_encode([ "status" => "success", "count" => $count, "data" => $data ]); } else { // The password is incorrect echo json_encode([ "status" => "Failure", "data" => "Incorrect password." ]); // jsonError("Incorrect password."); } } else { // The user does not exist echo json_encode([ "status" => "Failure", "data" => "User does not exist." ]); // jsonError("User does not exist."); } $conn->close(); ?> ``` ## File: auth/verifyOtpMessage.php ``` prepare($sql); // Log the parameters used in the SQL query for debugging error_log("Executing SELECT SQL: " . $sql . " with phone_number=" . $phone_number . " and token_code=" . $token_code); $stmt->bindParam(':phone_number', $phone_number, PDO::PARAM_STR); $stmt->bindParam(':token_code', $token_code, PDO::PARAM_STR); if ($stmt->execute()) { $result = $stmt->fetch(); if ($result) { // Update the verified status $sql = "UPDATE `phone_verification_passenger` SET `verified` = 1 WHERE `phone_number` = :phone_number"; $stmt = $con->prepare($sql); // Log the update query execution error_log("Executing UPDATE SQL: " . $sql . " with phone_number=" . $phone_number); $stmt->bindParam(':phone_number', $phone_number, PDO::PARAM_STR); if ($stmt->execute()) { jsonSuccess(null, "Your phone number has been verified."); } else { // Log if the update query fails error_log("Error executing UPDATE SQL: " . implode(", ", $stmt->errorInfo())); jsonError("An error occurred while verifying your phone number. Please try again."); } } else { // Log if no matching record was found error_log("No matching record found for phone_number=" . $phone_number . " and token_code=" . $token_code); jsonError("Your phone number could not be verified. Please try again."); } } else { // Log if the select query fails error_log("Error executing SELECT SQL: " . implode(", ", $stmt->errorInfo())); jsonError("An error occurred while verifying your phone number. Please try again."); } ?> ``` ## File: auth/packageInfo.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($stmt->rowCount() > 0) { // Print all the records // printData($result); jsonSuccess($data = $result); } else { // Print a failure message jsonError($message = "No records found"); } ?> ``` ## File: auth/passengerRemovedAccountEmail.php ``` ``` ## File: auth/sendVerifyEmail.php ``` prepare($sql); $stmt->execute(); $rowCount = $stmt->rowCount(); $admin='support@mobile-app.store'; $headers = "MIME-Version: 1.0" . "\r\n"; $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n"; $headers .= "From: $admin" . "\r\n"; $subject = "Verify your email address"; $bodyEmail = " Verify your email address

Hi [$email],

We recently received a request to verify your email address for your account on SEFER App.

To verify your email address, please write this to app .

$token

If you did not request to verify your email address, please ignore this email.

Thank you,

SEFER Team. "; if ($rowCount > 0) { // The email already exists, so update the data $sql = "UPDATE `email_verifications` SET `token` = '$token' WHERE `email` = '$email'"; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // The update was successful jsonSuccess($message = "Email verification data updated successfully"); mail($email, $subject, $bodyEmail, $headers); } else { // The update was unsuccessful jsonError($message = "Failed to update email verification data"); } } else { // The email does not exist, so insert the data $sql = "INSERT INTO `email_verifications` (`email`, `token`) VALUES ('$email', '$token')"; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // The insertion was successful jsonSuccess($message = "Email verification data saved successfully"); mail($email, $subject, $bodyEmail, $headers); } else { // The insertion was unsuccessful jsonError($message = "Failed to save email verification data"); } } ?> ``` ## File: auth/signup.php ``` encryptData($phone); $email = $encryptionHelper->encryptData($email); $gender = $encryptionHelper->encryptData($gender); $birthdate = $encryptionHelper->encryptData($birthdate); $site = $encryptionHelper->encryptData($site); $first_name = $encryptionHelper->encryptData($first_name); $last_name = $encryptionHelper->encryptData($last_name); // تشفير الباسورد $hashedPassword = password_hash($password, PASSWORD_DEFAULT); try { // التحقق من وجود الإيميل أو رقم الهاتف مسبقًا $sql = "SELECT * FROM passengers WHERE phone = :phone OR email = :email"; $stmt = $con->prepare($sql); $stmt->bindParam(":phone", $phone); $stmt->bindParam(":email", $email); $stmt->execute(); $results = $stmt->fetchAll(); if (count($results) > 0) { jsonError("The email or phone number is already registered."); exit; } // إدخال البيانات الجديدة $sql = "INSERT INTO passengers ( id, phone, email, password, gender, birthdate, site, first_name, last_name ) VALUES ( :id, :phone, :email, :password, :gender, :birthdate, :site, :first_name, :last_name )"; $stmt = $con->prepare($sql); $stmt->bindParam(":id", $id); $stmt->bindParam(":phone", $phone); $stmt->bindParam(":email", $email); $stmt->bindParam(":password", $hashedPassword); $stmt->bindParam(":gender", $gender); $stmt->bindParam(":birthdate", $birthdate); $stmt->bindParam(":site", $site); $stmt->bindParam(":first_name", $first_name); $stmt->bindParam(":last_name", $last_name); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "success to save passenger data"); } else { jsonError("Failed to save passenger data"); } } catch (PDOException $e) { error_log("Database Error: " . $e->getMessage()); jsonError("An error occurred while saving the data."); } ?> ``` ## File: auth/resetPassword.php ``` ``` ## File: auth/cnMap.php ``` "3", "1" => "7", "2" => "1", "3" => "9", "4" => "0", "5" => "5", "6" => "2", "7" => "6", "8" => "4", "9" => "8" ); // Convert the map to a JSON string with JSON_FORCE_OBJECT option $jsonString = json_encode($cn, JSON_FORCE_OBJECT); // Send the JSON string to the Flutter app echo $jsonString; ?> ``` ## File: auth/checkPhoneNumberISVerfiedPassenger.php ``` encryptData($phoneNumber); $email = $encryptionHelper->encryptData($email); // تنفيذ الاستعلام $sql = " SELECT pv.*, p.email FROM `phone_verification_passenger` pv INNER JOIN `passengers` p ON pv.phone_number = p.phone WHERE pv.phone_number = :phoneNumber AND p.email = :email "; $stmt = $con->prepare($sql); $stmt->bindParam(':phoneNumber', $phoneNumber, PDO::PARAM_STR); $stmt->bindParam(':email', $email, PDO::PARAM_STR); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // يمكنك هنا لاحقًا تفكيك تشفير أي حقل إذا كنت ترجع phone/email مثلاً للمستخدم، لكن في حالتنا ما في حاجة. jsonSuccess($rows); } else { jsonError("No Phone verified or related email found"); } ?> ``` ## File: auth/cn_map.json ``` ["3","7","1","9","0","5","2","6","4","8"] ``` ## File: auth/otpmessage.php ``` $username, 'password' => $password, 'language' => 'e' , // Assuming 'e' is for English as per original 'sender' => $sender, 'receiver' => $receiver, 'message' => $message ]; $jsonPayload = json_encode($payload); $response = callAPI("POST", $apiUrl, $jsonPayload); if ($response && isset($response->message) && $response->message == 'Success') { // 3. تخزين في Redis بدلاً من MySQL (أسرع وأكثر أماناً مع TTL تلقائي) if ($redis) { try { $redis->setex("otp:passenger:$receiver", 300, $otp); // صلاحية 5 دقائق jsonSuccess(null, "OTP sent and saved to Redis successfully"); } catch (Exception $e) { error_log("Redis Error (OTP): " . $e->getMessage()); jsonError("OTP sent but failed to save in Redis"); } } else { jsonError("Redis service unavailable"); } } else { jsonError("OTP not sent (SMS API failed or invalid response)"); } // دالة الاتصال بالـ API function callAPI($method, $url, $data) { $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_POSTFIELDS => $data, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Accept: application/json" // Often good to add ], CURLOPT_TIMEOUT => 30, // Set a timeout CURLOPT_CONNECTTIMEOUT => 10 // Set a connection timeout ]); $api_raw_response = curl_exec($curl); if (curl_errno($curl)) { $curl_error_msg = curl_error($curl); $curl_error_no = curl_errno($curl); error_log("cURL Error (callAPI): [{$curl_error_no}] " . $curl_error_msg); curl_close($curl); return false; // Indicate cURL failure clearly } curl_close($curl); $decoded_response = json_decode($api_raw_response); if (json_last_error() !== JSON_ERROR_NONE) { return null; // Indicate JSON decode failure } error_log("callAPI: Decoded response: " . print_r($decoded_response, true)); return $decoded_response; } ?> ``` ## File: auth/checkPhoneNumberISVerfiedDriver.php ``` encryptData($phoneNumber); // تجهيز الاستعلام باستخدام bindParam للحماية $sql = "SELECT * FROM `phone_verification` WHERE `phone_number` = :phone_number"; $stmt = $con->prepare($sql); $stmt->bindParam(":phone_number", $phoneNumber); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($rows); } else { jsonError("No phone verified yet found"); } ?> ``` ## File: auth/verifyEmail.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetch(); if ($result) { $id = $result["id"]; $sql = "UPDATE `email_verifications` SET `verified` = 1 WHERE `id` = $id"; $stmt = $con->prepare($sql); $stmt->execute(); $admin='support@sefer.com'; $headers = "MIME-Version: 1.0" . "\r\n"; $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n"; $headers .= "From: $admin" . "\r\n"; $subject = " Verify your email address"; $bodyEmail="Subject: Verify your email address Hi [$email], Your email address has been verified. Thank you, SEFER Team"; mail($email, $subject, $bodyEmail, $headers); jsonSuccess($message = "Your email address has been verified."); } else { jsonError($message ="Your email address could not be verified. Please try again."); } ?> ``` ## File: auth/loginFromGooglePassenger.php ``` encryptData($email); // تجهيز الاستعلام $sql = "SELECT p.`id`, p.`phone`, p.`email`, p.`gender`, p.`status`, p.`birthdate`, p.`site`, p.`first_name`, p.`last_name`, p.`sosPhone`, p.`education`, p.`employmentType`, p.`maritalStatus`, p.`created_at`, p.`updated_at`, phone_verification_passenger.verified, invitesToPassengers.isInstall, invitesToPassengers.inviteCode, invitesToPassengers.isGiftToken, (SELECT `version` FROM `packageInfo` WHERE platform = :platform AND appName = :appName) AS package, promos.promo_code AS promo, promos.amount AS discount, promos.validity_end_date AS validity FROM passengers p LEFT JOIN phone_verification_passenger ON phone_verification_passenger.phone_number = p.phone LEFT JOIN invitesToPassengers ON invitesToPassengers.inviterPassengerPhone = p.phone LEFT JOIN promos ON promos.passengerID = p.id WHERE p.email = :email AND p.id = :id AND phone_verification_passenger.verified = '1'"; // تنفيذ الاستعلام $stmt = $con->prepare($sql); $stmt->bindParam(':email', $email); $stmt->bindParam(':id', $id); $stmt->bindParam(':appName', $appName); $stmt->bindParam(':platform', $platform); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); $count = $stmt->rowCount(); // تجهيز الرد header('Content-Type: application/json'); if ($count > 0) { foreach ($data as &$row) { // فك تشفير الحقول الحساسة $row['phone'] = $encryptionHelper->decryptData($row['phone']); $row['email'] = $encryptionHelper->decryptData($row['email']); $row['gender'] = $encryptionHelper->decryptData($row['gender']); $row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']); $row['site'] = $encryptionHelper->decryptData($row['site']); $row['first_name'] = $encryptionHelper->decryptData($row['first_name']); $row['last_name'] = $encryptionHelper->decryptData($row['last_name']); $row['sosPhone'] = $encryptionHelper->decryptData($row['sosPhone']); $row['education'] = $encryptionHelper->decryptData($row['education']); $row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']); $row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']); } echo json_encode([ "status" => "success", "count" => $count, "data" => $data ]); } else { error_log("User does not exist: " . $email); echo json_encode([ "status" => "Failure", "data" => "User does not exist." ]); } // تنظيف الموارد $stmt = null; $con = null; exit(); ``` ## File: auth/syria/verifyOtp.php ``` encryptData($phoneNumber); error_log("[Auth_Debug] Phone number encrypted successfully."); try { // ✅ 1. حذف أي رموز قديمة لنفس الرقم error_log("[Auth_Step_1] Deleting old verification records for this phone..."); $stmtDelete = $con->prepare("DELETE FROM phone_verification_passenger WHERE phone_number = ?"); $stmtDelete->execute([$phoneNumber_encrypted]); error_log("[Auth_Step_1] Old records deleted (if any)."); // ✅ 2. إدخال سجل جديد مع تحقق مباشر (بدون OTP) $now = date('Y-m-d H:i:s'); error_log("[Auth_Step_2] Inserting new verified record at: " . $now); $stmt = $con->prepare(" INSERT INTO phone_verification_passenger (phone_number, token, expiration_time, verified, created_at) VALUES (?, NULL, NULL, 1, ?) "); $stmt->execute([$phoneNumber_encrypted, $now]); error_log("[Auth_Step_2] New record inserted successfully."); // ✅ 3. فحص هل الراكب موجود مسبقاً error_log("[Auth_Step_3] Checking if passenger exists in passengers table..."); $checkPassengerStmt = $con->prepare(" SELECT * FROM passengers WHERE phone = ? "); $checkPassengerStmt->execute([$phoneNumber_encrypted]); $passenger = $checkPassengerStmt->fetch(PDO::FETCH_ASSOC); if ($passenger) { // ✅ الراكب موجود error_log("[Auth_Result] Passenger Found. ID: " . $passenger['id']); printSuccess([ "message" => "Passenger already registered.", "isRegistered" => true, "passenger" => [ "id" => $passenger['id'], "first_name" => $encryptionHelper->decryptData($passenger['first_name']), "last_name" => $encryptionHelper->decryptData($passenger['last_name']), "email" => $encryptionHelper->decryptData($passenger['email']), "phone" => $phoneNumber ] ]); } else { // ✅ الراكب جديد error_log("[Auth_Result] Passenger Not Found. Treating as new user."); printSuccess([ "message" => "Phone number verified automatically (no OTP required).", "isRegistered" => false ]); } } catch (PDOException $e) { // تسجيل الخطأ بالتفصيل في ملف اللوج error_log("[Auth_DB_Exception] Error: " . $e->getMessage() . " | File: " . $e->getFile() . " | Line: " . $e->getLine()); // طباعة رسالة الخطأ للمستخدم (يفضل عدم إظهار تفاصيل الـ SQL للمستخدم النهائي لأسباب أمنية) jsonError("Database error occurred. Please contact support."); } catch (Exception $e) { // التقاط أي أخطاء عامة أخرى error_log("[Auth_General_Exception] Error: " . $e->getMessage()); jsonError("An unexpected error occurred."); } // تسجيل نهاية الطلب error_log("[Auth_Debug] Request processing finished."); ?> ``` ## File: auth/syria/send_survey.php ``` "buttons", "header" => [ "type" => "text", "text" => "استطلاع رأي سريع 🌟" ], "body" => [ "text" => "هل كانت تجربة التسجيل في تطبيق *سيرو* سهلة بالنسبة لك؟\n\n👇 اضغط أحد الخيارات:" ], "footer" => [ "text" => "للتواصل: +962 7XXXXXXX - رابط التطبيق: https://intaleq.xyz" ], "buttons" => [ [ "type" => "reply", "reply" => [ "id" => "feedback_yes", "title" => "👍 نعم" ] ], [ "type" => "reply", "reply" => [ "id" => "feedback_no", "title" => "👎 لا" ] ] ] ]; // استدعاء الدالة لإرسال الرسالة $response = sendWhatsAppFromServer($receiver, $surveyMessage); if ($response && isset($response["status"]) && $response["status"] === "sent") { jsonSuccess(null, "تم إرسال استطلاع الرأي بنجاح بعد $delay ثانية."); } else { jsonError("فشل في إرسال استطلاع الرأي"); } ?> ``` ## File: auth/syria/secure_image.php ``` file($path) ?: 'application/octet-stream'; header('Content-Type: ' . $mime); header('Content-Length: ' . filesize($path)); header('X-Content-Type-Options: nosniff'); // (اختياري) اطلب توكن وصول إضافي عبر Authorization للتحكم الأدق. // مثال: تحقق من $_SERVER['HTTP_AUTHORIZATION'] هنا إن أردت. readfile($path); ``` ## File: auth/syria/register_passenger.php ``` encryptData($phoneNumber); $firstName_encrypted = $encryptionHelper->encryptData($firstName); $lastName_encrypted = $encryptionHelper->encryptData($lastName); $email_encrypted = $encryptionHelper->encryptData($email); $password_hashed = password_hash($email, PASSWORD_DEFAULT); $unknown_encrypted = $encryptionHelper->encryptData("unknown yet"); // ====================================================== // Step 5: إنشاء ID فريد // ====================================================== $step = 5; // $uniqueId = substr(md5(uniqid(mt_rand(), true)), 0, 20); $uniqueId = substr(md5($phoneNumber_encrypted), 0, 20); error_log("$logTag Step 5: Generated Unique ID: $uniqueId"); // ====================================================== // Step 6: التحقق من وجود المستخدم (Database Check) // ====================================================== $step = 6; $checkStmt = $con->prepare("SELECT id FROM passengers WHERE phone = ?"); $checkStmt->execute([$phoneNumber_encrypted]); if ($checkStmt->rowCount() > 0) { error_log("$logTag Step 6 Error: User already exists."); jsonError("User with this phone number or email already exists."); exit(); } // ====================================================== // Step 7: الإضافة (Insert User) // ====================================================== $step = 7; error_log("$logTag Step 7: Inserting into passengers table..."); $insertStmt = $con->prepare(" INSERT INTO passengers (id, first_name, last_name, email, phone, password, gender, birthdate, site, sosPhone, education, employmentType, maritalStatus, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', NOW(), NOW()) "); $success = $insertStmt->execute([ $uniqueId, $firstName_encrypted, $lastName_encrypted, $email_encrypted, $phoneNumber_encrypted, $password_hashed, $unknown_encrypted, $unknown_encrypted, $unknown_encrypted, $unknown_encrypted, $unknown_encrypted, $unknown_encrypted, $unknown_encrypted ]); if (!$success) { $errorInfo = $insertStmt->errorInfo(); // طباعة تفاصيل خطأ الـ SQL في اللوج error_log("$logTag Step 7 Error: SQL Insert Failed. Details: " . json_encode($errorInfo)); jsonError("Failed to create user account."); exit(); } // ====================================================== // Step 9: جلب البيانات لإعادتها // ====================================================== $step = 9; $userStmt = $con->prepare("SELECT * FROM passengers WHERE id = ?"); $userStmt->execute([$uniqueId]); $newUser = $userStmt->fetch(PDO::FETCH_ASSOC); // ====================================================== // Step 10: فك التشفير وإرسال الرد // ====================================================== $step = 10; if ($newUser) { unset($newUser['password']); foreach ($newUser as $key => &$value) { if ($key !== 'id' && $key !== 'status' && $key !== 'created_at' && $key !== 'updated_at' && !is_null($value)) { $value = $encryptionHelper->decryptData($value); } } } error_log("$logTag Success: User registered successfully."); jsonSuccess(["status" => "registration_success", "data" => $newUser]); } catch (PDOException $e) { // طباعة خطأ قاعدة البيانات في اللوج error_log("$logTag PDO Exception at Step $step: " . $e->getMessage()); jsonError("Database Error."); } catch (Exception $e) { // طباعة الأخطاء العامة في اللوج error_log("$logTag General Exception at Step $step: " . $e->getMessage()); jsonError("General Error."); } ?> ``` ## File: auth/syria/uploadSyrianDocs.php ``` MAX_FILE_MB * 1024 * 1024) { jsonError("File too large. Max " . MAX_FILE_MB . " MB."); exit; } // MIME دقيق $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($tmpPath) ?: 'application/octet-stream'; if (!in_array($mime, ALLOWED_MIMES, true)) { jsonError("Unsupported file type: $mime"); exit; } // لاحقة الامتداد $extMap = [ 'image/jpeg' => '.jpg', 'image/png' => '.png', 'image/webp' => '.webp', ]; $ext = $extMap[$mime]; // --------- توليد مسار حتمي بدون تاريخ --------- // تنظيف driver_id لاسم ملف آمن $driverIdSafe = preg_replace('/[^A-Za-z0-9_\-]/', '_', $driverId); // شجرة مجلدات ثابتة من hash(driver_id) لتوزيع الملفات $h = hash('sha1', $driverIdSafe); $subdir = substr($h, 0, 2) . '/' . substr($h, 2, 2); $destDir = UPLOAD_ROOT . '/' . $subdir; if (!is_dir($destDir)) { @mkdir($destDir, 0700, true); } // الاسم النهائي بدون تاريخ $serverName = "{$driverIdSafe}__{$docType}{$ext}"; $destPath = $destDir . '/' . $serverName; // استبدال أي نسخة قديمة عن قصد (overwrite) if (is_file($destPath)) { @unlink($destPath); } // نقل الملف if (!move_uploaded_file($tmpPath, $destPath)) { jsonError("Failed to save the uploaded file."); exit; } @chmod($destPath, 0600); // --------- Signed URL --------- // سنضمّن driver_id و doc_type و ext في الرابط والتوقيع. // ext بدون النقطة $extShort = ltrim($ext, '.'); $expires = time() + SIGNED_TTL_SEC; // الرسالة الموقّعة: driver_id:doc_type:ext:expires $message = $driverIdSafe . ':' . $docType . ':' . $extShort . ':' . $expires; $signature = hash_hmac('sha256', $message, SIGN_SECRET); // رابط القراءة عبر البوابة الآمنة فقط // ملاحظة: لا نُرجع المسار الحقيقي، فقط معطيات موقّعة $fileUrl = PUBLIC_BASE . "/secure_image.php" . "?driver_id={$driverIdSafe}" . "&doc_type={$docType}" . "&ext={$extShort}" . "&expires={$expires}" . "&signature={$signature}"; // --------- استجابة --------- printSuccess([ "status" => "success", "success_file" => true, "file_url" => $fileUrl, "file_name" => $serverName, // الاسم الفعلي المحفوظ "driver_id" => $driverIdSafe, "doc_type" => $docType, "mime_type" => $mime, "size_bytes" => $size, "expires_at" => date('c', $expires) ]); ``` ## File: auth/syria/delete_old_images.php ``` isFile()) continue; $checked++; $path = $node->getPathname(); $ext = strtolower($node->getExtension()); // فلترة الامتدادات if (!in_array($ext, ALLOWED_EXTS, true)) continue; // فلترة اسم الملف (حماية من حذف ملفات أخرى) $name = $node->getBasename(); if (!preg_match('/^[A-Za-z0-9_-]+__(' . $docTypesRegex . ')\.(jpg|png|webp)$/i', $name)) { continue; } $age = $now - $node->getMTime(); if ($age >= $ttlSeconds) { if (@unlink($path)) { $deleted++; $logln("🗑 Deleted: {$path} | age=" . round($age/3600, 1) . "h"); } else { $logln("⚠️ Failed to delete: {$path}"); } } } $logln("Done. checked={$checked}, deleted={$deleted}"); if ($log) @fclose($log); ``` ## File: auth/syria/sendWhatsOpt.php ``` encryptData($raw); $enc_norm = $encryptionHelper->encryptData($norm); $sql = "SELECT 1 FROM passenger_blacklist WHERE phone IN (:enc_raw, :enc_norm) AND (expires_at IS NULL OR expires_at > NOW()) LIMIT 1"; $q = $con->prepare($sql); $q->execute([ 'enc_raw' => $enc_raw, 'enc_norm' => $enc_norm, ]); return (bool)$q->fetchColumn(); } /* 0) Get phone number */ $receiver = filterRequest("receiver"); if (!$receiver) { jsonError('Phone number is required.'); exit(); } if (is_blacklisted($con, $encryptionHelper, $receiver)) { jsonError('This phone is blacklisted and cannot receive OTP.'); error_log("[send_otp] BLOCKED (blacklisted): $receiver"); exit(); } /* 1) Generate OTP */ $otp = rand(10000, 99999); $messageBody = "Your verification code for Siro is: " . $otp; /* 🟢 2) Skip sending and log instead */ error_log("[send_otp] Skipping actual send. OTP generated for $receiver: $otp"); /* 3) Save OTP (encrypted) */ $receiver_enc = $encryptionHelper->encryptData($receiver); $otp_enc = $encryptionHelper->encryptData($otp); $exp = date('Y-m-d H:i:s', strtotime('+5 minutes')); $now = date('Y-m-d H:i:s'); try { $con->prepare("DELETE FROM phone_verification_passenger WHERE phone_number = ?") ->execute([$receiver_enc]); $stmt = $con->prepare(" INSERT INTO phone_verification_passenger (phone_number, token, expiration_time, verified, created_at) VALUES (?, ?, ?, 0, ?) "); $stmt->execute([$receiver_enc, $otp_enc, $exp, $now]); jsonSuccess(null, 'OTP generated and saved successfully (no message sent)'); error_log("[send_otp] OTP saved successfully for $receiver"); } catch (PDOException $e) { error_log("[send_otp] DB error: ".$e->getMessage()); jsonError('OTP generated but failed to save to database'); } /* require_once __DIR__ . '/../../connect.php'; error_log("--- [send_otp.php] Started ---"); function normalize_phone($s) { return preg_replace('/\D+/', '', (string)$s); } function is_blacklisted(PDO $con, $encryptionHelper, string $phone): bool { $raw = trim($phone); $norm = normalize_phone($raw); // شَفِّر قبل السؤال $enc_raw = $encryptionHelper->encryptData($raw); $enc_norm = $encryptionHelper->encryptData($norm); $sql = "SELECT 1 FROM passenger_blacklist WHERE phone IN (:enc_raw, :enc_norm) AND (expires_at IS NULL OR expires_at > NOW()) LIMIT 1"; $q = $con->prepare($sql); $q->execute([ 'enc_raw' => $enc_raw, 'enc_norm' => $enc_norm, ]); return (bool)$q->fetchColumn(); } $receiver = filterRequest("receiver"); if (!$receiver) { jsonError('Phone number is required.'); exit(); } if (is_blacklisted($con, $encryptionHelper, $receiver)) { jsonError('This phone is blacklisted and cannot receive OTP.'); error_log("[send_otp] BLOCKED (blacklisted): $receiver"); exit(); } $otp = rand(10000, 99999); $messageBody = "Your verification code for Siro is: " . $otp; function normalize($raw) { if (is_string($raw)) return json_decode($raw, true) ?: []; if ($raw instanceof stdClass) return (array)$raw; return is_array($raw) ? $raw : []; } $response = normalize(sendWhatsAppFromServer($receiver, $messageBody)); $sentOK = $response['success'] ?? false; if (!$sentOK) { error_log("[send_otp] WA-Server failed ⇒ ".(($response['message'] ?? null) ?: json_encode($response))); $payload = [ "number" => $receiver, "type" => "text", "message" => $messageBody, "instance_id" => getenv("RASEEL_DRIVER_INSTANCE_ID"), "access_token" => getenv("RASEEL_DRIVER_ACCESS_TOKEN") ]; $response = callAPI("POST", "https://raseelplus.com/api/send", json_encode($payload)); $response = normalize($response); $sentOK = ($response['status'] ?? '') === 'success'; if (!$sentOK) { error_log("[send_otp] RaseelPlus failed ⇒ ".json_encode($response)); jsonError('Failed to send OTP: '.($response['message'] ?? 'Unknown error')); exit(); } } $receiver_enc = $encryptionHelper->encryptData($receiver); // الهاتف المُرسل (خام) مُشفّر $otp_enc = $encryptionHelper->encryptData($otp); $exp = date('Y-m-d H:i:s', strtotime('+5 minutes')); $now = date('Y-m-d H:i:s'); try { $con->prepare("DELETE FROM phone_verification_passenger WHERE phone_number = ?") ->execute([$receiver_enc]); $stmt = $con->prepare(" INSERT INTO phone_verification_passenger (phone_number, token, expiration_time, verified, created_at) VALUES (?, ?, ?, 0, ?) "); $stmt->execute([$receiver_enc, $otp_enc, $exp, $now]); jsonSuccess(null, 'OTP sent and saved successfully'); error_log("[send_otp] OTP saved for $receiver"); } catch (PDOException $e) { error_log("[send_otp] DB error: ".$e->getMessage()); jsonError('OTP sent but failed to save to database'); } function callAPI($method, $url, $data) { $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_POSTFIELDS => $data, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Accept: application/json" ], ]); $body = curl_exec($ch); $err = curl_error($ch); curl_close($ch); return $err ? [] : json_decode($body, true); } */ ``` ## File: auth/syria/auth_proxy.php ``` setClientId($clientID); $client->setClientSecret($clientSecret); $client->setRedirectUri($redirectUri); $client->addScope("email"); $client->addScope("profile"); // 4. LOGIC: Handle the authentication flow if (isset($_GET['code'])) { // A. User has been redirected back from Google with an authorization code. try { // Exchange the authorization code for an access token. $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); if (isset($token['error'])) { // Handle error from Google throw new Exception('Error fetching access token: ' . $token['error_description']); } $client->setAccessToken($token['access_token']); // Get user profile information from Google. $google_oauth = new Google_Service_Oauth2($client); $google_account_info = $google_oauth->userinfo->get(); $id = $google_account_info->id; $email = $google_account_info->email; $name = $google_account_info->name; $picture = $google_account_info->picture; // B. Redirect back to the Flutter app with the user data in the URL. // We use urlencode to ensure data is passed correctly. $redirectUrl = $appRedirectScheme . '?status=success' . '&id=' . urlencode($id) . '&email=' . urlencode($email) . '&name=' . urlencode($name) . '&picture=' . urlencode($picture); header('Location: ' . $redirectUrl); exit(); } catch (Exception $e) { // C. Handle any errors and redirect back to the app with an error status. $error_message = urlencode($e->getMessage()); header('Location: ' . $appRedirectScheme . '?status=error&message=' . $error_message); exit(); } } else { // D. This is the initial request from the Flutter app. // Redirect the user to Google's OAuth 2.0 server for authentication. $authUrl = $client->createAuthUrl(); header('Location: ' . $authUrl); exit(); } ?> ``` ## File: auth/syria/driver/isPhoneVerified.php ``` encryptData($phoneNumber); try { // الاستعلام عن السائق حسب رقم الهاتف وحالة التحقق $stmt = $con->prepare(" SELECT * FROM phone_verification WHERE phone_number = ? AND is_verified = 1 "); $stmt->execute([$phoneNumber_encrypted]); $driver = $stmt->fetch(PDO::FETCH_ASSOC); if ($driver) { jsonSuccess(null, "Phone number is verified."); } else { jsonError("Phone number is not verified or does not exist."); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ``` ## File: auth/syria/driver/verifyOtp.php ``` encryptData($phoneNumber); $email_encrypted = $encryptionHelper->encryptData($email); try { // 🧹 حذف أي رموز قديمة لنفس الرقم $con->prepare("DELETE FROM phone_verification WHERE phone_number = ?") ->execute([$phoneNumber_encrypted]); // 🧾 توليد driverID فريد $raw = $phoneNumber; $driverID = substr(md5($raw), 2, 20); // 🔐 توليد رمز تجريبي (بدون OTP حقيقي لتجنب Null) $dummyToken = $encryptionHelper->encryptData('AUTO'); // 🕒 الوقت الحالي $now = date('Y-m-d H:i:s'); // ✅ إدخال سجل تحقق مباشر $stmt = $con->prepare(" INSERT INTO phone_verification (phone_number, token_code, email, driverId, expiration_time, is_verified, created_at) VALUES (?, ?, ?, ?, NULL, 1, ?) "); $stmt->execute([$phoneNumber_encrypted, $dummyToken, $email_encrypted, $driverID, $now]); error_log("✅ [verifyOtp.php] Auto verification record inserted successfully for $phoneNumber"); // 🔍 التحقق إذا السائق موجود مسبقاً $checkDriverStmt = $con->prepare("SELECT * FROM driver WHERE phone = ?"); $checkDriverStmt->execute([$phoneNumber_encrypted]); $driver = $checkDriverStmt->fetch(PDO::FETCH_ASSOC); if ($driver) { error_log("👤 [verifyOtp.php] Driver already registered. Returning driver info."); printSuccess([ "message" => "Driver already registered.", "isRegistered" => true, "driver" => [ "id" => $driver['id'], "first_name" => $encryptionHelper->decryptData($driver['first_name']), "last_name" => $encryptionHelper->decryptData($driver['last_name']), "email" => $encryptionHelper->decryptData($driver['email']), "phone" => $phoneNumber ] ]); } else { error_log("🆕 [verifyOtp.php] Phone verified automatically. Driver not found."); printSuccess([ "message" => "Phone number verified automatically (no OTP required).", "isRegistered" => false, "driverID" => $driverID ]); } } catch (PDOException $e) { error_log("💥 [verifyOtp.php] PDO ERROR: " . $e->getMessage()); jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: auth/syria/driver/driver_details.php ``` prepare($sql); $stmt->execute([':id' => $driverId]); $driver = $stmt->fetch(PDO::FETCH_ASSOC); if (!$driver) { jsonError("Driver not found."); exit; } // فك التشفير للحقول الحساسة foreach ($driver as $k => $v) { if (in_array($k, ['phone', 'email', 'first_name', 'last_name', 'national_number', 'address','gender','site', 'birthdate', 'name_arabic'])) { $driver[$k] = $encryptionHelper->decryptData($v); } } // الوثائق $sql2 = "SELECT doc_type, image_name, link FROM driver_documents WHERE driverID = :id"; $stmt2 = $con->prepare($sql2); $stmt2->execute([':id' => $driverId]); $docs = $stmt2->fetchAll(PDO::FETCH_ASSOC); printSuccess([ "driver" => $driver, "documents" => $docs ]); } catch (PDOException $e) { jsonError("Error: " . $e->getMessage()); } ``` ## File: auth/syria/driver/register_driver_and_car_signed.php ``` encryptData($data[$f]); } } // حساسات السيارة $car['vin'] = $encryptionHelper->encryptData($car['vin']); $car['car_plate'] = $encryptionHelper->encryptData($car['car_plate']); $car['owner'] = $encryptionHelper->encryptData($car['owner']); /* ========== 4) هَش كلمة المرور ========== */ $pwdHashed = password_hash(filterRequest('password'), PASSWORD_DEFAULT); /* ========== 5) بدء معاملة ========== */ $con->beginTransaction(); /* ========== 6) فحص تكرار هاتف/ايميل (المشفّرين) ========== */ $dup = $con->prepare("SELECT id FROM driver WHERE phone = :p OR email = :e"); $dup->execute([':p' => $data['phone'], ':e' => $data['email']]); if ($dup->rowCount() > 0) { $con->rollBack(); jsonError("Phone or email already registered."); exit; } /* ========== 7) إدراج السائق ========== */ $sqlDriver = " INSERT INTO driver ( id, phone, email, password, gender, license_type, national_number, name_arabic, issue_date, expiry_date, license_categories, address, licenseIssueDate, status, birthdate, site, first_name, last_name, accountBank, bankCode, employmentType, maritalStatus, fullNameMaritial, expirationDate, created_at, updated_at ) VALUES ( :id, :phone, :email, :pwd, :gender, :license_type, :national_number, :name_arabic, :issue_date, :expiry_date, :license_categories, :address, :licenseIssueDate, :status, :birthdate, :site, :first_name, :last_name, :accountBank, :bankCode, :employmentType, :maritalStatus, :fullNameMaritial, :expirationDate, NOW(), NOW() ) "; $insD = $con->prepare($sqlDriver); $okD = $insD->execute([ ':id' => $driverID, ':phone' => $data['phone'], ':email' => $data['email'], ':pwd' => $pwdHashed, ':gender' => $data['gender'], ':license_type' => $data['license_type'], ':national_number' => $data['national_number'], ':name_arabic' => $data['name_arabic'], ':issue_date' => $data['issue_date'], ':expiry_date' => $data['expiry_date'], ':license_categories'=> !empty($data['license_categories']) ? $data['license_categories'] : 'B', ':address' => $data['address'], ':licenseIssueDate' => $data['licenseIssueDate'], ':status' => !empty($data['status']) ? $data['status'] : 'yet', ':birthdate' => $data['birthdate'], ':site' => $data['site'], ':first_name' => $data['first_name'], ':last_name' => $data['last_name'], ':accountBank' => 'yet', ':bankCode' => 'yet', ':employmentType' => !empty($data['employmentType']) ? $data['employmentType'] : 'yet', ':maritalStatus' => !empty($data['maritalStatus']) ? $data['maritalStatus'] : 'yet', ':fullNameMaritial' => !empty($data['fullNameMaritial']) ? $data['fullNameMaritial'] : 'yet', ':expirationDate' => !empty($data['expirationDate']) ? $data['expirationDate'] : 'yet', ]); if (!$okD) { $con->rollBack(); jsonError("Failed to insert driver."); exit; } /* ========== 8) إدراج السيارة ========== */ $hasCar = $con->prepare("SELECT 1 FROM CarRegistration WHERE driverID = :d LIMIT 1"); $hasCar->execute([':d' => $driverID]); $isDefault = $hasCar->rowCount() === 0 ? 1 : 0; $sqlCar = " INSERT INTO CarRegistration ( driverID, vin, car_plate, make, model, year, expiration_date, color, owner, color_hex, fuel, isDefault, created_at, status ) VALUES ( :driverID, :vin, :car_plate, :make, :model, :year, :expiration_date, :color, :owner, :color_hex, :fuel, :isDefault, NOW(), 'yet' ) "; $insC = $con->prepare($sqlCar); $okC = $insC->execute([ ':driverID' => $driverID, ':vin' => $car['vin'], ':car_plate' => $car['car_plate'], ':make' => $car['make'], ':model' => $car['model'], ':year' => $car['year'], ':expiration_date' => $car['expiration_date'], ':color' => $car['color'], ':owner' => $car['owner'], ':color_hex' => $car['color_hex'], ':fuel' => $car['fuel'], ':isDefault' => $isDefault, ]); if (!$okC) { $con->rollBack(); jsonError("Failed to insert car registration."); exit; } $carRegID = $con->lastInsertId(); /* ========== 9) التحقّق من الروابط الموقّعة وحفظها ========== */ // دالة مساعدة تتحقّق من شكل الرابط وتستخرج doc_type/ext $validateSignedUrl = function(string $url) use ($allowedDocTypes, $allowedExts) { $parts = parse_url($url); if (!$parts || empty($parts['scheme']) || empty($parts['host']) || empty($parts['path'])) { throw new Exception("Invalid URL format."); } if (!in_array($parts['host'], $ALLOWED_SIGNED_HOSTS, true)) { throw new Exception("URL host not allowed: {$parts['host']}"); } if (stripos($parts['path'], 'secure_image.php') === false) { throw new Exception("URL path not allowed."); } if (empty($parts['query'])) { throw new Exception("URL missing query string."); } parse_str($parts['query'], $q); foreach (['driver_id','doc_type','ext','expires','signature'] as $k) { if (empty($q[$k])) throw new Exception("URL missing param: $k"); } if (!in_array($q['doc_type'], $allowedDocTypes, true)) { throw new Exception("Invalid doc_type in URL."); } if (!in_array(strtolower($q['ext']), $allowedExts, true)) { throw new Exception("Invalid ext in URL."); } return [ 'doc_type' => $q['doc_type'], 'ext' => strtolower($q['ext']), // بإمكانك التحقق من driver_id = $driverID إذا تحب تربطهما 'driver_id_in_url' => $q['driver_id'], ]; }; $docsToInsert = []; // [['doc_type'=>..., 'link'=>..., 'image_name'=>...], ...] foreach ($docUrlKeys as $k) { $link = $docUrls[$k]; $meta = $validateSignedUrl($link); // image_name ليس ضروريًا هنا (الرابط موقّع إلى بوابة قراءة)، احفظ doc_type + link فقط $docsToInsert[] = [ 'doc_type' => $meta['doc_type'], // يجب أن يتطابق مع $k منطقيًا 'link' => $link, 'image_name' => $meta['doc_type'] . '.' . $meta['ext'], // اسماً رمزياً فقط ]; } // إدراج في driver_documents // CREATE TABLE driver_documents ( // id INT AUTO_INCREMENT PRIMARY KEY, // driverID VARCHAR(64) NOT NULL, // doc_type VARCHAR(64) NOT NULL, // image_name VARCHAR(255) NULL, // link VARCHAR(1024) NOT NULL, // upload_date DATETIME NOT NULL, // INDEX(driverID) // ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; $insDoc = $con->prepare(" INSERT INTO driver_documents (driverID, doc_type, image_name, link, upload_date) VALUES (:driverID, :doc_type, :image_name, :link, NOW()) "); foreach ($docsToInsert as $row) { $insDoc->execute([ ':driverID' => $driverID, ':doc_type' => $row['doc_type'], ':image_name' => $row['image_name'], ':link' => $row['link'], ]); } /* ========== 10) إنهاء المعاملة ========== */ $con->commit(); printSuccess([ 'driverID' => $driverID, 'carRegID' => $carRegID, 'documents' => [ 'driver_license_front_url' => $docUrls['driver_license_front_url'], 'driver_license_back_url' => $docUrls['driver_license_back_url'], 'car_license_front_url' => $docUrls['car_license_front_url'], 'car_license_back_url' => $docUrls['car_license_back_url'], ] ]); } catch (Exception $e) { if (isset($con) && $con->inTransaction()) { $con->rollBack(); } error_log("register_driver_and_car ERROR: " . $e->getMessage()); jsonError("Server error: " . $e->getMessage()); } catch (PDOException $e) { if (isset($con) && $con->inTransaction()) { $con->rollBack(); } error_log("register_driver_and_car PDO: " . $e->getMessage()); jsonError("Database error."); } ``` ## File: auth/syria/driver/register_driver_and_car.php ``` 3) { if (strpos($phone, '9639') !== 0) { $phone = '9639' . substr($phone, 3); } } $data['phone'] = $phone; } /* ================== 🔴 END PHONE FORMATTING LOGIC 🔴 ================== */ // تجهيز تاريخ الميلاد قبل التشفير if (!empty($data['birthdate'])) { $data['birthdate'] = trim($data['birthdate']); $data['birthdate'] = $data['birthdate'] . '-01-01'; } else { $data['birthdate'] = '1970-01-01'; } // Read car fields $car = []; foreach ($carRequired as $f) { $v = filterRequest($f); if ($v === null || $v === '') { jsonError("Missing required field: $f"); exit; } $car[$f] = $v; } // Read document links $docUrls = []; foreach ($docKeys as $k) { $u = filterRequest($k); if ($u === null || $u === '') { jsonError("Missing document URL: $k"); exit; } if (!filter_var($u, FILTER_VALIDATE_URL)) { jsonError("Invalid document URL: $k"); exit; } $docUrls[$k] = $u; } /* ================== 2) Generate default id/email ================== */ if (empty($data['id'])) { $data['id'] = 'DRV' . date('YmdHis') . random_int(1000, 9999); } if ($data['email'] === null) { $data['email'] = $data['phone'] . '@intaleqapp.com'; } /* ================== 3) Encrypt sensitive fields ================== */ $toEncryptDriver = [ "phone","email","first_name","last_name","name_arabic","gender", "national_number","address","site","fullNameMaritial","birthdate" ]; foreach ($toEncryptDriver as $f) { if (!empty($data[$f])) { $data[$f] = $encryptionHelper->encryptData($data[$f]); } } // Encrypt car sensitive data $car['vin'] = $encryptionHelper->encryptData($car['vin']); $car['car_plate'] = $encryptionHelper->encryptData($car['car_plate']); $car['owner'] = $encryptionHelper->encryptData($car['owner']); /* ================== 4) Hash password (HMAC + password_hash) ================== */ // نقرأ الـ HMAC key من env $pepper = getenv('SECRET_KEY_HMAC'); // نبني baseString من أكثر من بارامتر // هنا نستخدم id + phone (بعد ما طبّقنا منطق تنسيق الهاتف) $baseParts = [ $data['id'], $data['phone'], ]; // نضيف رقم وطني أو سنة الميلاد إن توفروا (كما في الـ migration) if (!empty($data['national_number'])) { $baseParts[] = $data['national_number']; } elseif (!empty($data['birthdate'])) { // birthdate حالياً أصبح بصيغة YYYY-01-01 $year = substr($data['birthdate'], 0, 4); if (preg_match('/^\d{4}$/', $year)) { $baseParts[] = $year; } } $baseString = implode('|', $baseParts); // نشتق السر الخام باستخدام HMAC-SHA256 مع SECRET_KEY_HMAC $rawSecret = hash_hmac('sha256', $baseString, $pepper, true); // نخزّن فقط الهاش الناتج من password_hash في قاعدة البيانات $pwdHashed = password_hash($rawSecret, PASSWORD_DEFAULT); /* ================== 5) Start transaction ================== */ $con->beginTransaction(); /* ================== 6) Check duplicate ================== */ $dup = $con->prepare("SELECT id FROM driver WHERE phone = :p OR email = :e"); $dup->execute([':p' => $data['phone'], ':e' => $data['email']]); if ($dup->rowCount() > 0) { $con->rollBack(); jsonError("Phone or email already registered."); exit; } /* ================== 7) Insert Driver ================== */ $sqlDriver = " INSERT INTO driver ( id, phone, email, password, gender, license_type, national_number, name_arabic, issue_date, expiry_date, license_categories, address, licenseIssueDate, status, birthdate, site, first_name, last_name, accountBank, bankCode, employmentType, maritalStatus, fullNameMaritial, expirationDate, created_at, updated_at ) VALUES ( :id, :phone, :email, :pwd, :gender, :license_type, :national_number, :name_arabic, :issue_date, :expiry_date, :license_categories, :address, :licenseIssueDate, :status, :birthdate, :site, :first_name, :last_name, :accountBank, :bankCode, :employmentType, :maritalStatus, :fullNameMaritial, :expirationDate, NOW(), NOW() ) "; $insD = $con->prepare($sqlDriver); $okD = $insD->execute([ ':id' => $data['id'], ':phone' => $data['phone'], ':email' => $data['email'], ':pwd' => $pwdHashed, ':gender' => !empty($data['gender']) ? $data['gender'] : 'Male', ':license_type' => !empty($data['license_type']) ? $data['license_type'] : 'yet', ':national_number' => $data['national_number'], ':name_arabic' => $data['name_arabic'], ':issue_date' => !empty($data['issue_date']) ? $data['issue_date'] : '2020-01-01', ':expiry_date' => !empty($data['expiry_date']) ? $data['expiry_date'] : 'yet', ':license_categories' => !empty($data['license_categories']) ? $data['license_categories'] : 'B', ':address' => $data['address'], ':licenseIssueDate' => !empty($data['licenseIssueDate']) ? $data['licenseIssueDate'] : '2020-01-01', ':status' => !empty($data['status']) ? $data['status'] : 'yet', ':birthdate' => $data['birthdate'], ':site' => !empty($data['site']) ? $data['site'] : 'demascus', ':first_name' => $data['first_name'], ':last_name' => $data['last_name'], ':accountBank' => 'yet', ':bankCode' => 'yet', ':employmentType' => !empty($data['employmentType']) ? $data['employmentType'] : 'yet', ':maritalStatus' => !empty($data['maritalStatus']) ? $data['maritalStatus'] : 'yet', ':fullNameMaritial' => !empty($data['fullNameMaritial']) ? $data['fullNameMaritial'] : 'yet', ':expirationDate' => !empty($data['expirationDate']) ? $data['expirationDate'] : 'yet', ]); if (!$okD) { $con->rollBack(); jsonError("Failed to insert driver."); exit; } $driverID = $data['id']; /* ================== 8) Insert Vehicle ================== */ // ✅ استقبال القيم الجديدة (التصنيف والوقود) مع تعيين افتراضي 1 $vCatID = filterRequest("vehicle_category_id"); $vCatID = ($vCatID !== null && $vCatID !== '') ? $vCatID : 1; // 1 = Car $fTypeID = filterRequest("fuel_type_id"); $fTypeID = ($fTypeID !== null && $fTypeID !== '') ? $fTypeID : 1; // 1 = Petrol $hasCar = $con->prepare("SELECT 1 FROM CarRegistration WHERE driverID = :d LIMIT 1"); $hasCar->execute([':d' => $driverID]); $isDefault = $hasCar->rowCount() === 0 ? 1 : 0; $sqlCar = " INSERT INTO CarRegistration ( driverID, vin, car_plate, make, model, year, expiration_date, color, owner, color_hex, fuel, vehicle_category_id, fuel_type_id, isDefault, created_at, status ) VALUES ( :driverID, :vin, :car_plate, :make, :model, :year, :expiration_date, :color, :owner, :color_hex, :fuel, :vehicle_category_id, :fuel_type_id, :isDefault, NOW(), 'yet' ) "; $insC = $con->prepare($sqlCar); $okC = $insC->execute([ ':driverID' => $driverID, ':vin' => $car['vin'], ':car_plate' => $car['car_plate'], ':make' => $car['make'], ':model' => $car['model'], ':year' => $car['year'], ':expiration_date' => $car['expiration_date'], ':color' => $car['color'], ':owner' => $car['owner'], ':color_hex' => $car['color_hex'], ':fuel' => $car['fuel'], // النص القديم (للتوافق) ':vehicle_category_id' => $vCatID, // ✅ العمود الجديد ':fuel_type_id' => $fTypeID, // ✅ العمود الجديد ':isDefault' => $isDefault, ]); if (!$okC) { $con->rollBack(); jsonError("Failed to insert car registration."); exit; } $carRegID = $con->lastInsertId(); /* ================== 9) Store document links ================== */ $insDoc = $con->prepare(" INSERT INTO driver_documents (driverID, doc_type, image_name, link, upload_date) VALUES (:driverID, :doc_type, :image_name, :link, NOW()) "); foreach ($docKeys as $k) { $url = $docUrls[$k]; $name = basename(parse_url($url, PHP_URL_PATH) ?? ''); if ($name === '') { $name = $k . '_' . time() . '.jpg'; } $insDoc->execute([ ':driverID' => $driverID, ':doc_type' => $k, ':image_name' => $name, ':link' => $url, ]); } /* ================== 10) Commit ================== */ $con->commit(); /* ================== 11) Notification ================== */ try { $fcmSendUrl = 'https://api.intaleq.xyz/siro/ride/firebase/send_fcm.php'; $driverFullName = $raw_first_name . ' ' . $raw_last_name; $notificationTitle = 'تسجيل سائق جديد'; $notificationBody = "سائق جديد ($driverFullName) سجل برقم ID: $driverID وهو بانتظار المراجعة والتفعيل."; $notificationPayload = json_encode([ 'target' => 'service', 'title' => $notificationTitle, 'body' => $notificationBody, 'isTopic' => true, 'category' => 'new_driver_registration' ]); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $fcmSendUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json; charset=UTF-8']); curl_setopt($ch, CURLOPT_POSTFIELDS, $notificationPayload); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_exec($ch); curl_close($ch); } catch (Exception $notifyEx) { error_log("register_driver_and_car NOTIFY ERROR: " . $notifyEx->getMessage()); } printSuccess([ 'status' => 'success', 'driverID' => $driverID, 'carRegID' => $carRegID, 'documents' => $docUrls ]); } catch (Exception $e) { if (isset($con) && $con instanceof PDO && $con->inTransaction()) { $con->rollBack(); } error_log("register_driver_and_car ERROR: " . $e->getMessage()); jsonError("Server error: " . $e->getMessage()); } catch (PDOException $e) { if (isset($con) && $con instanceof PDO && $con->inTransaction()) { $con->rollBack(); } error_log("register_driver_and_car PDO: " . $e->getMessage()); jsonError("Database error."); } ?> ``` ## File: auth/syria/driver/drivers_pending_list.php ``` 'active' ORDER BY id DESC"; $stmt = $con->prepare($sql); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير foreach ($rows as &$r) { $r['phone'] = $encryptionHelper->decryptData($r['phone']); $r['first_name'] = $encryptionHelper->decryptData($r['first_name']); $r['last_name'] = $encryptionHelper->decryptData($r['last_name']); } jsonSuccess($rows); // يرجع كـ message: [...] } catch (PDOException $e) { jsonError("Error: " . $e->getMessage()); } ``` ## File: auth/syria/driver/sendWhatsAppDriver.php ``` encryptData($raw); $sql = "SELECT 1 FROM blacklist_driver WHERE phone = :ph LIMIT 1"; $q = $con->prepare($sql); $q->execute(['ph' => $enc_raw]); return (bool)$q->fetchColumn(); } /* 0) استقبل الرقم وتحقق من البلاك ليست */ $receiver = filterRequest("receiver"); if (!$receiver) { jsonError('Phone number is required.'); error_log("[send_otp_driver.php] Error: phone empty"); exit(); } if (is_blacklisted_driver($con, $encryptionHelper, $receiver)) { jsonError('This driver is blacklisted and cannot receive OTP.'); error_log("[send_otp_driver.php] BLOCKED (blacklisted): $receiver"); exit(); } /* 1) توليد الـ OTP */ $otp = rand(10000, 99999); $messageBody = "Your verification code for Siro is: " . $otp; /* 🟢 2) تخطي الإرسال الفعلي */ error_log("[send_otp_driver.php] Skipping actual WhatsApp send. OTP for $receiver: $otp"); /* 3) حفظ الـ OTP في قاعدة البيانات */ $receiver_enc = $encryptionHelper->encryptData($receiver); $otp_enc = $encryptionHelper->encryptData($otp); $exp = date('Y-m-d H:i:s', strtotime('+5 minutes')); $now = date('Y-m-d H:i:s'); try { // حذف أي رموز سابقة لنفس الرقم $con->prepare("DELETE FROM phone_verification WHERE phone_number = ?") ->execute([$receiver_enc]); $stmt = $con->prepare(" INSERT INTO phone_verification (phone_number, token_code, expiration_time, is_verified, created_at) VALUES (?, ?, ?, 0, ?) "); $stmt->execute([$receiver_enc, $otp_enc, $exp, $now]); jsonSuccess(null, 'OTP generated and saved successfully (no message sent)'); error_log("[send_otp_driver.php] OTP saved for driver $receiver"); } catch (PDOException $e) { error_log("[send_otp_driver.php] DB error: ".$e->getMessage()); jsonError('OTP generated but failed to save to database'); } ?> ``` ## File: auth/sms_new_backend/sendOtpPassenger.php ``` encryptData($text); $username = getenv('SMS_USERNAME'); $password = getenv('SMS_PASSWORD_EGYPT'); $sender = getenv('SMS_SENDER'); $language = filterRequest("language"); $receiver = filterRequest("receiver"); $otp = rand(10000, 99999); $message0 = "Tripz app code is " . $otp; $apiUrl = 'https://sms.kazumi.me/api/sms/send-sms'; $payload = [ 'username' => $username, 'password' => $password, 'language' => $language, 'sender' => $sender, 'receiver' => $receiver, 'message' => $message0 ]; error_log("Sending SMS to $receiver with OTP: $otp"); $response = callAPI("POST", $apiUrl, json_encode($payload)); error_log("API Response: " . print_r($response, true)); // التحقق من رسالة الاستجابة if ($response && isset($response->message) && $response->message == "Success") { $expiration_time = date('Y-m-d H:i:s', strtotime('+5 minutes')); $created_at = date('Y-m-d H:i:s'); error_log("Saving to DB: phone=$receiver, token=$otp, expires=$expiration_time"); try { $receiver1=$encryptionHelper->encryptData($receiver); $otp1=$encryptionHelper->encryptData($otp); $stmt = $con->prepare(" INSERT INTO phone_verification_passenger (phone_number, token, expiration_time, verified, created_at) VALUES (?, ?, ?, 0, ?) "); $success = $stmt->execute([$receiver1, $otp1, $expiration_time, $created_at]); if ($success) { error_log("OTP saved successfully to DB."); jsonSuccess(null, 'OTP sent and saved successfully'); } else { error_log("SQL execution failed."); jsonError('OTP sent but not saved to database'); } } catch (PDOException $e) { error_log("Database Error: " . $e->getMessage()); jsonError('Database error'); } } else { error_log("OTP not sent. API response did not indicate success. Response: " . print_r($response, true)); jsonError('OTP not sent'); } // دالة التعامل مع API function callAPI($method, $url, $data) { $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_POSTFIELDS => $data, CURLOPT_HTTPHEADER => ["Content-Type: application/json"] ]); $response = curl_exec($curl); if (curl_errno($curl)) { error_log("cURL Error: " . curl_error($curl)); } curl_close($curl); return json_decode($response); } ?> ``` ## File: auth/sms_new_backend/rasel_whatsapp.php ``` $receiver, // رقم المستلم "type" => "text", "message" => $messageBody, "instance_id" => "6863C59A7AFBD", // المعرف المأخوذ من مثال cURL "access_token"=> "68617b9b8fe53" // مفتاح الوصول المأخوذ من مثال cURL ]; error_log("Sending OTP to $receiver via RaseelPlus. Message: $messageBody"); // استدعاء الـ API $response = callAPI("POST", $apiUrl, json_encode($payload)); error_log("RaseelPlus API Response: " . print_r($response, true)); // --- نهاية التعديل --- // التحقق من الاستجابة من الـ API // ملاحظة: قد تحتاج إلى تعديل هذا الشرط بناءً على شكل الاستجابة الفعلي من RaseelPlus // نفترض هنا أن الاستجابة الناجحة تحتوي على "status":"success" أو شيء مشابه if ($response && !isset($response->error) && (isset($response->status) && $response->status == 'success' || isset($response->message))) { // تحديد وقت انتهاء صلاحية الرمز (بعد 5 دقائق) $expiration_time = date('Y-m-d H:i:s', strtotime('+5 minutes')); $created_at = date('Y-m-d H:i:s'); error_log("API call successful. Saving to DB: phone=$receiver, token=$otp, expires=$expiration_time"); try { // تشفير البيانات قبل حفظها (ممارسة أمنية جيدة) // $receiver_encrypted = $encryptionHelper->encryptData($receiver); // $otp_encrypted = $encryptionHelper->encryptData($otp); // استخدام البيانات غير المشفرة مؤقتاً إذا لم تكن تستخدم التشفير حالياً $receiver_to_db = $receiver; $otp_to_db = $otp; $stmt = $con->prepare(" INSERT INTO phone_verification_passenger (phone_number, token, expiration_time, verified, created_at) VALUES (?, ?, ?, 0, ?) "); $success = $stmt->execute([$receiver_to_db, $otp_to_db, $expiration_time, $created_at]); if ($success) { error_log("OTP saved successfully to DB."); // jsonSuccess() هي دالة مخصصة لديك لطباعة استجابة نجاح jsonSuccess(null, 'OTP sent and saved successfully'); } else { error_log("SQL execution failed."); // jsonError() هي دالة مخصصة لديك لطباعة استجابة فشل jsonError('OTP sent but failed to save to database'); } } catch (PDOException $e) { error_log("Database Error: " . $e->getMessage()); jsonError('Database error occurred'); } } else { // فشل إرسال الـ OTP $errorMessage = isset($response->message) ? $response->message : "Unknown error"; error_log("Failed to send OTP. API response: " . $errorMessage); jsonError('Failed to send OTP: ' . $errorMessage); } /** * دالة لإجراء استدعاءات API باستخدام cURL * @param string $method نوع الطلب (e.g., "POST", "GET") * @param string $url عنوان URL للـ API * @param mixed $data البيانات المراد إرسالها * @return mixed الاستجابة من الـ API بعد فك تشفير JSON */ function callAPI($method, $url, $data) { $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, // إرجاع الاستجابة كنص بدلاً من طباعتها CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, // مهلة زمنية للطلب CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_POSTFIELDS => $data, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Accept: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { error_log("cURL Error #: " . $err); return null; // إرجاع null في حالة وجود خطأ في cURL } else { return json_decode($response); // فك تشفير استجابة JSON } } // مثال على دالة طباعة النجاح (ضعها في ملف functions.php) ?> ``` ## File: auth/captin/updateDriverSecure.php ``` encryptData($value); $columnValues[] = "`$field` = ?"; $params[] = $encryptedValue; } } // تحقق من أن هناك حقول للتحديث if (empty($columnValues)) { jsonError("No valid encrypted passenger data provided for update."); exit; } // تركيب جملة SQL $setClause = implode(", ", $columnValues); $params[] = $id; $sql = "UPDATE `passengers` SET $setClause WHERE `id` = ?"; try { $stmt = $con->prepare($sql); foreach ($params as $index => $value) { $stmt->bindValue($index + 1, $value); } if ($stmt->execute()) { jsonSuccess(null, "Passenger data updated successfully with encryption"); } else { jsonError("Failed to update passenger data"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: auth/captin/sendOtpMessageDriver.php ``` encryptData($phone_number); $encryptedToken = $encryptionHelper->encryptData($token_code); $encryptedEmail = $encryptionHelper->encryptData($email); // اختياري إذا بتحب تشفيره // التحقق من وجود الرقم مسبقاً في قاعدة البيانات $sqlCheck = "SELECT * FROM `phone_verification` WHERE `phone_number` = :phone"; $stmtCheck = $con->prepare($sqlCheck); $stmtCheck->bindParam(":phone", $encryptedPhone); $stmtCheck->execute(); $success = false; // إذا كان الرقم موجود → تحديث if ($stmtCheck->rowCount() > 0) { $sqlUpdate = "UPDATE `phone_verification` SET `token_code` = :token, `expiration_time` = DATE_ADD(NOW(), INTERVAL 5 MINUTE) WHERE `phone_number` = :phone"; $stmt = $con->prepare($sqlUpdate); $stmt->bindParam(":token", $encryptedToken); $stmt->bindParam(":phone", $encryptedPhone); $stmt->execute(); $success = $stmt->rowCount() > 0; } else { // إذا الرقم غير موجود → إدخال جديد $sqlInsert = "INSERT INTO `phone_verification` (`phone_number`, `driverId`, `email`, `token_code`, `expiration_time`, `is_verified`, `created_at`) VALUES (:phone, :driverId, :email, :token, DATE_ADD(NOW(), INTERVAL 5 MINUTE), 0, NOW())"; $stmt = $con->prepare($sqlInsert); $stmt->bindParam(":phone", $encryptedPhone); $stmt->bindParam(":driverId", $driverId); $stmt->bindParam(":email", $encryptedEmail); $stmt->bindParam(":token", $encryptedToken); $stmt->execute(); $success = $stmt->rowCount() > 0; } // إذا تم الحفظ بنجاح → أرسل الرمز عبر SMS if ($success) { // تحميل بيانات الاتصال بالـ SMS API من المتغيرات البيئية $username = getenv('SMS_USERNAME'); $password = getenv('SMS_PASSWORD_EGYPT'); $sender = getenv('SMS_SENDER'); if (!$username || !$password || !$sender) { jsonError("SMS credentials are missing"); exit; } $message = "Tripz app code is " . $token_code; $receiver = $phone_number; $apiUrl = 'https://sms.kazumi.me/api/sms/send-sms'; $payload = [ 'username' => $username, 'password' => $password, 'language' => 'e', 'sender' => $sender, 'receiver' => $receiver, 'message' => $message ]; $jsonPayload = json_encode($payload); $smsResponse = callAPI("POST", $apiUrl, $jsonPayload); if ($smsResponse) { jsonSuccess(null, "Verification code sent and saved successfully"); } else { jsonError("Code saved, but SMS sending failed"); } } else { jsonError("Failed to save verification data"); } // دالة الاتصال بالـ API function callAPI($method, $url, $data) { $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_POSTFIELDS => $data, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Accept: application/json" ], CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 10 ]); $api_raw_response = curl_exec($curl); if (curl_errno($curl)) { error_log("cURL Error [".curl_errno($curl)."]: " . curl_error($curl)); curl_close($curl); return false; } curl_close($curl); $decoded_response = json_decode($api_raw_response, true); if (json_last_error() !== JSON_ERROR_NONE) { error_log("Invalid JSON response from SMS API."); return false; } error_log("SMS API response: " . print_r($decoded_response, true)); return $decoded_response; } ?> ``` ## File: auth/captin/login.php ``` encryptData($email); $phone = $encryptionHelper->encryptData($phone); $sql = "SELECT driver.id, driver.phone, driver.email, driver.password, driver.gender, driver.birthdate, driver.site, driver.first_name, driver.last_name, driver.education, driver.employmentType, driver.maritalStatus, driver.created_at, driver.updated_at, email_verifications.verified FROM driver LEFT JOIN email_verifications ON email_verifications.email = driver.email WHERE driver.phone = :phone AND driver.email = :email"; $stmt = $con->prepare($sql); $stmt->bindParam(':email', $email); $stmt->bindParam(':phone', $phone); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); $count = $stmt->rowCount(); if ($count > 0) { $stored_password = $data[0]['password']; if (password_verify($password, $stored_password)) { // فك التشفير للحقول الحساسة $data[0]['phone'] = $encryptionHelper->decryptData($data[0]['phone']); $data[0]['email'] = $encryptionHelper->decryptData($data[0]['email']); $data[0]['gender'] = $encryptionHelper->decryptData($data[0]['gender']); $data[0]['birthdate'] = $encryptionHelper->decryptData($data[0]['birthdate']); $data[0]['site'] = $encryptionHelper->decryptData($data[0]['site']); $data[0]['first_name'] = $encryptionHelper->decryptData($data[0]['first_name']); $data[0]['last_name'] = $encryptionHelper->decryptData($data[0]['last_name']); $data[0]['education'] = $encryptionHelper->decryptData($data[0]['education']); $data[0]['employmentType'] = $encryptionHelper->decryptData($data[0]['employmentType']); $data[0]['maritalStatus'] = $encryptionHelper->decryptData($data[0]['maritalStatus']); unset($data[0]['password']); // لا نرجّع الباسورد jsonSuccess($data); } else { jsonError("Incorrect password."); } } else { jsonError("User does not exist."); } ?> ``` ## File: auth/captin/updateAccountBank.php ``` $value) { $filtered = filterRequest($key); if ($key === "password") { // هاش لكلمة المرور $hashed = password_hash($filtered, PASSWORD_DEFAULT); $columnValues[] = "`password` = '$hashed'"; } elseif (in_array($key, $fieldsToEncrypt)) { $encrypted = $encryptionHelper->encryptData($filtered); $columnValues[] = "`$key` = '$encrypted'"; } elseif (in_array($key, $plainFields)) { $columnValues[] = "`$key` = '$filtered'"; } } // بناء جملة التحديث $setClause = implode(", ", $columnValues); $sql = "UPDATE `driver` SET $setClause WHERE `id` = '$id'"; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Driver data updated successfully"); } else { jsonError("Failed to update driver data"); } ?> ``` ## File: auth/captin/verifyOtpDriver.php ``` encryptData($phone_number); $encryptedToken = $encryptionHelper->encryptData($token_code); // Check if the phone number and token code match $sql = "SELECT `id`, `phone_number`, `token_code`, `expiration_time`, `is_verified`, `created_at` FROM `phone_verification` WHERE `phone_number` = :phone_number AND `token_code` = :token_code -- AND `expiration_time` > NOW()"; $stmt = $con->prepare($sql); $stmt->bindParam(':phone_number', $encryptedPhone, PDO::PARAM_STR); $stmt->bindParam(':token_code', $encryptedToken, PDO::PARAM_STR); $stmt->execute(); $result = $stmt->fetch(); if ($result) { // $id = $result["id"]; $sql = "UPDATE `phone_verification` SET `is_verified` = 1 WHERE `phone_number` = :phone_number"; $stmt = $con->prepare($sql); $stmt->bindParam(':phone_number', $phone_number, PDO::PARAM_STR); $stmt->execute(); jsonSuccess($message = "Your phone number has been verified."); } else { jsonError($message = "Your phone number could not be verified. Please try again."); } ?> ``` ## File: auth/captin/loginUsingCredentialsWithoutGoogle.php ``` encryptData($email); // SQL لاسترجاع المستخدم بناءً على البريد الإلكتروني المشفر $sql = "SELECT driver.id, driver.phone, driver.email, driver.gender, driver.birthdate, driver.site, driver.first_name, driver.last_name, driver.bankCode, driver.accountBank, driver.education, driver.employmentType, driver.maritalStatus, driver.created_at, driver.updated_at, driver.password, phone_verification.is_verified, CarRegistration.make, CarRegistration.model, CarRegistration.year FROM driver LEFT JOIN phone_verification ON phone_verification.phone_number = driver.phone LEFT JOIN CarRegistration ON CarRegistration.driverID = driver.id WHERE driver.email = :email AND phone_verification.is_verified = '1' LIMIT 1"; $stmt = $con->prepare($sql); $stmt->bindParam(':email', $encryptedEmail); $stmt->execute(); $data = $stmt->fetch(PDO::FETCH_ASSOC); if ($data) { if (password_verify($password, $data['password'])) { unset($data['password']); // فك تشفير الحقول الحساسة $data['phone'] = $encryptionHelper->decryptData($data['phone']); $data['email'] = $encryptionHelper->decryptData($data['email']); $data['gender'] = $encryptionHelper->decryptData($data['gender']); $data['birthdate'] = $encryptionHelper->decryptData($data['birthdate']); $data['site'] = $encryptionHelper->decryptData($data['site']); $data['first_name'] = $encryptionHelper->decryptData($data['first_name']); $data['last_name'] = $encryptionHelper->decryptData($data['last_name']); $data['education'] = $encryptionHelper->decryptData($data['education']); $data['employmentType'] = $encryptionHelper->decryptData($data['employmentType']); $data['maritalStatus'] = $encryptionHelper->decryptData($data['maritalStatus']); echo json_encode([ "status" => "success", "data" => $data ]); } else { jsonError("Incorrect password."); } } else { jsonError("User does not exist or phone number not verified."); } $stmt = null; $con = null; exit(); ?> ``` ## File: auth/captin/updateDriverClaim.php ``` prepare($checkSql); $checkStmt->bindParam(':driverId', $driverId, PDO::PARAM_INT); $checkStmt->execute(); $giftExists = $checkStmt->fetchColumn(); if ($giftExists > 0) { jsonError("Gift already exists for this driver"); exit; } // Insert a new claimed gift $sql = "INSERT INTO driver_gifts (driver_id, gift_description, is_claimed) VALUES (:driverId, 'new account 300 le', 1)"; $stmt = $con->prepare($sql); $stmt->bindParam(':driverId', $driverId, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Gift data saved successfully"); } else { jsonError("Failed to save gift data"); } } catch (PDOException $e) { error_log("Database Error: " . $e->getMessage()); jsonError("An error occurred while saving the data"); } ?> ``` ## File: auth/captin/register.php ``` encryptData($data[$f]); } } /* =========== 3) توليد driver ID (id) إذا لم يُرسَل =========== */ /* =========== 4) هَش كلمة المرور =========== */ $data['password_hashed'] = password_hash($data['password'], PASSWORD_DEFAULT); /* =========== 5) منع التكرار في الهاتف / الإيميل =========== */ $dup = $con->prepare( "SELECT id FROM driver WHERE phone = :phone OR email = :email" ); $dup->execute([ ':phone' => $data['phone'], ':email' => $data['email'] ]); if ($dup->rowCount() > 0) { jsonError("Phone or email already registered."); exit; } /* =========== 6) إدخال السجل الجديد =========== */ $sql = " INSERT INTO driver ( id, phone, email, password, gender, license_type, national_number, name_arabic, issue_date, expiry_date, license_categories, address, licenseIssueDate, status, birthdate, site, first_name, last_name, accountBank, bankCode, employmentType, maritalStatus, fullNameMaritial, expirationDate, created_at, updated_at ) VALUES ( :id, :phone, :email, :pwd, :gender, :license_type, :national_number, :name_arabic, :issue_date, :expiry_date, :license_categories, :address, :licenseIssueDate, :status, :birthdate, :site, :first_name, :last_name, :accountBank, :bankCode, :employmentType, :maritalStatus, :fullNameMaritial, :expirationDate, NOW(), NOW() ) "; $ins = $con->prepare($sql); // خريطة الربط (تطابق تمامًا أسماء الـ placeholders في الـ SQL أعلاه) $bind = [ 'id' => $data['id'], 'phone' => $data['phone'], 'email' => $data['email'], 'pwd' => $data['password_hashed'], 'gender' => $data['gender'], 'license_type' => $data['license_type'], 'national_number' => $data['national_number'], 'name_arabic' => $data['name_arabic'], 'issue_date' => $data['issue_date'], 'expiry_date' => $data['expiry_date'], 'license_categories'=> $data['license_categories']?? 'B', 'address' => $data['address'], 'licenseIssueDate' => $data['licenseIssueDate'], 'status' => $data['status'] ?? 'yet', 'birthdate' => $data['birthdate'], 'site' => $data['site'], 'first_name' => $data['first_name'], 'last_name' => $data['last_name'], 'accountBank' => 'yet', 'bankCode' => 'yet', 'employmentType' => $data['employmentType']?? 'yet', 'maritalStatus' => $data['maritalStatus']?? 'yet', 'fullNameMaritial' => $data['fullNameMaritial']?? 'yet', 'expirationDate' => $data['expirationDate']?? 'yet', ]; foreach ($bind as $key => $value) { $ins->bindValue(":$key", $value); } if ($ins->execute()) { jsonSuccess($data['id']); // ترجع driver ID } else { jsonError("Failed to insert driver record."); } } catch (PDOException $e) { error_log("DriverInsert PDO: " . $e->getMessage()); jsonError("Database error."); } ?> ``` ## File: auth/captin/loginFromGoogle.php ``` encryptData($emailRaw); // error_log("[Debug] Email (encrypted): $emailEnc"); /* ──────────────────────────────── 3) إعداد الاستعلام الموحَّد ───────────────────────────────── */ $sql = " SELECT driver.id, driver.phone, driver.email, driver.gender, driver.birthdate, driver.site, driver.first_name, driver.last_name, driver.bankCode, driver.accountBank, driver.employmentType,driver.status, driver.maritalStatus, driver.created_at, driver.updated_at, phone_verification.is_verified, CarRegistration.make, CarRegistration.model, CarRegistration.year, df.is_claimed, inv.isInstall, inv.isGiftToken FROM driver LEFT JOIN phone_verification ON phone_verification.phone_number = driver.phone LEFT JOIN driver_gifts df ON df.driver_id = driver.id LEFT JOIN CarRegistration ON CarRegistration.driverID = driver.id LEFT JOIN invites inv ON inv.driverId = driver.id WHERE driver.id = :id -- AND phone_verification.is_verified = '1' LIMIT 1 "; // error_log("[Debug] queryString:\n$sql"); $stmt = $con->prepare($sql); // باراميترات الربط $params = [ //':email' => $emailEnc, ':id' => $driverID, ]; foreach ($params as $k => $v) { $stmt->bindValue($k, $v); } /* ───────── dumpParams (اختياري) ───────── */ ob_start(); $stmt->debugDumpParams(); error_log("[Debug] dumpParams:\n" . ob_get_clean()); /* ──────────────────────────────── 4) تنفيذ الاستعلام ───────────────────────────────── */ $stmt->execute(); error_log("[Debug] stmt->rowCount(): " . $stmt->rowCount()); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // error_log("[Debug] Raw fetched JSON: " . json_encode($rows, JSON_UNESCAPED_UNICODE)); if (!$rows) { jsonError("User does not exist or phone not verified."); exit; } /* ──────────────────────────────── 5) فك التشفير للحقول الحسّاسة ───────────────────────────────── */ $data = &$rows[0]; // مرجع لتوفير الذاكرة $decryptIfNotNull = function($field) use (&$data, $encryptionHelper) { if (isset($data[$field]) && $data[$field] !== null) { $data[$field] = $encryptionHelper->decryptData($data[$field]); } }; foreach ([ 'phone', 'email', 'gender', 'birthdate', 'site', 'first_name', 'last_name' ] as $field) { $decryptIfNotNull($field); } error_log("[Debug] Raw fetched JSON: " . json_encode($rows, JSON_UNESCAPED_UNICODE)); echo json_encode([ "status" => "success", "count" => 1, "data" => $rows // نتيجة واحدة فقط ], JSON_UNESCAPED_UNICODE); } catch (PDOException $e) { error_log("[PDO ERROR] " . $e->getMessage()); jsonError("Database error: ".$e->getCode()); } catch (Exception $e) { error_log("[GENERAL ERROR] " . $e->getMessage()); jsonError("Error occurred."); } finally { $stmt = null; $con = null; } ?> ``` ## File: auth/captin/updateShamCashDriver.php ``` encryptData($accountBank); // 2. كود المحفظة يبقى كما هو (حسب القواعد bankCode غير مشفر) $plainBankCode = $encryptionHelper->encryptData($bankCode); // 3. جملة التحديث $stmt = $con->prepare("UPDATE `driver` SET `accountBank` = ?, `bankCode` = ? WHERE `id` = ?"); $stmt->execute(array($encryptedAccountBank, $plainBankCode, $id)); // التحقق من نجاح العملية // rowCount > 0 يعني تم التحديث، أحياناً يعطي 0 إذا كانت البيانات هي نفسها لم تتغير // لذا نرسل نجاح في كلتا الحالتين طالما لم يحدث Error jsonSuccess(null, "ShamCash info updated successfully"); } catch (PDOException $e) { // في حال وجود خطأ في قاعدة البيانات jsonError("Database Error: " . $e->getMessage()); } } else { jsonError("Missing required fields: id, accountBank, or bankCode"); } ?> ``` ## File: auth/captin/forgetPassword.php ``` ``` ## File: auth/captin/removeAccount.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Passenger deleted successfully."); } else { jsonError("Failed to delete passenger."); } ?> ``` ## File: auth/captin/addCriminalDocuments.php ``` prepare($sql); // Bind parameters $stmt->bindParam(':driverId', $driverId, PDO::PARAM_INT); $stmt->bindParam(':issueDate', $issueDate, PDO::PARAM_STR); $stmt->bindParam(':inspectionResult', $inspectionResult, PDO::PARAM_STR); // Execute the statement $stmt->execute(); // Check if the insertion was successful if ($stmt->rowCount() > 0) { jsonSuccess(null, "Criminal document data saved successfully"); } else { jsonError("Failed to save criminal document data"); } } catch (PDOException $e) { // Log the error and print a generic failure message error_log("Database Error: " . $e->getMessage()); jsonError("An error occurred while saving the data"); } ?> ``` ## File: auth/captin/deletecaptainAccounr.php ``` prepare("SELECT phone FROM `driver` WHERE `id` = :id"); $stmtPhone->bindParam(':id', $id, PDO::PARAM_INT); $stmtPhone->execute(); $driverData = $stmtPhone->fetch(PDO::FETCH_ASSOC); // التحقق من وجود السائق if (!$driverData) { jsonError("Driver not found"); exit(); } $phone = $driverData['phone']; // 2. تحديث حالة السائق $sql = "UPDATE `driver` SET `status` = 'deleteFromHimself' WHERE `id` = :id"; $stmt = $con->prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { // 3. الإضافة إلى القائمة السوداء (blacklist_driver) // نستخدم NOW() لتسجيل الوقت الحالي تلقائياً // لا نمرر id العمود الأول لأنه غالباً Auto Increment في قاعدة البيانات $insertSql = "INSERT INTO `blacklist_driver` (`driver_id`, `phone`, `reason`, `created_at`) VALUES (:driver_id, :phone, :reason, NOW())"; $insertStmt = $con->prepare($insertSql); $insertStmt->execute([ ':driver_id' => $id, ':phone' => $phone, ':reason' => $reason ]); jsonSuccess(null, "Record marked as deleted and added to blacklist successfully"); } else { jsonError("Failed to update record or no change made"); } } catch (PDOException $e) { // في حال حدوث خطأ في قاعدة البيانات (مثلاً تكرار الإضافة) jsonError("Database Error: " . $e->getMessage()); } ?> ``` ## File: auth/captin/getAccount.php ``` prepare($sql); $stmt->bindParam(':id', $driverID, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else { jsonError("No account bank record found"); } ?> ``` ## File: auth/captin/getAllDriverSecure.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك تشفير الحقول الحساسة foreach ($rows as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); $row['email'] = $encryptionHelper->decryptData($row['email']); $row['gender'] = $encryptionHelper->decryptData($row['gender']); $row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']); $row['first_name'] = $encryptionHelper->decryptData($row['first_name']); $row['last_name'] = $encryptionHelper->decryptData($row['last_name']); $row['sosPhone'] = $encryptionHelper->decryptData($row['sosPhone']); } jsonSuccess($rows); } else { jsonError("No wallet record found"); } ?> ``` ## File: auth/captin/verifyEmail.php ``` ``` ## File: auth/captin/getPromptDriverDocumentsEgypt.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: auth/sms/sms_to_user_change_fingerprint.php ``` encryptData($phone); $otpEncrypted = $encryptionHelper->encryptData($otp); // 4️⃣ تخزين OTP في قاعدة البيانات try { $insertOtp = "INSERT INTO otp_verification_fingerPrint (phone, otp) VALUES (?, ?)"; $stmt = $con->prepare($insertOtp); $stmt->execute([$phoneEncrypted, $otpEncrypted]); } catch (PDOException $e) { error_log("DB Insert Error: " . $e->getMessage()); jsonError("Failed to save OTP to the database"); exit; } // 5️⃣ إرسال الرسالة عبر API $message = "$appName app code is $otp\ncopy it to app"; $payload = json_encode([ "username" => $username, "password" => $password, "message" => $message, "language" => $language, "sender" => $sender, "receiver" => $phone ]); $ch = curl_init($apiEndpoint); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // 6️⃣ التحقق من نجاح الإرسال if ($httpCode != 200) { error_log("SMS API Failed. HTTP Code: $httpCode. Response: " . $response); jsonError("Failed to send OTP SMS"); exit; } // 7️⃣ إرجاع النتيجة jsonSuccess(["message" => "OTP sent successfully"]); ?> ``` ## File: auth/sms/updatePhoneInvalidSMS.php ``` encryptData($phone_number); // Prepare the SQL query to verify the phone $sql = "UPDATE phone_verification SET is_verified = 1 WHERE phone_number = :phone_number"; // Prepare the statement $stmt = $con->prepare($sql); $stmt->bindParam(":phone_number", $phone_number); // Execute the query $stmt->execute(); $affectedRows = $stmt->rowCount(); // Check if the update was successful if ($affectedRows > 0) { jsonSuccess(["message" => "Phone number verified successfully"]); } else { jsonError("No phone number found or verification failed"); } ?> ``` ## File: auth/sms/updatePhoneInvalidSMSPassenger.php ``` encryptData($phone_number); // تنفيذ الاستعلام $sql = "UPDATE phone_verification_passenger SET verified = 1 WHERE phone_number = :phone_number"; $stmt = $con->prepare($sql); $stmt->bindParam(":phone_number", $phone_number); $stmt->execute(); $affectedRows = $stmt->rowCount(); // إرجاع النتيجة if ($affectedRows > 0) { jsonSuccess(["message" => "Phone number verified successfully"]); } else { jsonError("No phone number found or verification failed"); } ?> ``` ## File: auth/sms/getSender.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($stmt->rowCount() > 0) { jsonSuccess($data = $result); } else { jsonError($message = "No driver order data found"); } ?> ``` ## File: auth/google_auth/check_status.php ``` 'error', 'message' => 'Login token is missing.']); exit(); } $loginToken = basename($input['loginToken']); // حماية // 2. التحقق من ملف الجلسة $pollDir = __DIR__ . '/polls'; $sessionFile = $pollDir . '/' . $loginToken . '.json'; if (file_exists($sessionFile)) { $sessionData = json_decode(file_get_contents($sessionFile), true); // إذا نجحت العملية، أرجع البيانات واحذف الملف if ($sessionData['status'] === 'success') { echo json_encode($sessionData); unlink($sessionFile); // حذف الملف بعد النجاح } else { // إذا كانت لا تزال معلقة echo json_encode(['status' => 'pending']); } } else { // إذا انتهت المهلة أو حدث خطأ http_response_code(404); echo json_encode(['status' => 'expired', 'message' => 'Session not found or expired.']); } exit(); ?> ``` ## File: auth/google_auth/google_auth.php ``` false, 'error' => null, 'data' => null, ]; try { if (!isset($_POST['code'])) { throw new Exception("Missing authorization code."); } $code = $_POST['code']; $client = new Client(); $client->setClientId('1086900987150-j8brn0i5s97315kh1ej9jr72grkfqgh5.apps.googleusercontent.com'); $client->setClientSecret('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'); $client->setRedirectUri('postmessage'); $client->addScope('email'); $client->addScope('profile'); $token = $client->fetchAccessTokenWithAuthCode($code); if (isset($token['error'])) { throw new Exception("Access token error: " . $token['error']); } $client->setAccessToken($token['access_token']); $oauth2 = new Google_Service_Oauth2($client); $userinfo = $oauth2->userinfo->get(); $response['success'] = true; $response['data'] = [ 'id' => $userinfo->id, 'email' => $userinfo->email, 'name' => $userinfo->name, 'picture' => $userinfo->picture, ]; } catch (Exception $e) { $response['error'] = $e->getMessage(); } echo json_encode($response); ``` ## File: auth/google_auth/login.php ``` 'pending'])); // 5. بناء رابط جوجل مع تمرير المعرف الفريد في متغير 'state' $authUrl = 'https://accounts.google.com/o/oauth2/v2/auth?' . http_build_query([ 'client_id' => $clientID, 'redirect_uri' => $redirectUri, 'response_type' => 'code', 'scope' => $scopes, 'access_type' => 'offline', 'state' => $loginToken // مهم جداً ]); // 6. إرجاع الرابط والمعرف للتطبيق header('Content-Type: application/json'); echo json_encode([ 'authUrl' => $authUrl, 'loginToken' => $loginToken ]); exit(); ?> ``` ## File: auth/google_auth/callback.php ``` $authCode, 'client_id' => $clientID, 'client_secret' => $clientSecret, 'redirect_uri' => $redirectUri, 'grant_type' => 'authorization_code' ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $tokenUrl); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $tokenData = json_decode($response, true); if (isset($tokenData['access_token'])) { // 4. جلب بيانات المستخدم $userInfoUrl = 'https://www.googleapis.com/oauth2/v2/userinfo?access_token=' . $tokenData['access_token']; $userInfoResponse = file_get_contents($userInfoUrl); $userData = json_decode($userInfoResponse, true); if (isset($userData['id'])) { // 5. تحديث ملف الجلسة بالبيانات الجديدة $finalData = [ 'status' => 'success', 'userData' => $userData ]; file_put_contents($sessionFile, json_encode($finalData)); } } // 6. عرض صفحة نجاح للمستخدم في المتصفح echo 'Success

Authentication Successful

You can now return to the Tripz app.

'; exit(); ?> ``` ## File: auth/token_passenger/send_otp.php ``` true, * 'details' => ['status' => 'PENDING' | 'SENT' | …] * ] */ $sentOK = $response['success'] ?? false; $statusOK = in_array($response['details']['status'] ?? '', ['PENDING', 'SENT', 'DELIVERED'], true); if ($sentOK ) { /* 3) تشفير البيانات وحفظ الرمز في قاعدة البيانات */ $receiver_enc = $encryptionHelper->encryptData($receiver); $otp_enc = $encryptionHelper->encryptData($otp); $exp = date('Y-m-d H:i:s', strtotime('+5 minutes')); $now = date('Y-m-d H:i:s'); try { $con->prepare("DELETE FROM token_verification WHERE phone_number = ?") ->execute([$receiver_enc]); $stmt = $con->prepare(" INSERT INTO token_verification (phone_number, token, expiration_time, verified, created_at) VALUES (?, ?, ?, 0, ?) "); $stmt->execute([$receiver_enc, $otp_enc, $exp, $now]); jsonSuccess(null, 'OTP sent and saved successfully'); } catch (PDOException $e) { jsonError('OTP sent but failed to save to database'); } } else { $errMsg = $response['message'] ?? 'Unknown error'; jsonError('Failed to send OTP: ' . $errMsg); } /* ----------------------------------------------------------------- * يمكن حذف callAPI() تمامًا إن لم يعد مستخدمًا في أي ملف آخر. * ---------------------------------------------------------------- */ function callAPI($method, $url, $data) { /* … (أبقِها أو احذفها) */ } ?> ``` ## File: auth/token_passenger/verify_otp.php ``` encryptData($phoneNumber); $otp_encrypted = $encryptionHelper->encryptData($otp); try { // 1. التحقق من Redis بدلاً من MySQL if (!$redis) { jsonError("Security service unavailable"); exit; } $cachedOtp = $redis->get("otp:passenger:$phoneNumber"); if ($cachedOtp && $cachedOtp == $otp) { // ننجح في التحقق ونحذف المفتاح من Redis لمنع استخدامه مرة أخرى (One-time use) $redis->del("otp:passenger:$phoneNumber"); error_log("[verify_otp.php] OTP verified via Redis for phone: $phoneNumber"); // 2. التحقق من وجود الراكب في قاعدة البيانات $passengerStmt = $con->prepare("SELECT id FROM passengers WHERE phone = ?"); $passengerStmt->execute([$phoneNumber_encrypted]); $passenger = $passengerStmt->fetch(PDO::FETCH_ASSOC); if ($passenger) { $passengerID = $passenger['id']; // تحديث التوكن والبصمة إن وجدا $newToken = filterRequest("token"); $fingerPrint = filterRequest("fingerPrint"); if ($newToken && $fingerPrint) { $tokenEncrypted = $encryptionHelper->encryptData($newToken); $updateTokenStmt = $con->prepare("UPDATE tokens SET token = ?, fingerPrint = ? WHERE passengerID = ?"); $updateTokenStmt->execute([$tokenEncrypted, $fingerPrint, $passengerID]); } printSuccess([ "message" => "Token verified and updated.", "isRegistered" => true, "passengerID" => $passengerID ]); } else { printSuccess([ "message" => "Phone verified, passenger not found.", "isRegistered" => false ]); } } else { error_log("[verify_otp.php] Invalid or expired OTP for phone: $phoneNumber"); jsonError("Invalid or expired OTP."); } } catch (Exception $e) { // Log the detailed database error message for debugging. error_log("[verify_otp.php] FATAL DATABASE ERROR: " . $e->getMessage()); jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: auth/token_passenger/driver/verify_otp_driver.php ``` encryptData($phoneNumber); $otp_encrypted = $encryptionHelper->encryptData($otp); try { $stmt = $con->prepare(" SELECT * FROM token_verification_driver WHERE phone_number = ? AND token = ? "); $stmt->execute([$phoneNumber_encrypted, $otp_encrypted]); $result = $stmt->fetch(PDO::FETCH_ASSOC); if ($result) { $expiration_time = strtotime($result['expiration_time']); if (time() <= $expiration_time) { $con->prepare("UPDATE token_verification_driver SET verified = 1 WHERE id = ?") ->execute([$result['id']]); $driverStmt = $con->prepare("SELECT id FROM driver WHERE phone = ?"); $driverStmt->execute([$phoneNumber_encrypted]); $driver = $driverStmt->fetch(PDO::FETCH_ASSOC); if ($driver) { $driverID = $driver['id']; $newToken = filterRequest("token"); $fingerPrint = filterRequest("fingerPrint"); if ($newToken && $fingerPrint) { $tokenEncrypted = $encryptionHelper->encryptData($newToken); $checkTokenStmt = $con->prepare("SELECT id FROM driverToken WHERE captain_id = ?"); $checkTokenStmt->execute([$driverID]); if ($checkTokenStmt->rowCount() > 0) { $con->prepare("UPDATE driverToken SET token = ?, fingerPrint = ? WHERE captain_id = ?") ->execute([$tokenEncrypted, $fingerPrint, $driverID]); } else { $con->prepare("INSERT INTO driverToken (token, fingerPrint, captain_id, created_at) VALUES (?, ?, ?, NOW())") ->execute([$tokenEncrypted, $fingerPrint, $driverID]); } $response = [ "message" => "Driver token verified and updated.", "isRegistered" => true, "driverID" => $driverID ]; jsonSuccess($response); } else { jsonError("Token or fingerprint missing."); } } else { printSuccess([ "message" => "Phone verified, but driver not found.", "isRegistered" => false ]); } } else { jsonError("OTP expired. Request a new one."); } } else { jsonError("Invalid OTP."); } } catch (PDOException $e) { jsonError("Database error occurred."); } ``` ## File: auth/token_passenger/driver/send_otp_driver.php ``` true/false, * 'message' => 'Message sent successfully!', * 'details' => ['status' => 'PENDING' | 'SENT' | …] * ] */ $raw = sendWhatsAppFromServer($receiver, $messageBody); $response = is_string($raw) ? json_decode($raw, true) : (array) $raw; $sentOK = $response['success'] ?? false; $waStatus = $response['details']['status'] ?? ''; if ($sentOK ) { /* 3) تشفير البيانات وحفظها في DB ----------------------------------- */ $receiver_enc = $encryptionHelper->encryptData($receiver); $otp_enc = $encryptionHelper->encryptData($otp); $exp = date('Y-m-d H:i:s', strtotime('+5 minutes')); $now = date('Y-m-d H:i:s'); try { // حذف رموز قديمة $con->prepare("DELETE FROM token_verification_driver WHERE phone_number = ?") ->execute([$receiver_enc]); $stmt = $con->prepare(" INSERT INTO token_verification_driver (phone_number, token, expiration_time, verified, created_at) VALUES (?, ?, ?, 0, ?) "); $stmt->execute([$receiver_enc, $otp_enc, $exp, $now]); jsonSuccess(null, 'OTP sent and saved successfully'); } catch (PDOException $e) { jsonError('OTP sent but failed to save to database'); } } else { $errMsg = $response['message'] ?? 'Unknown error'; jsonError('Failed to send OTP: ' . $errMsg); } /* ----------------------------------------------------------------------- * أبقينا callAPI() فقط إذا كان يُستخدم في ملفات أخرى – احذفه إن شئت. * --------------------------------------------------------------------- */ function callAPI($method, $url, $data) { /* … */ } ?> ``` ## File: auth/document_syria/ai_document.php ``` 'image/jpeg', 'png' => 'image/png', default => 'application/octet-stream', }; $prompts = [ "id_front_sy" => << << << << << << [ ["role" => "user", "parts" => [["text" => $prompt]]], ["role" => "user", "parts" => [["inlineData" => ["mimeType" => $mimeType, "data" => $imageBase64]]]] ] ]; $ch = curl_init($apiURL); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); $response = curl_exec($ch); if (curl_errno($ch)) { $error_msg = curl_error($ch); error_log("CURL error: $error_msg"); jsonError("AI Error: $error_msg"); curl_close($ch); exit; } curl_close($ch); error_log("AI raw response: $response"); $data = json_decode($response, true); if (json_last_error() !== JSON_ERROR_NONE) { error_log("JSON decode error: " . json_last_error_msg()); jsonError("Failed to parse AI response"); exit; } $textRaw = $data['candidates'][0]['content']['parts'][0]['text'] ?? ''; $textRaw = trim(preg_replace('/```json|```/', '', $textRaw)); $json = json_decode($textRaw, true); $requiredKey = match ($type) { 'id_front_sy' => 'national_number', 'id_back_sy' => 'gender', 'driving_license_sy' => 'license_type', 'vehicle_license_sy' => 'chassis', default => null, }; if (!$json || ($requiredKey && !isset($json[$requiredKey]))) { error_log("AI response missing required key '$requiredKey': $textRaw"); jsonError("AI failed to extract required information"); exit; } printSuccess([ "image_url" => $imageUrl, "data" => $json ]); ``` ## File: auth/document_syria/uploadDocSyria.php ``` file($file['tmp_name']) ?: 'application/octet-stream'; $allowedMime = ['image/jpeg', 'image/png']; if (!in_array($mime, $allowedMime, true)) { error_log("Unsupported MIME type: $mime"); jsonError("Unsupported image MIME type"); exit; } // (اختياري) حد أقصى للحجم 10MB $maxBytes = 10 * 1024 * 1024; if ($file['size'] > $maxBytes) { error_log("Image too large: {$file['size']} bytes"); jsonError("Image too large (max 10MB)"); exit; } // 📁 مسارات الحفظ $uploadDir = "../uploads/documents/"; if (!is_dir($uploadDir)) { if (!mkdir($uploadDir, 0755, true) && !is_dir($uploadDir)) { error_log("Failed to create upload directory: $uploadDir"); jsonError("Server error: cannot create upload directory"); exit; } } $baseName = "driver_{$type}_{$driverId}"; $uniqueName = $baseName . "." . $extension; $uploadPath = $uploadDir . $uniqueName; // ⬆️ نقل الملف if (!move_uploaded_file($file['tmp_name'], $uploadPath)) { error_log("Failed to move uploaded file to $uploadPath"); jsonError("Failed to move uploaded image"); exit; } // 🔒 منع التنفيذ لو رُفع PHP بالخطأ @chmod($uploadPath, 0644); // 🌐 توليد BASE_URL آمن (يدعم ENV أو يعتمد على المضيف الحالي) if (!defined('BASE_URL')) { $APP_BASE_URL = rtrim(getenv('APP_BASE_URL') ?: '', '/'); if ($APP_BASE_URL === '') { $scheme = isset($_SERVER['REQUEST_SCHEME']) ? $_SERVER['REQUEST_SCHEME'] : ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http'); $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; define('BASE_URL', $scheme . '://' . $host); } else { define('BASE_URL', $APP_BASE_URL); } } // ⚙️ مسار الرابط العام (عدّل المسار حسب نشر مشروعك) $publicPath = "/siro/auth/uploads/documents/" . $uniqueName; $imageUrl = rtrim(BASE_URL, '/') . $publicPath; // ✅ نتيجة نهائية: فقط رابط الصورة وبعض البيانات المفيدة printSuccess([ $imageUrl, ]); ``` ## File: auth/Tester/getTesterApp.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($stmt->rowCount() > 0) { // Print the retrieved data // echo json_encode($result); jsonSuccess($data = $result); } else { // Print a failure message jsonError($message = "No driver order data found"); } ?> ``` ## File: auth/Tester/updateTesterApp.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = "Test data updated successfully"); } else { // Print a failure message jsonError($message = "Failed to update driver order data"); } ?> ``` ## File: auth/passengerOTP/sendOtpPassenger.php ``` prepare($sql); $stmt->execute(); $rowCount = $stmt->rowCount(); if ($rowCount > 0) { // The phone number already exists, so update the data $sql = "UPDATE `phone_verification_passenger` SET `token_code` = '$token_code', `expiration_time` = DATE_ADD(NOW(), INTERVAL 5 MINUTE) WHERE `phone_number` = '$phone_number'"; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // The update was successful jsonSuccess($message = "Phone verification data updated successfully"); } else { // The update was unsuccessful jsonError($message = "Failed to update phone verification data"); } } else { // The phone number does not exist, so insert the data $sql = "INSERT INTO `phone_verification_passenger` (`phone_number`, `token_code`, `expiration_time`, `is_verified`, `created_at`) VALUES ('$phone_number', '$token_code', DATE_ADD(NOW(), INTERVAL 5 MINUTE), 0, NOW())"; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // The insertion was successful jsonSuccess($message = "Phone verification data saved successfully"); } else { // The insertion was unsuccessful jsonError($message = "Failed to save phone verification data"); } } ?> ``` ## File: auth/passengerOTP/verifyOtpPassenger.php ``` encryptData(filterRequest("phone_number")); $token_code = $encryptionHelper->encryptData(filterRequest("token")); // error_log("phone=$phone_number, token=$token_code"); // Check if the phone number and token code match $sql = "SELECT * FROM `phone_verification_passenger` WHERE `phone_number` = '$phone_number' AND `token` = '$token_code' AND `verified` = 0 "; // error_log("sql is =$sql"); $stmt = $con->prepare($sql); $stmt->execute(); $result = $stmt->fetch(); if ($result) { // $id = $result["id"]; $sql = "UPDATE `phone_verification_passenger` SET `verified` = 1 WHERE `phone_number` = '$phone_number'"; $stmt = $con->prepare($sql); $stmt->execute(); jsonSuccess($message = "Your phone number has been verified."); } else { jsonError($message = "Your phone number could not be verified. Please try again."); } ?> ``` ## File: serviceapp/getDriversPhoneNotComplete.php ``` = (NOW() - INTERVAL 6 DAY) -- تم الإنشاء خلال آخر 3 أيام ORDER BY RAND() LIMIT 1; "; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك تشفير أرقام الهاتف والإيميل foreach ($rows as &$r) { if (isset($r['phone_number']) && $r['phone_number'] != null) { $r['phone_number'] = $encryptionHelper->decryptData($r['phone_number']); } if (isset($r['email']) && $r['email'] != null) { $r['email'] = $encryptionHelper->decryptData($r['email']); } } jsonSuccess($rows); } else { jsonError("No phone numbers found in the last 5 days"); } ?> ``` ## File: serviceapp/getCarPlateNotEdit.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as &$row) { $row['vin'] = $encryptionHelper->decryptData($row['vin']); $row['car_plate'] = $encryptionHelper->decryptData($row['car_plate']); $row['owner'] = $encryptionHelper->decryptData($row['owner']); $row['address'] = $encryptionHelper->decryptData($row['address']); $row['phone'] = $encryptionHelper->decryptData($row['phone']); } jsonSuccess($rows); } else { jsonError($message = "No Car verified yet found"); } ?> ``` ## File: serviceapp/getDriverByPhone.php ``` encryptData($phone); // تشفير الهاتف $sql = "SELECT COALESCE( ( SELECT COUNT(*) FROM `ride` WHERE `ride`.`driver_id` = d.id ), 0) AS countRide, COALESCE( ( SELECT AVG(`ratingDriver`.`rating`) FROM ratingDriver WHERE `ratingDriver`.`driver_id` = d.id ), 0) AS rating, COALESCE( ( SELECT SUM(pd.amount) FROM `payments` pd WHERE pd.driverID = d.id ), 0) AS totalPayment, COALESCE( ( SELECT SUM(dw.amount) FROM `driverWallet` dw WHERE dw.driverID = d.id ), 0) AS totalDriverWallet, COALESCE( ( SELECT COUNT(*) FROM complaint WHERE complaint.driver_id = d.id ), 0) AS countComplaint, COALESCE( ( SELECT COUNT(*) FROM driver_ride_scam scam WHERE scam.driverID = d.id ), 0) AS countScam, COALESCE( ( SELECT complaint.description FROM complaint WHERE complaint.driver_id = d.id ORDER BY complaint.date_resolved DESC LIMIT 1 ), '' ) AS complaint, COALESCE( ( SELECT COUNT(*) FROM ratingPassenger WHERE ratingPassenger.driverID = d.id ), 0) AS DRatingPassengersCount, COALESCE( ( SELECT AVG(ratingPassenger.rating) FROM ratingPassenger WHERE ratingPassenger.driverID = d.id ), 0) AS avgDRatingPassenger, cr.*, d.* FROM driver d LEFT JOIN CarRegistration cr ON cr.driverID = d.id WHERE d.phone = :phone; "; $stmt = $con->prepare($sql); $stmt->bindParam(':phone', $encryptedPhone); $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك تشفير الحقول المهمة foreach ($row as &$r) { if (isset($r['phone'])) $r['phone'] = $encryptionHelper->decryptData($r['phone']); if (isset($r['email'])) $r['email'] = $encryptionHelper->decryptData($r['email']); if (isset($r['first_name'])) $r['first_name'] = $encryptionHelper->decryptData($r['first_name']); if (isset($r['last_name'])) $r['last_name'] = $encryptionHelper->decryptData($r['last_name']); if (isset($r['gender'])) $r['gender'] = $encryptionHelper->decryptData($r['gender']); if (isset($r['birthdate'])) $r['birthdate'] = $encryptionHelper->decryptData($r['birthdate']); if (isset($r['site'])) $r['site'] = $encryptionHelper->decryptData($r['site']); if (isset($r['name_arabic'])) $r['name_arabic'] = $encryptionHelper->decryptData($r['name_arabic']); if (isset($r['national_number'])) $r['national_number'] = $encryptionHelper->decryptData($r['national_number']); if (isset($r['maritalStatus'])) $r['maritalStatus'] = $encryptionHelper->decryptData($r['maritalStatus']); if (isset($r['sosPhone'])) $r['sosPhone'] = $encryptionHelper->decryptData($r['sosPhone']); if (isset($r['car_plate'])) $r['car_plate'] = $encryptionHelper->decryptData($r['car_plate']); if (isset($r['owner'])) $r['owner'] = $encryptionHelper->decryptData($r['owner']); if (isset($r['address'])) $r['address'] = $encryptionHelper->decryptData($r['address']); if (isset($r['vin'])) $r['vin'] = $encryptionHelper->decryptData($r['vin']); unset($r['password']); } jsonSuccess($row); } else { jsonError("No wallet record found"); } ?> ``` ## File: serviceapp/driverWhoregisterFfterCall.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else { jsonError("No driver records found with notes this month."); } ?> ``` ## File: serviceapp/getdriverWithoutCar.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير للحقول الحساسة foreach ($rows as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); $row['name_arabic'] = $encryptionHelper->decryptData($row['name_arabic']); } jsonSuccess($rows); } else { jsonError("No Car verified yet found"); } ``` ## File: serviceapp/login.php ``` "failure", "message" => "Email and password are required." ]); exit(); } // SQL to check for user with provided email $sql = "SELECT * FROM `users` WHERE `email` = :email"; $stmt = $con->prepare($sql); $stmt->bindParam(':email', $email); $stmt->execute(); $user = $stmt->fetch(PDO::FETCH_ASSOC); header('Content-Type: application/json'); // Ensure the response is JSON if ($user) { // Verify the password if ($password=== $user['password']) { // Password is correct unset($user['password']); // Remove password from the response echo json_encode([ "status" => "success", "message" => "Login successful", "data" => $user ]); } else { // Password is incorrect echo json_encode([ "status" => "failure", "message" => "Incorrect password", "password"=>$password, "password1"=>$user['password'], ]); } } else { // User not found echo json_encode([ "status" => "failure", "message" => "User not found" ]); } $stmt = null; // Close the statement $con = null; // Close the connection exit(); // Ensure no further output ``` ## File: serviceapp/getComplaintAllData.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($row as &$item) { if (isset($item['passengerName'])) { $item['passengerName'] = $encryptionHelper->decryptData($item['passengerName']); } if (isset($item['driverName'])) { $item['driverName'] = $encryptionHelper->decryptData($item['driverName']); } if (isset($item['gender'])) { $item['gender'] = $encryptionHelper->decryptData($item['gender']); } if (isset($item['driverToken'])) { $item['driverToken'] = $encryptionHelper->decryptData($item['driverToken']); } if (isset($item['passengerToken'])) { $item['passengerToken'] = $encryptionHelper->decryptData($item['passengerToken']); } } jsonSuccess($row); } else { jsonError("No wallet record found"); } ?> ``` ## File: serviceapp/getDriverNotCompleteRegistration.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك تشفير أرقام الهواتف فقط للإخراج foreach ($rows as &$row) { if (!empty($row['phone'])) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); } if (!empty($row['email'])) { $row['email'] = $encryptionHelper->decryptData($row['email']); } if (isset($row['phone_number'])) { $row['phone_number'] = $encryptionHelper->decryptData($row['phone_number']); } } jsonSuccess($rows); } else { jsonError("No Phone verified yet found"); } ?> ``` ## File: serviceapp/getPackages.php ``` prepare($sql); $stmt->execute(); $passenger_data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($passenger_data) { // Print the passenger data as JSON jsonSuccess($data = $passenger_data); } else { // Print a failure message jsonError($message = "No passenger data found"); } ?> ``` ## File: serviceapp/updateDriver.php ``` $driverID]; foreach ($driverFieldsAllowed as $field) { if (isset($_POST[$field]) && $_POST[$field] !== "") { $value = filterRequest($field); if (in_array($field, $encryptedDriverFields)) { $value = $encryptionHelper->encryptData($value); } $driverSet[] = "`$field` = :$field"; $driverParams[":$field"] = $value; } } // Execute Driver Update $driverUpdated = false; if (!empty($driverSet)) { $driverSql = "UPDATE `driver` SET " . implode(", ", $driverSet) . " WHERE `id` = :id"; $stmt = $con->prepare($driverSql); $stmt->execute($driverParams); $driverUpdated = $stmt->rowCount() > 0; } /* --------------------------------------------------------- CAR REGISTRATION TABLE --------------------------------------------------------- */ $carFieldsAllowed = [ "id", "vin", "car_plate", "make", "model", "year", "expiration_date", "color", "owner", "color_hex", "fuel", "isDefault", "created_at", "status" ]; $carSet = []; $carParams = [":driverID" => $driverID]; foreach ($carFieldsAllowed as $field) { if ($field === "id") continue; // skip primary key in SET if (isset($_POST[$field]) && $_POST[$field] !== "") { $value = filterRequest($field); $carSet[] = "`$field` = :$field"; $carParams[":$field"] = $value; } } // Execute Car Update $carUpdated = false; if (!empty($carSet)) { $carSql = "UPDATE `CarRegistration` SET " . implode(", ", $carSet) . " WHERE `driverID` = :driverID"; $stmtCar = $con->prepare($carSql); $stmtCar->execute($carParams); $carUpdated = $stmtCar->rowCount() > 0; } /* --------------------------------------------------------- RESPONSE --------------------------------------------------------- */ if ($driverUpdated || $carUpdated) { jsonSuccess(null, "Driver & Car updated successfully"); } else { jsonError("No changes were applied"); } ?> ``` ## File: serviceapp/getDriverByNational.php ``` encryptData($national_number); $sql = "SELECT COALESCE( ( SELECT COUNT(*) FROM `ride` WHERE `ride`.`driver_id` = d.id ), 0) AS countRide, COALESCE( ( SELECT AVG(`ratingDriver`.`rating`) FROM ratingDriver WHERE `ratingDriver`.`driver_id` = d.id ), 0) AS rating, COALESCE( ( SELECT SUM(pd.amount) FROM `payments` pd WHERE pd.driverID = d.id ), 0) AS totalPayment, COALESCE( ( SELECT SUM(dw.amount) FROM `driverWallet` dw WHERE dw.driverID = d.id ), 0) AS totalDriverWallet, COALESCE( ( SELECT COUNT(*) FROM complaint WHERE complaint.driver_id = d.id ), 0) AS countComplaint, COALESCE( ( SELECT COUNT(*) FROM driver_ride_scam scam WHERE scam.driverID = d.id ), 0) AS countScam, COALESCE( ( SELECT complaint.description FROM complaint WHERE complaint.driver_id = d.id ORDER BY complaint.date_resolved DESC LIMIT 1 ), '' ) AS complaint, COALESCE( ( SELECT COUNT(*) FROM ratingPassenger WHERE ratingPassenger.driverID = d.id ), 0) AS DRatingPassengersCount, COALESCE( ( SELECT AVG(ratingPassenger.rating) FROM ratingPassenger WHERE ratingPassenger.driverID = d.id ), 0) AS avgDRatingPassenger, cr.*, d.* FROM driver d LEFT JOIN CarRegistration cr ON cr.driverID = d.id WHERE d.national_number = :national_number; "; // 3. تم تعديل الشرط أعلاه للبحث بالرقم الوطني $stmt = $con->prepare($sql); // 4. ربط الباراميتر الجديد $stmt->bindParam(':national_number', $encryptedNationalNumber); $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك تشفير الحقول المهمة foreach ($row as &$r) { if (isset($r['phone'])) $r['phone'] = $encryptionHelper->decryptData($r['phone']); if (isset($r['email'])) $r['email'] = $encryptionHelper->decryptData($r['email']); if (isset($r['first_name'])) $r['first_name'] = $encryptionHelper->decryptData($r['first_name']); if (isset($r['last_name'])) $r['last_name'] = $encryptionHelper->decryptData($r['last_name']); if (isset($r['gender'])) $r['gender'] = $encryptionHelper->decryptData($r['gender']); if (isset($r['birthdate'])) $r['birthdate'] = $encryptionHelper->decryptData($r['birthdate']); if (isset($r['site'])) $r['site'] = $encryptionHelper->decryptData($r['site']); if (isset($r['name_arabic'])) $r['name_arabic'] = $encryptionHelper->decryptData($r['name_arabic']); if (isset($r['national_number'])) $r['national_number'] = $encryptionHelper->decryptData($r['national_number']); if (isset($r['maritalStatus'])) $r['maritalStatus'] = $encryptionHelper->decryptData($r['maritalStatus']); if (isset($r['sosPhone'])) $r['sosPhone'] = $encryptionHelper->decryptData($r['sosPhone']); if (isset($r['car_plate'])) $r['car_plate'] = $encryptionHelper->decryptData($r['car_plate']); if (isset($r['owner'])) $r['owner'] = $encryptionHelper->decryptData($r['owner']); if (isset($r['address'])) $r['address'] = $encryptionHelper->decryptData($r['address']); if (isset($r['vin'])) $r['vin'] = $encryptionHelper->decryptData($r['vin']); unset($r['password']); } jsonSuccess($row); } else { // يمكنك تعديل الرسالة لتكون "No driver found" بدلاً من wallet record jsonError("No record found for this national number"); } ?> ``` ## File: serviceapp/getEditorStatsCalls.php ``` prepare($sql); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($data) { echo json_encode(array("status" => "success", "message" => $data)); } else { echo json_encode(array("status" => "success", "message" => [])); } } catch (PDOException $e) { echo json_encode(array("status" => "failure", "message" => $e->getMessage())); } ?> ``` ## File: serviceapp/editCarPlate.php ``` encryptData(filterRequest("carPlate")); $color = filterRequest("color"); $color_hex = filterRequest("color_hex"); $make = filterRequest("make"); $model = filterRequest("model"); $expiration_date = filterRequest("expiration_date"); $owner = $encryptionHelper->encryptData(filterRequest("owner")); $year = filterRequest("year"); $employee = filterRequest("employee"); // تحديث CarRegistration $sqlUpdate = " UPDATE `CarRegistration` SET `car_plate` = :carPlate, `color` = :color, `color_hex` = :color_hex, `make` = :make, `model` = :model, `year` = :year, `expiration_date` = :expiration_date, `owner` = :owner WHERE `driverID` = :driverId"; $stmtUpdate = $con->prepare($sqlUpdate); $stmtUpdate->execute([ ':carPlate' => $carPlate, ':color' => $color, ':color_hex' => $color_hex, ':make' => $make, ':model' => $model, ':year' => $year, ':expiration_date' => $expiration_date, ':owner' => $owner, ':driverId' => $driverId ]); if ($stmtUpdate->rowCount() > 0) { // تسجيل التعديل $sqlInsert = "INSERT INTO `carPlateEdit` (`driverId`, `carPlate`, `color`, `make`, `model`, `expiration_date`, `owner`, `year`, `employee`, `isEdit`) VALUES (:driverId, :carPlate, :color, :make, :model, :expiration_date, :owner, :year, :employee, 1)"; $stmtInsert = $con->prepare($sqlInsert); $stmtInsert->execute([ ':driverId' => $driverId, ':carPlate' => $carPlate, ':color' => $color, ':make' => $make, ':model' => $model, ':expiration_date' => $expiration_date, ':owner' => $owner, ':year' => $year, ':employee' => $employee ]); jsonSuccess(null, "Car data updated and edit logged successfully."); } else { jsonError("No changes were made to the car data."); } ``` ## File: serviceapp/getPassengersByPhone.php ``` encryptData($phone); $sql = "SELECT p.*, COALESCE(r.id, 0) AS ride_id, COALESCE(r.start_location, '') AS start_location, COALESCE(r.end_location, '') AS end_location, COALESCE(r.date, '1970-01-01') AS ride_date, COALESCE(r.time, '00:00:00') AS ride_time, COALESCE(r.endtime, '00:00:00') AS ride_endtime, COALESCE(r.price, 0) AS price, COALESCE(r.passenger_id, 0) AS ride_passenger_id, COALESCE(r.driver_id, 0) AS driver_id, COALESCE(r.status, '') AS ride_status, COALESCE(r.paymentMethod, '') AS ride_payment_method, COALESCE(r.carType, '') AS car_type, COALESCE(r.created_at, '1970-01-01 00:00:00') AS ride_created_at, COALESCE(r.updated_at, '1970-01-01 00:00:00') AS ride_updated_at, COALESCE(r.DriverIsGoingToPassenger, 0) AS driver_is_going_to_passenger, COALESCE(r.rideTimeStart, '1970-01-01 00:00:00') AS ride_time_start, COALESCE(r.rideTimeFinish, '1970-01-01 00:00:00') AS ride_time_finish, COALESCE(r.price_for_driver, 0) AS price_for_driver, COALESCE(r.price_for_passenger, 0) AS price_for_passenger, COALESCE(r.distance, 0) AS distance, COALESCE(pw.balance, 0) AS passenger_wallet_balance, COALESCE(pay.amount, 0) AS passenger_payment_amount, COALESCE(pay.payment_method, '') AS passenger_payment_method, COALESCE(dw.amount, 0) AS driver_payment_amount, COALESCE(dw.paymentMethod, '') AS driver_payment_method FROM passengers p LEFT JOIN ride r ON p.id = r.passenger_id LEFT JOIN passengerWallet pw ON p.id = pw.passenger_id LEFT JOIN payments pay ON r.id = pay.rideId LEFT JOIN driverWallet dw ON r.driver_id = dw.driverID AND pay.id = dw.paymentID WHERE p.phone = :phone AND r.id = ( SELECT id FROM ride WHERE passenger_id = p.id ORDER BY date DESC, time DESC LIMIT 1 )"; $stmt = $con->prepare($sql); $stmt->bindParam(':phone', $phoneEncrypted); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير للحقول الحساسة foreach ($rows as &$row) { if (isset($row['phone'])) $row['phone'] = $encryptionHelper->decryptData($row['phone']); if (isset($row['email'])) $row['email'] = $encryptionHelper->decryptData($row['email']); if (isset($row['gender'])) $row['gender'] = $encryptionHelper->decryptData($row['gender']); if (isset($row['birthdate'])) $row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']); if (isset($row['site'])) $row['site'] = $encryptionHelper->decryptData($row['site']); if (isset($row['first_name'])) $row['first_name'] = $encryptionHelper->decryptData($row['first_name']); if (isset($row['last_name'])) $row['last_name'] = $encryptionHelper->decryptData($row['last_name']); if (isset($row['employmentType']))$row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']); if (isset($row['maritalStatus'])) $row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']); unset($r['password']); } jsonSuccess($rows); } else { jsonError("No wallet record found"); } ?> ``` ## File: serviceapp/addNotesPassenger.php ``` encryptData($phone); // SQL query to insert into notesForPassengerService $sql = "INSERT INTO `notesForPassengerService` (`phone`, `note`, `editor`) VALUES (:phone, :note, :editor)"; // Prepare the statement $stmt = $con->prepare($sql); $stmt->bindParam(':phone', $encryptedPhone); $stmt->bindParam(':note', $note); $stmt->bindParam(':editor', $editor); // Execute and respond $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Note inserted successfully"); } else { jsonError("Failed to insert note"); } ?> ``` ## File: serviceapp/updateDriverToActive.php ``` beginTransaction(); try { // --- 1. معالجة وتشفير البيانات --- $nameArabic = $firstName . ' ' . $lastName; $address = $site; // تشفير الحقول الحساسة $encryptedFirstName = $encryptionHelper->encryptData($firstName); $encryptedLastName = $encryptionHelper->encryptData($lastName); $encryptedSite = $encryptionHelper->encryptData($site); $encryptedAddress = $encryptionHelper->encryptData($address); $encryptedNameArabic = $encryptionHelper->encryptData($nameArabic); $encryptedNationalNumber = $encryptionHelper->encryptData($nationalNumber); $encryptedOwner = $encryptionHelper->encryptData($owner); $encryptedCarPlate = $encryptionHelper->encryptData($carPlate); $encryptedBirthdate = $encryptionHelper->encryptData($birthdate); $encryptedGender = $encryptionHelper->encryptData($gender); // --- 2. تحديث جدول السائق --- $sqlDriver = "UPDATE `driver` SET `first_name` = :first_name, `last_name` = :last_name, `site` = :site, `address` = :address, `national_number` = :national_number, `license_categories` = :license_categories, `expiry_date` = :expiry_date, `issue_date` = :issue_date, `gender` = :gender, `birthdate` = :birthdate, `name_arabic` = :name_arabic, `maritalStatus` = :maritalStatus, `status` = 'actives' WHERE `id` = :driverId"; $stmtDriver = $con->prepare($sqlDriver); $stmtDriver->execute([ ':first_name' => $encryptedFirstName, ':last_name' => $encryptedLastName, ':site' => $encryptedSite, ':address' => $encryptedAddress, ':national_number' => $encryptedNationalNumber, ':license_categories' => $licenseCategories, ':expiry_date' => $expiryDate, ':issue_date' => $licenseIssueDate, ':gender' => $encryptedGender, ':birthdate' => $encryptedBirthdate, ':name_arabic' => $encryptedNameArabic, ':driverId' => $driverId, ':maritalStatus' =>$maritalStatus ]); // --- 3. تحديث جدول السيارة --- $sqlCar = "UPDATE `CarRegistration` SET `owner` = :owner, `color` = :color, `color_hex` = :color_hex, `model` = :model, `car_plate` = :car_plate, `make` = :make, `fuel` = :fuel, `year` = :year, `expiration_date` = :expiration_date WHERE `driverID` = :driverId"; $stmtCar = $con->prepare($sqlCar); $stmtCar->execute([ ':owner' => $encryptedOwner, ':color' => $color, ':color_hex' => $colorHex, ':model' => $model, ':car_plate' => $encryptedCarPlate, ':make' => $make, ':fuel' => $fuel, ':year' => $year, ':expiration_date' => $carExpirationDate, ':driverId' => $driverId ]); // --- 4. تأكيد المعاملة --- $con->commit(); jsonSuccess(["message" => "Driver and car data updated successfully."]); // --- 5. إرسال رسالة واتساب مبسطة وآمنة (باختيار رقم عشوائي) --- // 5.1. تعريف الأرقام $supportPhones = ['0952475740', '0952475742']; // يمكنك إضافة المزيد من الأرقام هنا // 5.2. اختيار رقم عشوائي من القائمة $randomIndex = array_rand($supportPhones); // يختار "مفتاح" عشوائي (index) $phoneToUse = $supportPhones[$randomIndex]; // يحصل على الرقم من المفتاح // --- !!! التعديل: إضافة رقم عشوائي --- // هذا يضيف رقم عشوائي (4-6 خانات) لجعل الرسالة فريدة $randomNumber = rand(1000, 999999); // 5.5. إعداد نص الرسالة بالرقم المتغير $messageBody = "أهلاً وسهلاً كابتن $firstName 👋\n" . "تم تفعيل حسابك على تطبيق *سيرو*.\n" . "يمكنك الآن تسجيل الدخول والبدء بالعمل مباشرة.\n" . "للمساعدة تواصل معنا على الرقم: $phoneToUse\n" // <-- تم استخدام المتغير العشوائي هنا . "نتمنى لك عمل موفق 🚖\n\n" . "معرف الرسالة: $randomNumber"; // <-- إضافة الرقم العشوائي // 5.6. إرسال الرسالة sendWhatsAppFromServer($phone, $messageBody); } catch (Exception $e) { // --- 6. التراجع في حال الخطأ --- $con->rollBack(); jsonError("An error occurred: " . $e->getMessage()); } ?> ``` ## File: serviceapp/getNewDriverRegister.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the records $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير للحقول الحساسة foreach ($rows as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); $row['email'] = $encryptionHelper->decryptData($row['email']); $row['gender'] = $encryptionHelper->decryptData($row['gender']); $row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']); $row['national_number'] = $encryptionHelper->decryptData($row['national_number']); $row['site'] = $encryptionHelper->decryptData($row['site']); $row['first_name'] = $encryptionHelper->decryptData($row['first_name']); $row['last_name'] = $encryptionHelper->decryptData($row['last_name']); // $row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']); // $row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']); } jsonSuccess($rows); } else { // Print a failure message jsonError($message = "No Phone verified yet found"); } ?> ``` ## File: serviceapp/getPassengersNotCompleteRegistration.php ``` = DATE_SUB(CURDATE(), INTERVAL 4 DAY) ORDER BY phone_verification_passenger.created_at DESC LIMIT 25; "; $stmt = $con->prepare($sql); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير إذا كان مطلوباً (مثلاً إذا phone_number مشفّر) foreach ($rows as &$row) { if (isset($row['phone_number'])) { $row['phone_number'] = $encryptionHelper->decryptData($row['phone_number']); } if (isset($row['note'])) { $row['note'] = $encryptionHelper->decryptData($row['note']); // إذا كانت مضافة مشفّرة } } if ($rows) { jsonSuccess($rows); } else { jsonError("No phone verified passengers found"); } ?> ``` ## File: serviceapp/updatePackages.php ``` prepare($sql); $stmt->execute(); error_log("Updating package: ID = $sql, Version = $version"); // Debugging: Check if the query affected any rows if ($stmt->rowCount() > 0) { // If rows were affected, print success echo json_encode(['status' => 'success', 'message' => "Package version updated successfully for ID $id"]); } else { // If no rows were affected, print failure and debug the query echo json_encode(['status' => 'failure', 'message' => "Failed to update package version. No rows affected. ID: $id, Version: $version"]); } ?> ``` ## File: serviceapp/addCartoDriver.php ``` encryptData(filterRequest("vin")); $carPlate = $encryptionHelper->encryptData(filterRequest("car_plate")); $make = filterRequest("make"); $model = filterRequest("model"); $year = filterRequest("year"); $expirationDate = filterRequest("expiration_date"); $color = filterRequest("color"); $owner = $encryptionHelper->encryptData(filterRequest("owner")); $colorHex = filterRequest("color_hex"); $address = $encryptionHelper->encryptData(filterRequest("address")); $displacement = filterRequest("displacement"); $fuel = filterRequest("fuel"); $registrationDate = filterRequest("registration_date"); // تحقق من الحقول المطلوبة if ( is_null($driverID) || is_null($vin) || is_null($carPlate) || is_null($make) || is_null($model) || is_null($year) || is_null($expirationDate) || is_null($color) || is_null($owner) || is_null($colorHex) || is_null($address) || is_null($displacement) || is_null($fuel) || is_null($registrationDate) ) { jsonError("One or more required parameters are missing."); exit(); } $con->beginTransaction(); try { $checkSql = "SELECT * FROM `CarRegistration` WHERE `driverID` = :driverID"; $checkStmt = $con->prepare($checkSql); $checkStmt->bindParam(':driverID', $driverID); $checkStmt->execute(); if ($checkStmt->rowCount() > 0) { jsonError("Car has already been registered for this driver."); exit(); } // إدخال السيارة $sqlInsert = "INSERT INTO `CarRegistration` ( `driverID`, `vin`, `car_plate`, `make`, `model`, `year`, `expiration_date`, `color`, `owner`, `color_hex`, `address`, `displacement`, `fuel`, `registration_date` ) VALUES ( :driverID, :vin, :carPlate, :make, :model, :year, :expirationDate, :color, :owner, :colorHex, :address, :displacement, :fuel, :registrationDate )"; $stmtInsert = $con->prepare($sqlInsert); $stmtInsert->bindParam(':driverID', $driverID); $stmtInsert->bindParam(':vin', $vin); $stmtInsert->bindParam(':carPlate', $carPlate); $stmtInsert->bindParam(':make', $make); $stmtInsert->bindParam(':model', $model); $stmtInsert->bindParam(':year', $year); $stmtInsert->bindParam(':expirationDate', $expirationDate); $stmtInsert->bindParam(':color', $color); $stmtInsert->bindParam(':owner', $owner); $stmtInsert->bindParam(':colorHex', $colorHex); $stmtInsert->bindParam(':address', $address); $stmtInsert->bindParam(':displacement', $displacement); $stmtInsert->bindParam(':fuel', $fuel); $stmtInsert->bindParam(':registrationDate', $registrationDate); $stmtInsert->execute(); if ($stmtInsert->rowCount() > 0) { // سجل في carPlateEdit $sqlLog = "INSERT INTO `carPlateEdit` (`driverId`, `carPlate`, `color`, `make`, `model`, `expiration_date`, `owner`, `year`, `isEdit`) VALUES (:driverID, :carPlate, :color, :make, :model, :expirationDate, :owner, :year, 0)"; $stmtLog = $con->prepare($sqlLog); $stmtLog->bindParam(':driverID', $driverID); $stmtLog->bindParam(':carPlate', $carPlate); $stmtLog->bindParam(':color', $color); $stmtLog->bindParam(':make', $make); $stmtLog->bindParam(':model', $model); $stmtLog->bindParam(':expirationDate', $expirationDate); $stmtLog->bindParam(':owner', $owner); $stmtLog->bindParam(':year', $year); $stmtLog->execute(); $con->commit(); jsonSuccess(null, "Car registration data saved and logged successfully"); } else { $con->rollBack(); jsonError("Failed to save car registration data"); } } catch (Exception $e) { $con->rollBack(); jsonError("An error occurred: " . $e->getMessage()); } ?> ``` ## File: serviceapp/addWelcomeDriverNote.php ``` prepare($sql); // Bind parameters $stmt->bindParam(':driverId', $driverId); $stmt->bindParam(':notes', $notes); // Execute the statement $success = $stmt->execute(); if ($success) { jsonSuccess(null, "Record inserted/updated successfully"); } else { jsonError("Failed to insert or update record"); } ?> ``` ## File: serviceapp/drivers_list.txt ``` Phone: 963995473295 | Note: No Note Phone: 963932997741 | Note: No Note Phone: 963946792550 | Note: No Note Phone: | Note: لا يوجد رقم Phone: 963930124895 | Note: No Note Phone: 963932845375 | Note: No Note Phone: 9630937563437 | Note: No Note Phone: 963937563437 | Note: No Note Phone: 963933014381 | Note: No Note Phone: 963940740211 | Note: No Note Phone: 963997731147 | Note: No Note Phone: 9630982494498 | Note: No Note Phone: 963982494498 | Note: No Note Phone: 963936780435 | Note: No Note Phone: 963932894042 | Note: No Note Phone: 963955609157 | Note: No Note Phone: 963943433943 | Note: No Note Phone: 963934020587 | Note: No Note Phone: 963991486923 | Note: No Note Phone: 963930246282 | Note: No Note Phone: 963936388893 | Note: No Note Phone: 963965444917 | Note: No Note Phone: 963968622928 | Note: No Note Phone: 963941588818 | Note: No Note Phone: 9630941588818 | Note: No Note Phone: 963998557963 | Note: No Note Phone: 963995737121 | Note: ماعندو واتس وخطو مسكر Phone: 963996673522 | Note: No Note Phone: 963992159193 | Note: No Note Phone: 963933231038 | Note: No Note Phone: 963990320212 | Note: تم Phone: 963991918177 | Note: No Note Phone: 963962293692 | Note: No Note Phone: 963980043065 | Note: No Note Phone: 963933665775 | Note: No Note Phone: 963997678811 | Note: No Note Phone: 963935541277 | Note: No Note Phone: 963937173449 | Note: تم Phone: 963998235145 | Note: No Note Phone: 963991514602 | Note: No Note Phone: 963993725589 | Note: No Note Phone: 963939761870 | Note: No Note Phone: 963956825657 | Note: No Note Phone: 963933642491 | Note: No Note Phone: 963956906783 | Note: No Note Phone: 9630956906783 | Note: No Note Phone: 9630936984029 | Note: No Note Phone: 963941418151 | Note: No Note Phone: 9630941418151 | Note: No Note Phone: 963981237272 | Note: No Note Phone: 963933897890 | Note: No Note Phone: 963944344937 | Note: No Note Phone: 963993828902 | Note: No Note Phone: 963933659200 | Note: No Note Phone: 963955414963 | Note: No Note Phone: 963942024560 | Note: No Note Phone: 9639494022840 | Note: No Note Phone: 9639639362485 | Note: No Note Phone: 963965833448 | Note: مشغول Phone: 9630930291349 | Note: بدو يفعل Phone: 963945267161 | Note: تم Phone: 9630934627741 | Note: No Note Phone: 963934627741 | Note: No Note Phone: 963935777840 | Note: No Note Phone: 963994436621 | Note: No Note Phone: 963940031237 | Note: No Note Phone: 963957833531 | Note: No Note Phone: 963943949925 | Note: No Note Phone: 963953263161 | Note: ما برن Phone: 963980486635 | Note: No Note Phone: 963٩٩٢٩٩٩٠٨٣ | Note: No Note Phone: 963950505715 | Note: No Note Phone: 963934443912 | Note: كان بدو يشتري سيارة وفقست بس يكفي رح يسجل Phone: 963945452222 | Note: رح يكفي تسجيل Phone: 963948899644 | Note: No Note Phone: 963937525133 | Note: رح يكفي تسجيل Phone: 963934441423 | Note: No Note Phone: 963968044972 | Note: تم التواصل Phone: 963984137014 | Note: مابدو Phone: 963796377987 | Note: No Note Phone: 963988455623 | Note: No Note Phone: 9630939386057 | Note: No Note Phone: 963939386057 | Note: No Note Phone: 963966880940 | Note: تم Phone: 963932928765 | Note: تم Phone: 963993641405 | Note: تم Phone: 963933027735 | Note: No Note Phone: 963933433725 | Note: تم Phone: 963988870417 | Note: تم Phone: 963951670237 | Note: تم Phone: 963930795196 | Note: تم Phone: 963991960766 | Note: تم Phone: 963935998441 | Note: تم Phone: 963947938918 | Note: تم Phone: 963992435599 | Note: تم Phone: 963954364865 | Note: تم Phone: 963995438666 | Note: تم Phone: 963991420279 | Note: تم Phone: 963933969836 | Note: تم Phone: 963095874505 | Note: الرقم خطأ Phone: 963933586167 | Note: تم Phone: 963997791974 | Note: تم Phone: 963938092584 | Note: تم Phone: 963936412209 | Note: تم Phone: 963993998201 | Note: تم Phone: 963954845028 | Note: No Note Phone: 963985472276 | Note: No Note Phone: 963983727779 | Note: تم Phone: 963935005982 | Note: تم Phone: 963996095507 | Note: No Note Phone: 963993952009 | Note: تم Phone: 9630993952009 | Note: No Note Phone: 963940056304 | Note: تم Phone: 963995797246 | Note: تم Phone: 963993492062 | Note: No Note Phone: 963988493310 | Note: تم Phone: 971567312720 | Note: No Note Phone: 963991748590 | Note: تم Phone: 963996807389 | Note: تم Phone: 963933624099 | Note: تم Phone: 963981997355 | Note: تم Phone: 9630983758855 | Note: تم Phone: 963986198636 | Note: No Note Phone: 963932392061 | Note: No Note Phone: 963944087759 | Note: No Note Phone: 9630944087759 | Note: No Note Phone: 963996489269 | Note: No Note Phone: 963956465908 | Note: No Note Phone: 963937829076 | Note: No Note Phone: 963952398851 | Note: No Note Phone: 963947785627 | Note: No Note Phone: 963944725825 | Note: No Note Phone: 963985041549 | Note: No Note Phone: 963992485425 | Note: No Note Phone: 963990462939 | Note: No Note Phone: 963997451873 | Note: No Note Phone: 9630992952235 | Note: No Note Phone: 963991543059 | Note: No Note Phone: 963938800414 | Note: No Note Phone: 963955915110 | Note: No Note Phone: 963933436896 | Note: No Note Phone: 963962203899 | Note: No Note Phone: 963980561370 | Note: No Note Phone: 963938449446 | Note: No Note Phone: 963933989564 | Note: No Note Phone: 963952726606 | Note: No Note Phone: 963954152143 | Note: No Note Phone: 963095272660 | Note: No Note Phone: 963985131776 | Note: No Note Phone: 963093184436 | Note: No Note Phone: 963933751093 | Note: No Note Phone: 963937475542 | Note: No Note Phone: 963944619801 | Note: No Note Phone: 963994776559 | Note: No Note Phone: 963931802363 | Note: No Note Phone: 963986312807 | Note: No Note Phone: 963933502898 | Note: No Note Phone: 963992667679 | Note: No Note Phone: 963988514496 | Note: No Note Phone: 963954251613 | Note: No Note Phone: 963955630089 | Note: No Note Phone: 963096491319 | Note: رقم غلط Phone: 963999352010 | Note: تم Phone: 963997823542 | Note: No Note Phone: 963935561540 | Note: No Note Phone: 963991907984 | Note: تم التواصل Phone: 963963992952 | Note: غير موضوع بالخدمة Phone: 919154792561 | Note: غلط Phone: 963095371707 | Note: غير صحيح Phone: 963964701914 | Note: تم Phone: 963991175918 | Note: No Note Phone: 963962215103 | Note: تم Phone: 963099295223 | Note: خطأ Phone: 963990368364 | Note: تم التواصل Phone: 963931447359 | Note: No Note Phone: 963994875810 | Note: تم التواصل Phone: 963998047263 | Note: تم التواصل Phone: 963988892598 | Note: تم التواصل Phone: 963996136343 | Note: تم التواصل Phone: 963934245841 | Note: تم التواصل Phone: 963933944881 | Note: تم التواصل Phone: 963993484762 | Note: تم التواصل Phone: 963997386925 | Note: تم التواصل Phone: 963955300562 | Note: تم التواصل Phone: 963099123427 | Note: الرقم خطأ Phone: 963998752835 | Note: تم التواصل Phone: 963986164501 | Note: تم التواصل Phone: 963994221981 | Note: تم Phone: 963985111107 | Note: تم Phone: 963965665584 | Note: تم Phone: 963093309389 | Note: الرقم خطأ Phone: 963933009411 | Note: تم التواصل Phone: 963997226674 | Note: تم التواصل Phone: 963985322261 | Note: تم التواصل Phone: 963944585751 | Note: تم Phone: 963936520446 | Note: تم Phone: 963942272548 | Note: تم Phone: 963932784840 | Note: تم Phone: 963966337233 | Note: تم Phone: 963982498933 | Note: تم Phone: 963934792333 | Note: تم Phone: 963992323421 | Note: No Note Phone: 963937512107 | Note: تم Phone: 963095247574 | Note: No Note Phone: 963994800068 | Note: تم Phone: 963955809725 | Note: No Note Phone: 963933823485 | Note: No Note Phone: 963949204755 | Note: تم Phone: 963983691808 | Note: No Note Phone: 963983626721 | Note: No Note Phone: 963981610336 | Note: No Note Phone: 963937927500 | Note: No Note Phone: 963959853846 | Note: No Note Phone: 963997073925 | Note: تم Phone: 963956732767 | Note: غلط Phone: 963947021104 | Note: تم Phone: 963940052998 | Note: تم Phone: 963944662446 | Note: تم Phone: 963982678522 | Note: تم Phone: 963962135909 | Note: تم Phone: 963936610855 | Note: تم التواصل Phone: 963994299736 | Note: تم التواصل Phone: 963994202784 | Note: تم التواصل Phone: 963938506392 | Note: تم التواصل Phone: 963996355773 | Note: تم التواصل Phone: 963993211641 | Note: تم التواصل Phone: 963958885#01 | Note: خطأ Phone: 963993214588 | Note: تم التواصل Phone: 963930690439 | Note: تم التواصل Phone: 963981320471 | Note: No Note Phone: 963958749567 | Note: No Note Phone: 963955399707 | Note: السيارة بالتصليح Phone: 963981661357 | Note: تم Phone: 963935151385 | Note: تم Phone: 963933524019 | Note: تم Phone: 963969079332 | Note: تم Phone: 963982380563 | Note: تم Phone: 963998817414 | Note: تم Phone: 963962864640 | Note: تم Phone: 963954932302 | Note: تم Phone: 963951628380 | Note: No Note Phone: 963956742311 | Note: تم Phone: 963988605516 | Note: No Note Phone: 963933122432 | Note: No Note Phone: 963943562177 | Note: No Note Phone: 963936700433 | Note: No Note Phone: 963991539595 | Note: No Note Phone: 963997634135 | Note: No Note Phone: 963954512319 | Note: No Note Phone: 963991392595 | Note: No Note Phone: 963930053897 | Note: No Note Phone: 963941494393 | Note: No Note Phone: 963938963278 | Note: No Note Phone: 963996725663 | Note: No Note Phone: 963932998203 | Note: No Note Phone: 963984743097 | Note: No Note Phone: 963+20952653 | Note: No Note Phone: 963933263408 | Note: No Note Phone: 963992603003 | Note: No Note Phone: 963999186608 | Note: No Note Phone: 963093319092 | Note: No Note Phone: 963992200572 | Note: No Note Phone: 963935860379 | Note: تم التواصل Phone: 963932612511 | Note: No Note Phone: 963955665828 | Note: No Note Phone: 963958748659 | Note: No Note Phone: 963948956757 | Note: No Note Phone: 963991527216 | Note: No Note Phone: 963967434852 | Note: No Note Phone: 963933473946 | Note: No Note Phone: 963959281303 | Note: No Note Phone: 963937506427 | Note: No Note Phone: 963945017743 | Note: No Note Phone: 963941973355 | Note: No Note Phone: 963969369322 | Note: No Note Phone: 963935221144 | Note: No Note Phone: 963991933762 | Note: No Note Phone: 963991331539 | Note: No Note Phone: 963995940170 | Note: No Note Phone: 963996450146 | Note: No Note Phone: 963942283959 | Note: No Note Phone: 963936825881 | Note: No Note Phone: 963994058290 | Note: تم التواصل Phone: 963980387211 | Note: No Note Phone: 963960003815 | Note: No Note Phone: 963938705215 | Note: No Note Phone: 963930097924 | Note: No Note Phone: 963982872652 | Note: تم التواصل Phone: 963985327571 | Note: No Note Phone: 963958786360 | Note: No Note Phone: 963968840086 | Note: No Note Phone: 963937536957 | Note: No Note Phone: 963953925409 | Note: No Note Phone: 963947157325 | Note: No Note Phone: 963981489190 | Note: No Note Phone: 963937583931 | Note: No Note Phone: 963949631384 | Note: No Note Phone: 963953344805 | Note: No Note Phone: 963930104547 | Note: No Note Phone: 963952300665 | Note: No Note Phone: 963095230066 | Note: No Note Phone: 963988510023 | Note: No Note Phone: 963992274229 | Note: No Note Phone: 963991506951 | Note: تم التواصل Phone: 963954894895 | Note: تم التواصل Phone: 963955585012 | Note: خارج الخدمة Phone: 963996307122 | Note: تم التواصل Phone: 963991610683 | Note: تم التواصل Phone: 963991355714 | Note: تم التواصل Phone: 963937557764 | Note: تم التواصل Phone: 963988514321 | Note: تم التواصل Phone: 963944077035 | Note: تم التواصل Phone: 963938129427 | Note: تم التواصل Phone: 963990444099 | Note: تم التواصل Phone: 963956786668 | Note: تم التواصل Phone: 963940728564 | Note: تم التواصل Phone: 963954402659 | Note: خارج الخدمة وتس واتصال Phone: 963936765364 | Note: تم التواصل Phone: 963933078901 | Note: تم التواصل Phone: 963934417178 | Note: تم التواصل Phone: 963930447695 | Note: تم التواصل Phone: 963094051564 | Note: الرقم خطأ Phone: 963992417040 | Note: تم التواصل Phone: 963958922780 | Note: تم الاتصال سكودا Phone: 963951379303 | Note: تم التواصل Phone: 963953858808 | Note: تم التواصل Phone: 963964646415 | Note: تم التواصل Phone: 963960098818 | Note: تم التواصل Phone: 963933899771 | Note: تم التواصل Phone: 963096949698 | Note: الرقم خطأ Phone: 963982861634 | Note: No Note Phone: 963938252876 | Note: No Note Phone: 963986561347 | Note: No Note Phone: 963933700937 | Note: No Note Phone: 963960078368 | Note: No Note Phone: 963933737355 | Note: No Note Phone: 963983755054 | Note: hvta Phone: 963940907547 | Note: No Note Phone: 963949757956 | Note: No Note Phone: 963938938514 | Note: No Note Phone: 963980457705 | Note: No Note Phone: 963944404002 | Note: No Note Phone: 963965410313 | Note: No Note Phone: 963982325766 | Note: No Note Phone: 963981289181 | Note: No Note Phone: 963993462192 | Note: No Note Phone: 963968504915 | Note: No Note Phone: 963936628380 | Note: No Note Phone: 963951366246 | Note: No Note Phone: 963998727408 | Note: No Note Phone: 963953877512 | Note: No Note Phone: 963940478435 | Note: No Note Phone: 963984625505 | Note: No Note Phone: 963954659494 | Note: No Note Phone: 963947653804 | Note: No Note Phone: 963959218092 | Note: No Note Phone: 963994511053 | Note: No Note Phone: 963938341514 | Note: No Note Phone: 963982672582 | Note: No Note Phone: 963992495126 | Note: No Note Phone: 963993163487 | Note: No Note Phone: 963966516151 | Note: No Note Phone: 963958472195 | Note: No Note Phone: 963954611914 | Note: No Note Phone: 963940865211 | Note: No Note Phone: 963955875120 | Note: No Note Phone: 963985347924 | Note: No Note Phone: 963951450015 | Note: No Note Phone: 963991449908 | Note: No Note Phone: 963939715983 | Note: No Note Phone: 963932166786 | Note: No Note Phone: 963932334792 | Note: No Note Phone: 963998615843 | Note: No Note Phone: 963995232226 | Note: No Note Phone: 963983772298 | Note: No Note Phone: 963988736467 | Note: No Note Phone: 963959109269 | Note: No Note Phone: 963934770200 | Note: No Note Phone: 963995149210 | Note: No Note Phone: 963985665216 | Note: No Note Phone: 963962423870 | Note: No Note Phone: 963939894588 | Note: No Note Phone: 963930018143 | Note: No Note Phone: 963944940930 | Note: No Note Phone: 963930354266 | Note: No Note Phone: 963952380026 | Note: No Note Phone: 963932838183 | Note: No Note Phone: 963988131966 | Note: No Note Phone: 963993300063 | Note: No Note Phone: 963949754561 | Note: No Note Phone: 963935927218 | Note: No Note Phone: 963935595928 | Note: No Note Phone: 963949282497 | Note: No Note Phone: 963934392382 | Note: No Note Phone: 963937593945 | Note: No Note Phone: 963938883892 | Note: No Note Phone: 963093727926 | Note: No Note Phone: 963999062031 | Note: No Note Phone: 963938059209 | Note: No Note Phone: 963964685561 | Note: No Note Phone: 963944344299 | Note: No Note Phone: 963955355766 | Note: No Note Phone: 963999823383 | Note: No Note Phone: 963944439897 | Note: No Note Phone: 963995127821 | Note: No Note Phone: 963994257265 | Note: No Note Phone: 963936490987 | Note: No Note Phone: 963993530236 | Note: No Note Phone: 963 959 503 | Note: No Note Phone: 963986797797 | Note: No Note Phone: 963933529331 | Note: No Note Phone: 963951343947 | Note: No Note Phone: 963997585651 | Note: No Note Phone: 963991907052 | Note: No Note Phone: 963988964744 | Note: No Note Phone: 963099161662 | Note: No Note Phone: 963933175809 | Note: No Note Phone: 963937590105 | Note: No Note Phone: 963984222103 | Note: No Note Phone: 963099467874 | Note: No Note Phone: 963930301422 | Note: No Note Phone: 963988561330 | Note: No Note Phone: 963986769366 | Note: No Note Phone: 963940554896 | Note: No Note Phone: 963934825832 | Note: No Note Phone: 963980823984 | Note: No Note Phone: 963993761215 | Note: No Note Phone: 963+96399339 | Note: No Note Phone: 963992811392 | Note: No Note Phone: 963993292569 | Note: No Note Phone: 963985774901 | Note: No Note Phone: 963992475789 | Note: No Note Phone: 963995953364 | Note: No Note Phone: 96385166225 | Note: No Note Phone: 96398516622 | Note: No Note Phone: 963935689658 | Note: No Note Phone: 963933572705 | Note: No Note Phone: 963935722215 | Note: No Note Phone: 963981140916 | Note: No Note Phone: 963985215116 | Note: No Note Phone: 963932762035 | Note: No Note Phone: 963946120103 | Note: No Note Phone: 963933818455 | Note: No Note Phone: 963964858616 | Note: No Note Phone: 963944390916 | Note: No Note Phone: 963945739489 | Note: No Note Phone: 963932776772 | Note: No Note Phone: 963933333813 | Note: No Note Phone: 963980874584 | Note: No Note Phone: 963980294990 | Note: No Note Phone: 963934185580 | Note: No Note Phone: 963936921204 | Note: No Note Phone: 963093554127 | Note: No Note Phone: 963095965191 | Note: No Note Phone: 963093352887 | Note: No Note Phone: 963988128853 | Note: No Note Phone: 963094729812 | Note: No Note Phone: 963998748039 | Note: No Note Phone: 963955374066 | Note: تم Phone: 963095537406 | Note: No Note Phone: 963949005027 | Note: تم Phone: 963959651915 | Note: لاااااا Phone: 963094906005 | Note: No Note Phone: 963988617564 | Note: No Note Phone: 963992652773 | Note: No Note Phone: 963996727211 | Note: No Note Phone: 963991363270 | Note: No Note Phone: 963946790074 | Note: No Note Phone: 963939297072 | Note: No Note Phone: 963991197416 | Note: No Note Phone: 963980362067 | Note: No Note Phone: 963987076781 | Note: No Note Phone: 963945458695 | Note: No Note Phone: 963936408390 | Note: No Note Phone: 963991431763 | Note: No Note Phone: 963964795089 | Note: No Note Phone: 963965800050 | Note: No Note Phone: 963953677959 | Note: No Note Phone: 963099310584 | Note: No Note Phone: 963934108410 | Note: No Note Phone: 963944498647 | Note: No Note Phone: 963943569855 | Note: No Note Phone: 963992000214 | Note: No Note Phone: 963988733184 | Note: No Note Phone: 963997357928 | Note: No Note Phone: 963968217127 | Note: No Note Phone: 963984213886 | Note: No Note Phone: 963969955380 | Note: No Note Phone: 963093039426 | Note: No Note Phone: 963993067534 | Note: No Note Phone: 963996882906 | Note: No Note Phone: 963930981086 | Note: No Note Phone: 2979639929 | Note: No Note Phone: 963948320564 | Note: No Note Phone: 963933236526 | Note: No Note Phone: 963935731025 | Note: No Note Phone: 963940005693 | Note: No Note Phone: 963093435196 | Note: No Note Phone: 963933147140 | Note: رح يكمل تسجيل Phone: 963982950096 | Note: عم يصلح سيارتو بس تجهز رح يكمل تسجيل Phone: 963992304426 | Note: سيارتو جيب مصروفات كبير Phone: 963093412182 | Note: رقمو غلط Phone: 963944707024 | Note: راح النت من عندو واليوم رح يرجع يسجل Phone: 963997952574 | Note: No Note Phone: 963932863040 | Note: سيارتو بالتصليح Phone: 963942074619 | Note: مابدو Phone: 963934146486 | Note: تم التواصل Phone: 963992566299 | Note: تم التواصل Phone: 96348‏‪94573 | Note: رقم غلط Phone: 963933383373 | Note: تم التواصل Phone: 963962419880 | Note: تم التواصل Phone: 963938105556 | Note: تم التواصل Phone: 963981347112 | Note: تم التواصل Phone: 963959052791 | Note: تم التواصل Phone: 963949608050 | Note: تم التواصل Phone: 963998977934 | Note: تم التواصل Phone: 963931839232 | Note: تم التواصل Phone: 963935140176 | Note: تم التواصل Phone: 963932033543 | Note: تم التواصل Phone: 963991172711 | Note: تم التواصل Phone: 963959164134 | Note: تم التواصل Phone: 963943919419 | Note: ماعندو واتس رقمو مسكر Phone: 963994000556 | Note: تم التواصل Phone: 963098084512 | Note: رقم غلط Phone: 963932254575 | Note: تم التواصل Phone: 963945117692 | Note: تم التواصل Phone: 963932119678 | Note: تم التواصل Phone: 963993034046 | Note: تم التواصل Phone: 963954183741 | Note: تم التواصل Phone: 963951433826 | Note: ماعندو واتس خطو مسكر Phone: 963093661085 | Note: رقم غلط Phone: 963998287801 | Note: تم التواصل Phone: 963988912182 | Note: ماعندو واتس Phone: 963996024113 | Note: تم التواصل Phone: 963931677655 | Note: تم التواصل Phone: 963933921336 | Note: تم التواصل Phone: 963936374163 | Note: تم التواصل Phone: 963942047365 | Note: تم التواصل Phone: 963981360800 | Note: تم التواصل Phone: 963956396223 | Note: تم التواصل Phone: 963963899416 | Note: رقم غلط Phone: 963934493911 | Note: تم التواصل Phone: 963934950868 | Note: تم التواصل Phone: 963936659081 | Note: تم التواصل Phone: 963945973939 | Note: تم التواصل Phone: 963983444102 | Note: تم التواصل Phone: 963951844719 | Note: تم التواصل Phone: 963932663633 | Note: تم التواصل Phone: 963093266363 | Note: رقم غلط Phone: 963937271849 | Note: تم التواصل معو بيك اب Phone: 963938728361 | Note: تم التواصل Phone: 963947640146 | Note: تم التواصل Phone: 963992439500 | Note: No Note Phone: 963997489672 | Note: تم التواصل Phone: 963094850489 | Note: رقم غلط Phone: 963990115156 | Note: تم التواصل Phone: 963962311317 | Note: ماعندو واتس وخطو مسكر Phone: 963093172947 | Note: الرقم غلط Phone: 963993762515 | Note: تم التواصل Phone: 963931799545 | Note: تم التواصل Phone: 963945187714 | Note: تم التواصل Phone: 963968911015 | Note: ماعندو واتس رقمو مسكر Phone: 963944750715 | Note: تم التواصل Phone: 963998134492 | Note: تم التواصل Phone: 963099813449 | Note: رقمو غلط Phone: 963932727476 | Note: تم التواصل Phone: 963933518336 | Note: تم التواصل Phone: 963998885309 | Note: تم التواصل Phone: 963988248185 | Note: تم التواصل Phone: 963093067938 | Note: No Note Phone: 963981383714 | Note: تم التواصل Phone: 963939362191 | Note: رقمو مغلق وماعندو واتس Phone: 963933440323 | Note: تم التواصل Phone: 963982143227 | Note: تم التواصل Phone: 963938145916 | Note: تم التواصل Phone: 963933718454 | Note: تم التواصل Phone: 963931800533 | Note: تم التواصل Phone: 963934294133 | Note: تم التواصل Phone: 963939808314 | Note: رقم غلط ومسكر خطو Phone: 963935745914 | Note: تم التواصل Phone: 963969902667 | Note: تم التواصل Phone: 963933735326 | Note: ماعندو واتس رقمو غلط Phone: 963998699541 | Note: تم التواصل Phone: 963093333839 | Note: رقم غلط Phone: 963966313126 | Note: تم التواصل Phone: 963956451887 | Note: تم التواصل Phone: 963967415296 | Note: تم التواصل Phone: 963997766064 | Note: تم التواصل Phone: 963962854801 | Note: تم التواصل Phone: 963998190089 | Note: تم التواصل Phone: 963981634358 | Note: تم التواصل Phone: 963938289156 | Note: تم التواصل Phone: 963095645188 | Note: رقم غلط Phone: 963936908818 | Note: تم التواصل Phone: 963941385190 | Note: تم التواصل Phone: 963009639885 | Note: رقم غلط Phone: 963935777750 | Note: تم التواصل Phone: 963985578199 | Note: تم التواصل Phone: 963099317895 | Note: رقم غلط Phone: 963990417834 | Note: تم التواصل Phone: 963093727184 | Note: رقم غلط Phone: 963968750666 | Note: ماعندو واتس ورقمو مسكر Phone: 963998668125 | Note: تم التواصل Phone: 963991833068 | Note: تم التواصل Phone: 963940740151 | Note: ماعندي واتس ورقمو مسكر Phone: 963955544813 | Note: تم التواصل Phone: 963933202022 | Note: ماعندو واتساب ورخطو مسكر Phone: 963933221881 | Note: ماعندو واتس وخطو مسكر Phone: 963943358179 | Note: تم التواصل Phone: 963+96393349 | Note: رقم غلط Phone: 963933804760 | Note: تم التواصل Phone: 963988214321 | Note: تم التواصل Phone: 963991903251 | Note: تم التواصل Phone: 963933400489 | Note: تم التواصل Phone: 963940340848 | Note: تم التواصل Phone: 963992458425 | Note: تم التواصل Phone: 963932555452 | Note: تم التواصل Phone: 963965218471 | Note: تم التواصل Phone: 963933292470 | Note: تم التواصل Phone: 963943889236 | Note: تم التواصل وكمل تسجيلو Phone: 963988133863 | Note: تم التواصل Phone: 963094444810 | Note: رقمو غلط Phone: 963930946809 | Note: تم التواصل Phone: 963968191496 | Note: تم التواصل Phone: 963935090886 | Note: تم التواصل Phone: 963991922952 | Note: تم التواصل Phone: 963991112991 | Note: تم التواصل Phone: 963986170776 | Note: تم التواصل Phone: 963999743765 | Note: تم التواصل Phone: 963932111786 | Note: تم التواصل Phone: 963933681672 | Note: تم التواصل Phone: 963938552167 | Note: تم التواصل Phone: 963933206306 | Note: تم التواصل Phone: 963957346118 | Note: تم التواصل Phone: 963997392413 | Note: تم التواصل Phone: 963988227272 | Note: تم التواصل Phone: 963988029059 | Note: تم التواصل Phone: 963945832988 | Note: تم التواصل Phone: 963997944590 | Note: تم التواصل Phone: 963980363715 | Note: تم التواصل Phone: 963935102639 | Note: تم التواصل Phone: 963954438781 | Note: تم التواصل Phone: 963945223878 | Note: تم التواصل Phone: 963980581094 | Note: تم التواصل Phone: 963939164164 | Note: تم التواصل Phone: 963938124006 | Note: تم التواصل Phone: 963944349036 | Note: تم التواصل Phone: 963992057768 | Note: غير مهتم Phone: 963988177909 | Note: تم التواصل Phone: 963932049144 | Note: No Note Phone: 963992393038 | Note: No Note Phone: 963952391236 | Note: No Note Phone: 963935039644 | Note: No Note Phone: 963985924850 | Note: No Note Phone: 963932377014 | Note: No Note Phone: 963993235215 | Note: No Note Phone: 963980541950 | Note: No Note Phone: 963945957334 | Note: No Note Phone: 963981355144 | Note: No Note Phone: 963938139830 | Note: No Note Phone: 963932562745 | Note: No Note Phone: 963994661362 | Note: No Note Phone: 963988342603 | Note: No Note Phone: 963994011134 | Note: No Note Phone: 963936104080 | Note: No Note Phone: 963992788749 | Note: No Note Phone: 963998892720 | Note: No Note Phone: 963996682748 | Note: No Note Phone: 963938570002 | Note: No Note Phone: 963931745699 | Note: No Note Phone: 963992165521 | Note: No Note Phone: 963993595631 | Note: No Note Phone: 963933949753 | Note: No Note Phone: 963934629935 | Note: No Note Phone: 963965778887 | Note: اجدب Phone: 963980212534 | Note: No Note Phone: 963956784191 | Note: No Note Phone: 963935443899 | Note: No Note Phone: 963958642713 | Note: No Note Phone: 963999138915 | Note: No Note Phone: 963948941187 | Note: No Note Phone: 963953459606 | Note: تم Phone: 963934146288 | Note: تم Phone: 963933256528 | Note: تم Phone: 963998883027 | Note: تم Phone: 963968481449 | Note: تم Phone: 963965247307 | Note: ما معو سيارة Phone: 963956761624 | Note: تم Phone: 963939724962 | Note: تم Phone: 963936030548 | Note: تم Phone: 962781821306 | Note: خطأ Phone: 963960040775 | Note: No Note Phone: 963996642236 | Note: No Note Phone: 963934293954 | Note: تم Phone: 963934928537 | Note: تم Phone: 963941440312 | Note: No Note Phone: 963937214172 | Note: No Note Phone: 963933824331 | Note: No Note Phone: 963945555043 | Note: No Note Phone: 963938676742 | Note: تم Phone: 963933306898 | Note: تم Phone: 963933708476 | Note: No Note Phone: 963994795950 | Note: No Note Phone: 963990329520 | Note: تم Phone: 963960977309 | Note: تم Phone: 963933267955 | Note: تم Phone: 963996186195 | Note: تم Phone: 916364908545 | Note: تم Phone: 919154792575 | Note: تم Phone: 963998119558 | Note: تم Phone: 919606970074 | Note: خطأ Phone: 916364908621 | Note: خطأ Phone: 962772735902 | Note: No Note Phone: 916366356713 | Note: No Note Phone: 16693334444 | Note: No Note Phone: 962782700835 | Note: No Note Phone: 962782070515 | Note: No Note Phone: 963984429412 | Note: No Note Phone: 963966673673 | Note: No Note Phone: 962796377987 | Note: No Note Phone: 963947222548 | Note: No Note Phone: 639276036618 | Note: No Note Phone: 963798583052 | Note: No Note ``` ## File: serviceapp/deleteDriverNotCompleteRegistration.php ``` encryptData($phone); // 2. تنفيذ الحذف بشرط تطابق الهاتف وأن الحالة 'yet' $sql = "DELETE FROM driver WHERE phone = ? AND employmentType = 'yet'"; $stmt = $con->prepare($sql); $stmt->execute(array($phone)); $count = $stmt->rowCount(); if ($count > 0) { // 3. إرسال رد النجاح ليتم عرضه في التطبيق (Get.snackbar) jsonSuccess(null, "Driver deleted successfully"); } else { // إرسال رد فشل (إذا لم يتم العثور على الرقم أو كان السائق مكتملاً) jsonError("Driver not found or already active"); } ?> ``` ## File: serviceapp/getDriversWaitingActive.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك تشفير أرقام الهواتف فقط للإخراج foreach ($rows as &$row) { if (!empty($row['phone_number'])) { $row['phone_number'] = $encryptionHelper->decryptData($row['phone_number']); } if (!empty($row['first_name'])) { $row['first_name'] = $encryptionHelper->decryptData($row['first_name']); } if (isset($row['last_name'])) { $row['last_name'] = $encryptionHelper->decryptData($row['last_name']); } } jsonSuccess($rows); } else { jsonError("No Phone verified yet found"); } ?> ``` ## File: serviceapp/getDriverDetailsForActivate.php ``` prepare($sql); $stmt->execute([':driverId' => $driverId]); if ($stmt->rowCount() > 0) { $row = $stmt->fetch(PDO::FETCH_ASSOC); // فك التشفير للحقول المطلوبة $fieldsToDecrypt = [ 'phone','email','gender','national_number','first_name','last_name', 'name_arabic','address','site','vin','car_plate','owner' ]; foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && $row[$field] !== '') { try { $row[$field] = $encryptionHelper->decryptData($row[$field]); } catch (Exception $e) { $row[$field] = "Decryption Failed"; } } } // ✅ إزالة الحقول الحسّاسة من الاستجابة $fieldsToRemove = ['password', 'password_hash', 'salt', 'reset_token']; foreach ($fieldsToRemove as $f) { if (array_key_exists($f, $row)) { unset($row[$f]); } } // إرسال الاستجابة jsonSuccess([$row]); } else { jsonError("No data found for the specified driver ID"); } ``` ## File: serviceapp/getComplaintAllDataForDriver.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($row as &$item) { if (isset($item['passengerName'])) { $item['passengerName'] = $encryptionHelper->decryptData($item['passengerName']); } if (isset($item['driverName'])) { $item['driverName'] = $encryptionHelper->decryptData($item['driverName']); } if (isset($item['gender'])) { $item['gender'] = $encryptionHelper->decryptData($item['gender']); } if (isset($item['driverToken'])) { $item['driverToken'] = $encryptionHelper->decryptData($item['driverToken']); } if (isset($item['passengerToken'])) { $item['passengerToken'] = $encryptionHelper->decryptData($item['passengerToken']); } } jsonSuccess($row); } else { jsonError($message = $sql); } ?> ``` ## File: serviceapp/getJsonFile.php ``` = DATE_SUB(NOW(), INTERVAL 5 DAY) ORDER BY pv.created_at DESC; "; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فتح الملف للكتابة (Mode 'w' يقوم بإنشاء الملف أو مسح محتواه السابق والكتابة من جديد) $fileHandle = fopen($filename, 'w'); // التحقق من أن الملف فُتح بنجاح if ($fileHandle) { foreach ($rows as $r) { $phone = ""; $note = "No Note"; // القيمة الافتراضية إذا لم توجد ملاحظة // 1. فك تشفير رقم الهاتف if (isset($r['phone_number']) && $r['phone_number'] != null) { $phone = $encryptionHelper->decryptData($r['phone_number']); } // 2. تجهيز نص الملاحظة if (isset($r['note']) && $r['note'] != null) { $note = $r['note']; } // 3. تنسيق السطر الذي سيتم حفظه // الشكل: Phone: 0123456789 | Note: مهتم بالتسجيل $line = "Phone: " . $phone . " | Note: " . $note . PHP_EOL; // 4. الكتابة داخل الملف fwrite($fileHandle, $line); } // إغلاق الملف بعد الانتهاء fclose($fileHandle); // طباعة رسالة نجاح مع رابط للملف (اختياري) echo json_encode([ "status" => "success", "message" => "File created successfully", "file" => $filename, "count" => count($rows) ]); } else { jsonError("Unable to open file for writing."); } } else { jsonError("No phone numbers found in the last 5 days"); } ?> ``` ## File: serviceapp/registerDriverAndCarService.php ``` beginTransaction(); logStep(1, "Transaction started via beginTransaction()"); // --- 2. Recolección de Datos (Conductor + Coche) --- $phone = filterRequest("phone"); $password = filterRequest("password"); $firstName = filterRequest("first_name"); $lastName = filterRequest("last_name"); // تسجيل البيانات المبدئية (بدون كلمات المرور) للتأكد من وصولها logStep(2, "Inputs received -> Phone: $phone, Name: $firstName $lastName"); // التحقق من الحقول الإجبارية if (empty($phone) || empty($password) || empty($firstName) || empty($lastName)) { throw new Exception("Required fields missing (phone, password, first_name, last_name)."); } // --- 3. Generar ID de Conductor --- $driverId = substr(md5($phone), 0, 20); logStep(3, "Driver ID generated: $driverId"); // --- 4. Procesamiento de Datos del Conductor --- $password_hashed = password_hash($password, PASSWORD_DEFAULT); $email = filterRequest("email"); if (empty($email) || $email === 'Not specified') { $email = $phone . '@intaleqapp.com'; } $nameArabic = $firstName . ' ' . $lastName; $site = filterRequest("site"); $address = $site; // بيانات إضافية $gender = filterRequest("gender"); $license_type = filterRequest("license_type"); $nationalNumber = filterRequest("national_number"); $issue_date = filterRequest("issue_date"); $expiry_date = filterRequest("expiry_date"); $licenseCategories = filterRequest("license_categories"); $licenseIssueDate = filterRequest("license_issue_date"); $birthdate = filterRequest("birthdate"); $maritalStatus = filterRequest("maritalStatus"); // --- 5. Recolección de Datos del Coche --- $owner = filterRequest("owner"); $color = filterRequest("color"); $colorHex = filterRequest("color_hex"); $model = filterRequest("model"); $carPlate = filterRequest("car_plate"); $make = filterRequest("make"); $fuel = filterRequest("fuel"); $year = filterRequest("year"); $vin = filterRequest("vin"); if (empty($vin)) { $vin = 'unknown'; } $carExpirationDate = filterRequest("expiration_date"); logStep(4, "Data processing completed. Car Plate: $carPlate, VIN: $vin"); // --- 6. Cifrado de Datos --- try { $encryptedPhone = $encryptionHelper->encryptData($phone); $encryptedEmail = $encryptionHelper->encryptData($email); $encryptedFirstName = $encryptionHelper->encryptData($firstName); $encryptedLastName = $encryptionHelper->encryptData($lastName); $encryptedNameArabic = $encryptionHelper->encryptData($nameArabic); $encryptedGender = $encryptionHelper->encryptData($gender); $encryptedNationalNumber = $encryptionHelper->encryptData($nationalNumber); $encryptedAddress = $encryptionHelper->encryptData($address); $encryptedSite = $encryptionHelper->encryptData($site); $encryptedBirthdate = $encryptionHelper->encryptData($birthdate); $encryptedOwner = $encryptionHelper->encryptData($owner); $encryptedCarPlate = $encryptionHelper->encryptData($carPlate); logStep(5, "Encryption successful for sensitive fields."); } catch (Exception $encEx) { throw new Exception("Encryption Error: " . $encEx->getMessage()); } // --- 7. Comprobación de Duplicados --- // ملاحظة: إذا كان التشفير عشوائياً، فلن يجد التكرار هنا. $dup = $con->prepare("SELECT id FROM driver WHERE phone = :phone OR email = :email OR national_number = :national_number"); $dup->execute([':phone' => $encryptedPhone, ':email' => $encryptedEmail, ':national_number' =>$encryptedNationalNumber]); if ($dup->rowCount() > 0) { logStep(6, "Duplicate found! Phone or Email or encryptedNationalNumber already exists."); throw new Exception("Phone or email already registered."); } logStep(6, "No duplicates found. Proceeding."); // --- 8. INSERCIÓN 1: Tabla 'driver' --- $sqlDriver = " INSERT INTO driver ( id, phone, email, password, gender, license_type, national_number, name_arabic, issue_date, expiry_date, license_categories, address, licenseIssueDate, status, birthdate, site, first_name, last_name, accountBank, bankCode, employmentType, maritalStatus, fullNameMaritial, expirationDate, created_at, updated_at ) VALUES ( :id, :phone, :email, :pwd, :gender, :license_type, :national_number, :name_arabic, :issue_date, :expiry_date, :license_categories, :address, :licenseIssueDate, :status, :birthdate, :site, :first_name, :last_name, :accountBank, :bankCode, :employmentType, :maritalStatus, :fullNameMaritial, :expirationDate, NOW(), NOW() ) "; $stmtDriver = $con->prepare($sqlDriver); // تم توحيد المفاتيح لتشمل النقطتين (:) $driverData = [ ':id' => $driverId, ':phone' => $encryptedPhone, ':email' => $encryptedEmail, ':pwd' => $password_hashed, ':gender' => $encryptedGender, ':license_type' => $license_type, ':national_number' => $encryptedNationalNumber, ':name_arabic' => $encryptedNameArabic, ':issue_date' => $issue_date, ':expiry_date' => $expiry_date, ':license_categories' => $licenseCategories ?? 'B', ':address' => $encryptedAddress, ':licenseIssueDate' => $licenseIssueDate, ':status' => 'actives', ':birthdate' => $encryptedBirthdate, ':site' => $encryptedSite, ':first_name' => $encryptedFirstName, ':last_name' => $encryptedLastName, ':accountBank' => 'yet', ':bankCode' => 'yet', ':employmentType' => $maritalStatus ?? 'yet', ':maritalStatus' => $maritalStatus ?? 'yet', ':fullNameMaritial' => 'yet', ':expirationDate' => 'yet', ]; if (!$stmtDriver->execute($driverData)) { // تسجيل خطأ SQL بالتفصيل $errInfo = $stmtDriver->errorInfo(); throw new Exception("Driver Insert Failed: " . $errInfo[2]); } logStep(7, "Driver table insert successful."); // --- 9. INSERCIÓN 2: Tabla 'CarRegistration' --- $sqlCar = " INSERT INTO CarRegistration ( driverID, vin, owner, color, color_hex, model, car_plate, make, fuel, `year`, expiration_date, created_at ) VALUES ( :driverId, :vin, :owner, :color, :color_hex, :model, :car_plate, :make, :fuel, :year, :expiration_date, NOW() ) "; $stmtCar = $con->prepare($sqlCar); $carData = [ ':driverId' => $driverId, ':vin' => $vin, ':owner' => $encryptedOwner, ':color' => $color, ':color_hex' => $colorHex, ':model' => $model, ':car_plate' => $encryptedCarPlate, ':make' => $make, ':fuel' => $fuel, ':year' => $year, ':expiration_date' => $carExpirationDate ]; if (!$stmtCar->execute($carData)) { $errInfo = $stmtCar->errorInfo(); throw new Exception("Car Insert Failed: " . $errInfo[2]); } logStep(8, "CarRegistration insert successful."); // --- 10. Confirmar Transacción --- $con->commit(); logStep(9, "COMMIT successful. Sending Success Response."); jsonSuccess(["driverId" => $driverId, "message" => "Driver and car registered successfully."]); // --- 11. Enviar Notificación (خارج المعاملة يفضل، ولكن هنا كما في الكود الأصلي) --- try { $supportPhones = ['0952475740', '0952475742']; $randomIndex = array_rand($supportPhones); $phoneToUse = $supportPhones[$randomIndex]; $randomNumber = rand(1000, 999999); $messageBody = "أهلاً وسهلاً كابتن $firstName 👋\n" . "تم تفعيل حسابك على تطبيق *سيرو*.\n" . "يمكنك الآن تسجيل الدخول والبدء بالعمل مباشرة.\n" . "للمساعدة تواصل معنا على الرقم: $phoneToUse\n" . "نتمنى لك عمل موفق 🚖\n\n" . "معرف الرسالة: $randomNumber"; sendWhatsAppFromServer($phone, $messageBody); logStep(10, "WhatsApp notification sent."); } catch (Exception $waError) { // لا نوقف العملية إذا فشل الواتساب، فقط نسجل الخطأ logStep(10, "WhatsApp Warning: " . $waError->getMessage()); } } catch (PDOException $e) { $con->rollBack(); $errorMsg = "Database Error (PDO): " . $e->getMessage(); logStep("ERROR-PDO", $errorMsg); // إظهار رسالة عامة للمستخدم، وتسجيل التفاصيل في السيرفر jsonError("System error during registration. Please contact support."); } catch (Exception $e) { // إذا كانت المعاملة مفتوحة، قم بإلغائها if ($con->inTransaction()) { $con->rollBack(); } $errorMsg = "General Error: " . $e->getMessage(); logStep("ERROR-GEN", $errorMsg); jsonError($e->getMessage()); } ?> ``` ## File: serviceapp/getdriverstotalMonthly.php ``` prepare($sql); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($data) { echo json_encode(array("status" => "success", "message" => $data)); } else { echo json_encode(array("status" => "success", "message" => [])); } } catch (PDOException $e) { echo json_encode(array("status" => "failure", "message" => $e->getMessage())); } ?> ``` ## File: serviceapp/addNotesDriver.php ``` encryptData($phone); // SQL query: insert new row OR update existing one if phone already exists $sql = "INSERT INTO `notesForDriverService` (`phone`, `note`, `editor`) VALUES (:phone, :note, :editor) ON DUPLICATE KEY UPDATE `note` = VALUES(`note`), `editor` = VALUES(`editor`)"; // Prepare the SQL statement $stmt = $con->prepare($sql); // Bind the parameters $stmt->bindParam(':phone', $encryptedPhone); $stmt->bindParam(':note', $note); $stmt->bindParam(':editor', $editor); // Execute the query $success = $stmt->execute(); if ($success) { if ($stmt->rowCount() > 0) { jsonSuccess(null, "Note inserted/updated successfully"); } else { jsonError("No changes were made"); } } else { jsonError("Database error"); } ?> ``` ## File: serviceapp/getNotesForEmployee.php ``` prepare($sql); $stmt->execute(); $notes_data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($notes_data) { // التصحيح: استخدام حلقة التكرار وتمرير الصف كمرجع (&) لتعديل البيانات الأصلية foreach ($notes_data as &$row) { // التأكد من وجود عمود الهاتف قبل فك التشفير if (isset($row['phone'])) { // استخدام دالة فك التشفير (تأكد أن الدالة decrypt موجودة في connect.php) // أو استخدم $encryptionHelper->decryptData($row['phone']) إذا كنت تستخدم كلاس $row['phone'] = $encryptionHelper->decryptData($row['phone']); } } unset($row); // كسر الارتباط بالمتغير الأخير لضمان سلامة الكود jsonSuccess($notes_data); } else { jsonError("No notes found for this date"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: serviceapp/getEmployeeDriverAfterCallingRegister.php ``` = '$start_date' AND DATE(created_at) <= '$end_date' GROUP BY employmentType"; try { $stmt = $con->prepare($sql); $stmt->execute(); $stats_data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($stats_data) { // طباعة البيانات كـ JSON مع إضافة التواريخ المستخدمة للعلم printSuccess([ "data" => $stats_data, "period" => [ "start" => $start_date, "end" => $end_date ] ]); } else { jsonError("No data found for the selected period"); } } catch (PDOException $e) { // في حال حدوث خطأ في قاعدة البيانات jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: serviceapp/getRidesStatic.php ``` = '$start_date' AND ride.created_at <= '$end_date 23:59:59' AND ride.status = 'Finished') AS totalMonthly FROM date_series LEFT JOIN ride ON DATE(ride.created_at) = date_series.date AND ride.status = 'Finished' WHERE date_series.date >= '$start_date' AND date_series.date <= '$end_date' GROUP BY date_series.date ORDER BY date_series.date ASC; "; $stmt = $con->prepare($sql); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($data) { jsonSuccess($data); } else { jsonError("No data found"); } ?> ``` ## File: serviceapp/getEmployeeStatic.php ``` = '$first_day_of_month' AND DATE(d.created_at) <= '$last_day_of_month' GROUP BY `date`, d.`maritalStatus` ORDER BY `date` ASC; "; $stmt = $con->prepare($sql); $stmt->execute(); $passenger_data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($passenger_data) { // طباعة البيانات كـ JSON jsonSuccess($data = $passenger_data); } else { // طباعة رسالة فشل jsonError($message = "No data found"); } ?> ``` ## File: serviceapp/getPassengersStatic.php ``` prepare($sql); $stmt->execute(); $passenger_data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($passenger_data) { echo json_encode(array("status" => "success", "message" => $passenger_data)); } else { echo json_encode(array("status" => "success", "message" => [])); } } catch (PDOException $e) { echo json_encode(array("status" => "failure", "message" => $e->getMessage())); } ?> ``` ## File: serviceapp/web/getDrivers.php ``` exec("set names utf8mb4"); } $phone = ""; if (isset($_GET['phone_number'])) { $phone = htmlspecialchars(strip_tags($_GET['phone_number'])); } elseif (isset($_POST['phone_number'])) { $phone = htmlspecialchars(strip_tags($_POST['phone_number'])); } else { $phone = filterRequest("phone_number"); } if (empty($phone)) { jsonError("Phone number is required"); exit; } // تشفير الرقم للبحث $phoneEncrypted = $encryptionHelper->encryptData($phone); // الاستعلام: نختار الحقول بدقة لتجنب التضارب $sql = "SELECT d.id as driver_id, d.name_arabic as driver_name_encrypted, -- الاسم من جدول السائق d.phone as phone_encrypted, d.gender as gender_encrypted FROM `driver` d WHERE d.phone = ? LIMIT 1"; try { $stmt = $con->prepare($sql); $stmt->execute([$phoneEncrypted]); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as &$item) { // ============================================ // 1. فك تشفير الحقول المشفرة فقط (حسب ملف CSV) // ============================================ // بيانات السائق if (!empty($item['driver_name_encrypted'])) { $item['driverName'] = $encryptionHelper->decryptData($item['driver_name_encrypted']); } if (!empty($item['phone_encrypted'])) { $item['phone'] = $encryptionHelper->decryptData($item['phone_encrypted']); } if (!empty($item['gender_encrypted'])) { $item['gender'] = $encryptionHelper->decryptData($item['gender_encrypted']); } } jsonSuccess($rows); } else { jsonError("No driver found with this phone number"); } } catch (PDOException $e) { error_log("SQL Error: " . $e->getMessage()); jsonError("Database error"); } catch (Exception $e) { error_log("General Error: " . $e->getMessage()); jsonError("System error"); } ?> ``` ## File: serviceapp/work/addDriverWantWork.php ``` prepare($sql); // ربط القيم $stmt->bindParam(':driver_name', $driver_name); $stmt->bindParam(':phone', $phone); $stmt->bindParam(':national_id', $national_id); $stmt->bindParam(':birth_date', $birth_date); $stmt->bindParam(':license_type', $license_type); $stmt->bindParam(':site', $site); // تنفيذ الاستعلام if ($stmt->execute()) { jsonSuccess(null, "Driver data saved successfully"); } else { jsonError("Failed to save driver data"); } ?> ``` ## File: serviceapp/work/addCarWantWork.php ``` encryptData(filterRequest("owner_name")); $phone = $encryptionHelper->encryptData(filterRequest("phone")); // 🔒 $car_number = $encryptionHelper->encryptData(filterRequest("car_number")); $manufacture_year = filterRequest("manufacture_year"); $car_model = filterRequest("car_model"); $car_type = filterRequest("car_type"); $site = filterRequest("site"); $registration_date = filterRequest("registration_date"); // تحقق بسيط من القيم المطلوبة if (empty($owner_name) || empty($phone)) { jsonError("Missing required fields", 422); } // SQL مع bind parameters $sql = "INSERT INTO `carsToWork`( `owner_name`, `phone`, `car_number`, `manufacture_year`, `car_model`, `car_type`, `site`, `registration_date` ) VALUES ( :owner_name, :phone, :car_number, :manufacture_year, :car_model, :car_type, :site, :registration_date )"; try { $stmt = $con->prepare($sql); $stmt->bindParam(':owner_name', $owner_name); $stmt->bindParam(':phone', $phone); $stmt->bindParam(':car_number', $car_number); $stmt->bindParam(':manufacture_year', $manufacture_year); $stmt->bindParam(':car_model', $car_model); $stmt->bindParam(':car_type', $car_type); $stmt->bindParam(':site', $site); $stmt->bindParam(':registration_date', $registration_date); if ($stmt->execute()) { printSuccess("Car data saved successfully", ["insert_id" => $con->lastInsertId()]); } else { $err = $stmt->errorInfo(); jsonError("Failed to save car data: " . ($err[2] ?? 'unknown error'), 500); } } catch (Exception $e) { jsonError("Exception: " . $e->getMessage(), 500); } ?> ``` ## File: ride/rate/add.php ``` prepare($sql); $stmt->bindParam(':passenger_id', $passenger_id); $stmt->bindParam(':driverID', $driverID); $stmt->bindParam(':rideId', $rideId); $stmt->bindParam(':rating', $rating); $stmt->bindParam(':comment', $comment); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Rate inserted successfully"); } else { jsonError("Failed to save rating information"); } ?> ``` ## File: ride/rate/add_rate_app.php ``` encryptData($email); $phone = $encryptionHelper->encryptData($phone); // Insert into `ratingApp` table $sql = "INSERT INTO `ratingApp`(`id`, `name`, `email`, `phone`, `userId`, `userType`, `rating`, `comment`) VALUES (null, :name, :email, :phone, :userId, :userType, :rating, :comment)"; $stmt = $con->prepare($sql); $stmt->bindParam(':name', $name); $stmt->bindParam(':email', $email); $stmt->bindParam(':phone', $phone); $stmt->bindParam(':userId', $userId); $stmt->bindParam(':userType', $userType); $stmt->bindParam(':rating', $rating); $stmt->bindParam(':comment', $comment); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess($message = 'Rating inserted successfully'); } else { jsonError($message = "Failed to save rating information"); } ?> ``` ## File: ride/rate/addRateToDriver.php ``` prepare($sql); $stmt->bindParam(':passenger_id', $passenger_id); $stmt->bindParam(':driver_id', $driver_id); $stmt->bindParam(':ride_id', $ride_id); $stmt->bindParam(':rating', $rating); $stmt->bindParam(':comment', $comment); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Rate inserted successfully"); } else { // في حال لم يتم الإدخال ولكن لم يحدث خطأ فني (نادرة الحدوث في Insert) jsonError("Failed to save rating information"); } } catch (PDOException $e) { // --- هذا القسم خاص بأخطاء قاعدة البيانات --- // 1. تسجيل الخطأ في ملف نصي على السيرفر (للمطور فقط) // سيتم إنشاء ملف اسمه errors.log في نفس المجلد إذا لم يكن موجوداً $errorMsg = "[" . date("Y-m-d H:i:s") . "] DB Error: " . $e->getMessage() . " | RideID: $ride_id \n"; file_put_contents("errors.log", $errorMsg, FILE_APPEND); // 2. إرجاع رسالة خطأ عامة للتطبيق jsonError("Database Error: Could not save rating"); } catch (Exception $e) { // --- هذا القسم خاص بالأخطاء العامة الأخرى --- $errorMsg = "[" . date("Y-m-d H:i:s") . "] General Error: " . $e->getMessage() . "\n"; file_put_contents("errors.log", $errorMsg, FILE_APPEND); jsonError("Error: " . $e->getMessage()); } ?> ``` ## File: ride/rate/getPassengerRate.php ``` prepare($sql); $stmt->bindParam(':passenger_id', $passengerId); $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetch(PDO::FETCH_ASSOC); jsonSuccess($row); } else { jsonError("No rating record found"); } ?> ``` ## File: ride/rate/sendEmailRateingApp.php ```

أهلاً كابتن $name،

نشكرك جزيل الشكر على تقييمك لتطبيق سيرو!

لقد استلمنا تقييمك وهو $rating نجوم.

تعليقك: \"$comment\"

نحن نقدر ملاحظاتك، ونسعد دائماً بتواصلك معنا لتحسين تجربتك. إذا كان لديك أي استفسار، لا تتردد بالرد على هذا البريد.

مع خالص الشكر،

فريق سيرو.

"; if (mail($email, $subject, $bodyEmail, $headers)) { echo "Email sent successfully to $email."; } else { echo "Failed to send email."; } ?> ``` ## File: ride/rate/getDriverRate.php ``` prepare($sql); $stmt->bindParam(':driver_id', $driver_id); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else { // Print a failure message jsonError($message = "No rating record found"); } ?> ``` ## File: ride/places_syria/add.php ``` ``` ## File: ride/places_syria/get.php ``` setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { // تجاهل الخطأ إذا كان قد تم تعيينه بالفعل } // 1. استقبال المدخلات باستخدام دالة filterRequest الخاصة بك $query = trim((string) filterRequest("query")); $latMin = filterRequest("lat_min"); $latMax = filterRequest("lat_max"); $lngMin = filterRequest("lng_min"); $lngMax = filterRequest("lng_max"); // 2. التحقق من المدخلات if ($query === "" || $latMin === null || $latMax === null || $lngMin === null || $lngMax === null) { jsonError("Missing required parameters: query, lat_min, lat_max, lng_min, lng_max"); exit; } // تحويل الإحداثيات إلى أرقام عشرية $latMin = (float) $latMin; $latMax = (float) $latMax; $lngMin = (float) $lngMin; $lngMax = (float) $lngMax; // 3. بناء الاستعلام الذكي (الجزء المحدّث) // تحضير كلمة البحث لوضعها في MATCH() AGAINST() // نضيف '*' لكل كلمة للبحث عن الكلمات التي تبدأ بهذا الجزء $search_terms = preg_split('/\s+/', $query, -1, PREG_SPLIT_NO_EMPTY); $search_boolean = ''; foreach ($search_terms as $term) { $search_boolean .= '+' . $term . '* '; // '+' تعني أن الكلمة يجب أن تكون موجودة } $search_boolean = trim($search_boolean); // بناء المضلع الجغرافي (Bounding Box Polygon) للفهرس المكاني $bbox_wkt = sprintf( 'POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))', $lngMin, $latMin, $lngMax, $latMin, $lngMax, $latMax, $lngMin, $latMax, $lngMin, $latMin ); // الاستعلام النهائي الذي يجمع بين البحث النصي والجغرافي $sql = " SELECT id, latitude, longitude, name, name_ar, name_en, address, category, created_at FROM `{$tableName}` WHERE -- الشرط الأول: البحث بالنص الكامل (سريع جداً) MATCH(name, name_ar, name_en, address, category) AGAINST(? IN BOOLEAN MODE) -- الشرط الثاني: البحث الجغرافي (سريع جداً) AND ST_CONTAINS(ST_GEOMFROMTEXT(?), location) LIMIT 50; -- حد أعلى للنتائج الأولية "; // 4. تنفيذ الاستعلام وإرجاع النتيجة try { $stmt = $con->prepare($sql); // ربط المتغيرات بالاستعلام بالترتيب $stmt->execute([$search_boolean, $bbox_wkt]); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($rows); } catch (PDOException $e) { // يمكنك استخدام هذا السطر أثناء التطوير لعرض الخطأ الفعلي // jsonError('DB Error: ' . $e->getMessage()); exit; // تسجيل الخطأ في سجلات الخادم للرجوع إليه لاحقاً error_log("search_places_optimized.php error: " . $e->getMessage()); jsonError("Database query error occurred"); } ?> ``` ## File: ride/places_syria/reverse_geocode.php ``` 'error', 'message' => 'Missing lat or lon parameters']); exit; } // --- الاتصال بقاعدة البيانات --- $conn = new mysqli($servername, $username, $password, $dbname); $conn->set_charset("utf8mb4"); if ($conn->connect_error) { echo json_encode(['status' => 'error', 'message' => 'Database connection failed: ' . $conn->connect_error]); exit; } // --- دالة لتحليل other_tags (نفس الدالة من السكربت السابق) --- function parseHstoreValue($hstoreString, $keyToFind) { if (empty($hstoreString) || empty($keyToFind)) return null; if (preg_match('/"' . preg_quote($keyToFind, '/') . '"\s*=>\s*"([^"]+)"/', $hstoreString, $matches)) { $value = $matches[1]; $decodedValue = urldecode($value); $decodedValue = urldecode($decodedValue); $cleanedValue = iconv('UTF-8', 'UTF-8//IGNORE', $decodedValue); return ($cleanedValue === false || trim($cleanedValue) === '') ? null : $cleanedValue; } return null; } // --- الاستعلام الرئيسي: البحث عن أقرب نقطة باستخدام الفهرس المكاني --- // نختار الأعمدة الأساسية + أعمدة المناطق المحسوبة مسبقاً + other_tags $sql = " SELECT p.name, p.neighbourhood_name, p.city_name, p.other_tags, ST_Distance_Sphere( p.geom, ST_PointFromText(CONCAT('POINT(', ?, ' ', ?, ')'), 4326) ) AS distance_meters FROM osm_points_with_area p WHERE -- استخدام MBRContains للفلترة الأولية السريعة (باستخدام الفهرس المكاني) MBRContains( ST_Buffer(ST_PointFromText(CONCAT('POINT(', ?, ' ', ?, ')'), 4326), 0.01), -- مربع بحث ~ 1 كم p.geom ) -- الترتيب الدقيق حسب المسافة الأقرب (يستخدم الفهرس المكاني بكفاءة) ORDER BY p.geom <-> ST_PointFromText(CONCAT('POINT(', ?, ' ', ?, ')'), 4326) LIMIT 1"; // نريد أقرب نقطة فقط $stmt = $conn->prepare($sql); if ($stmt === false) { echo json_encode(['status' => 'error', 'message' => 'Failed to prepare statement: ' . $conn->error]); $conn->close(); exit; } // ربط المتغيرات (6 متغيرات: lon, lat مرتين للمربع ومرة للمسافة) $stmt->bind_param("dddddd", $input_lon, $input_lat, $input_lon, $input_lat, $input_lon, $input_lat); $stmt->execute(); $result = $stmt->get_result(); // --- تنسيق وإرجاع النتيجة --- if ($result->num_rows > 0) { $row = $result->fetch_assoc(); // استخراج التفاصيل الإضافية من other_tags $name_ar = parseHstoreValue($row['other_tags'], 'name:ar'); $addr_street = parseHstoreValue($row['other_tags'], 'addr:street'); $amenity = parseHstoreValue($row['other_tags'], 'amenity'); $shop = parseHstoreValue($row['other_tags'], 'shop'); // بناء اسم وصفي (الأولوية للعربي إن وجد) $primaryName = $name_ar ?? $row['name'] ?? $addr_street ?? null; // الاسم الأساسي للنقطة $displayName = $primaryName ?? 'موقع قريب'; // اسم افتراضي إذا لم يوجد اسم // إضافة اسم الحي والمدينة (المحسوبة مسبقاً) $addressParts = array_filter([ $row['neighbourhood_name'], $row['city_name'] ]); if (!empty($addressParts)) { // تجنب تكرار اسم المدينة إذا كان هو نفسه اسم النقطة if ($primaryName !== $row['city_name']) { $displayName .= '، ' . implode('، ', $addressParts); } elseif ($row['neighbourhood_name'] && $primaryName !== $row['neighbourhood_name']) { $displayName .= '، ' . $row['neighbourhood_name']; } } // إرجاع النتيجة كـ JSON echo json_encode([ 'status' => 'ok', 'display_name' => $displayName, // الاسم المنسق للعرض 'name' => $row['name'], // الاسم الأصلي (إن وجد) 'name_ar' => $name_ar, // الاسم العربي (إن وجد) 'street' => $addr_street, // اسم الشارع (إن وجد) 'neighbourhood' => $row['neighbourhood_name'], // اسم الحي (المحسوب مسبقاً) 'city' => $row['city_name'], // اسم المدينة (المحسوب مسبقاً) 'amenity' => $amenity, // نوع الخدمة (إن وجد) 'shop' => $shop, // نوع المحل (إن وجد) 'distance_meters' => round($row['distance_meters'], 1) // المسافة لأقرب POI ], JSON_UNESCAPED_UNICODE); // مهم لعرض العربية بشكل صحيح } else { // لم يتم العثور على نقطة قريبة، ابحث عن أقرب مدينة/حي كحل بديل $areaSqlFallback = " SELECT name, other_tags, place_type FROM osm_areas ORDER BY ST_Distance_Sphere(geom, ST_PointFromText(CONCAT('POINT(', ?, ' ', ?, ')'), 4326)) ASC LIMIT 1"; $stmtFallback = $conn->prepare($areaSqlFallback); if ($stmtFallback) { $stmtFallback->bind_param("dd", $input_lon, $input_lat); $stmtFallback->execute(); $fallbackResult = $stmtFallback->get_result()->fetch_assoc(); $stmtFallback->close(); if ($fallbackResult) { $fallbackNameAr = parseHstoreValue($fallbackResult['other_tags'], 'name:ar'); $fallbackDisplayName = $fallbackNameAr ?? $fallbackResult['name'] ?? 'منطقة غير معروفة'; echo json_encode([ 'status' => 'ok', 'display_name' => $fallbackDisplayName, ($fallbackResult['place_type'] === 'city' || $fallbackResult['place_type'] === 'town' || $fallbackResult['place_type'] === 'village') ? 'city' : 'neighbourhood' => $fallbackDisplayName ], JSON_UNESCAPED_UNICODE); } else { echo json_encode(['status' => 'not_found', 'message' => 'No nearby places or areas found']); } } else { echo json_encode(['status' => 'error', 'message' => 'Fallback query failed: ' . $conn->error]); } } $stmt->close(); $conn->close(); ?> ``` ## File: ride/rides/start_ride.php ``` prepare("UPDATE ride SET status = ?, rideTimeStart = NOW() WHERE id = ?"); $stmtRemote->execute([$status, $ride_id]); if ($stmtRemote->rowCount() == 0) { // ملاحظة: أحياناً التحديث لا يؤثر بصفوف إذا كانت البيانات نفسها، // لكن هنا نفترض الفشل إذا لم يجد الرحلة. // يمكنك إكمال التنفيذ إذا كنت متأكداً أن الرحلة موجودة. } // 2. تحديث السيرفر المحلي (Local DB) والمعاملات $con->beginTransaction(); // تحديث الرحلة محلياً $stmtMainRide = $con->prepare("UPDATE ride SET status = ?, rideTimeStart = NOW() WHERE id = ?"); $stmtMainRide->execute([$status, $ride_id]); // تحديث أو إدخال في جدول Driver Orders $checkSql = "SELECT `order_id` FROM `driver_orders` WHERE `order_id` = ?"; $checkStmt = $con->prepare($checkSql); $checkStmt->execute([$ride_id]); if ($checkStmt->rowCount() > 0) { $updateSql = "UPDATE `driver_orders` SET `driver_id` = ?, `status` = ?, `created_at` = NOW() WHERE `order_id` = ?"; $con->prepare($updateSql)->execute([$driver_id, $status, $ride_id]); } else { $insertSql = "INSERT INTO `driver_orders` (`driver_id`, `order_id`, `created_at`, `status`) VALUES (?, ?, NOW(), ?)"; $con->prepare($insertSql)->execute([$driver_id, $ride_id, $status]); } // ================================================================= // 🔥 الخطوة 3: إشعار الراكب (Socket + FCM) // ================================================================= // جلب بيانات الراكب من قاعدة البيانات لضمان الدقة $stmtPas = $con_ride->prepare("SELECT passenger_id FROM ride WHERE id = ?"); $stmtPas->execute([$ride_id]); $passenger_id = $stmtPas->fetchColumn(); if ($passenger_id) { // أ) إرسال السوكيت (Socket) // تم إلغاء التعليق عنه ليكون السيرفر هو المسؤول $socketPayload = [ 'ride_id' => $ride_id, 'status' => 'started', // أو 'Begin' حسب ما يتوقعه التطبيق 'msg' => 'بدأت الرحلة، نتمنى لك سلامة الوصول 🚀' ]; if (function_exists('notifyPassengerOnRideServer')) { notifyPassengerOnRideServer($passenger_id, $socketPayload); } // ب) إرسال FCM (Internal) if (!empty($passengerToken)) { $fcmData = [ 'ride_id' => (string)$ride_id ]; // 🔥 استخدام sendFCM_Internal sendFCM_Internal( $passengerToken, // الهدف "بدأت الرحلة 🏁", // العنوان "نتمنى لك رحلة آمنة ومريحة.", // النص $fcmData, // البيانات "Trip is Begin", // التصنيف (حافظنا عليه كما هو في التطبيق) false // ليس Topic ); } } $con->commit(); jsonSuccess(null, "Ride started successfully"); } catch (PDOException $e) { if ($con->inTransaction()) { $con->rollBack(); } jsonError("Exception: " . $e->getMessage()); } ?> ``` ## File: ride/rides/add.php ``` $start_location, ":end_location" => $end_location, ":date" => $date_formatted, // نستخدم الصيغة المعالجة ":time" => $time_formatted, // نستخدم الصيغة المعالجة ":endtime" => $endtime_formatted, ":price" => $price, ":passenger_id" => $passenger_id, ":driver_id" => $driver_id, ":status" => $status, ":carType" => $carType, ":price_for_driver" => $price_for_driver, ":price_for_passenger" => $price_for_passenger, ":distance" => $distance, ]; // تسجيل البيانات التي سيتم إدخالها للتأكد error_log("ℹ️ [add_ride.php] Prepared Data: " . json_encode($data)); // --------------------------------------------------------- // 3. الإضافة في السيرفر المحلي (Main DB) // --------------------------------------------------------- $sql = "INSERT INTO `ride` ( `start_location`, `end_location`, `date`, `time`, `endtime`, `price`, `passenger_id`, `driver_id`, `status`, `carType`, `price_for_driver`, `price_for_passenger`, `distance` ) VALUES ( :start_location, :end_location, :date, :time, :endtime, :price, :passenger_id, :driver_id, :status, :carType, :price_for_driver, :price_for_passenger, :distance )"; try { error_log("🔄 [add_ride.php] Inserting into LOCAL DB..."); $stmt = $con->prepare($sql); $stmt->execute($data); $insertedId = $con->lastInsertId(); $count = $stmt->rowCount(); error_log("✅ [add_ride.php] Local Insert Success. ID: $insertedId"); if ($count > 0) { // --------------------------------------------------------- // 4. الإضافة في سيرفر التتبع (Tracking DB) // --------------------------------------------------------- $sqlRemote = "INSERT INTO `ride` ( `id`, `start_location`, `end_location`, `date`, `time`, `endtime`, `price`, `passenger_id`, `driver_id`, `status`, `carType`, `price_for_driver`, `price_for_passenger`, `distance` ) VALUES ( :id, :start_location, :end_location, :date, :time, :endtime, :price, :passenger_id, :driver_id, :status, :carType, :price_for_driver, :price_for_passenger, :distance )"; // إضافة الـ ID للمصفوفة $data[':id'] = $insertedId; try { error_log("🔄 [add_ride.php] Inserting into REMOTE DB..."); $stmtRemote = $con_ride->prepare($sqlRemote); $stmtRemote->execute($data); error_log("✅ [add_ride.php] Remote Insert Success."); } catch (PDOException $eRemote) { // نسجل خطأ الريموت لكن لا نوقف العملية لأن اللوكل تم بنجاح error_log("⚠️ [add_ride.php] Remote DB Error: " . $eRemote->getMessage()); } // طباعة النجاح (JSON صحيح) jsonSuccess($insertedId); } else { error_log("❌ [add_ride.php] Failed to insert locally (Rows affected 0)."); jsonError("Failed to save ride information locally"); } } catch (PDOException $e) { // تسجيل الخطأ بدقة error_log("❌ [add_ride.php] SQL Error: " . $e->getMessage()); jsonError("Database Error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/updateStausFromSpeed.php ``` prepare("UPDATE `ride` SET `status` = :status, `driver_id` = :driverId, `rideTimeStart` = NOW() WHERE `id` = :id AND `status` IN ('waiting', 'wait') "); $stmtRideRemote->execute([ ':status' => $status, ':driverId' => $driverId, ':id' => $rideId ]); $count = $stmtRideRemote->rowCount(); error_log("ℹ️ [accept_ride.php] Remote DB Rows Affected: $count"); // نتحقق: هل نجح التحديث في سيرفر التتبع؟ if ($count > 0) { // --------------------------------------------------------- // 2. التحديث على السيرفر الرئيسي (تثبيت السجل فقط) // --------------------------------------------------------- error_log("🔄 [accept_ride.php] Remote success. Updating LOCAL Main DB..."); $sqlUpdate = "UPDATE `ride` SET `driver_id` = :driverId, `status` = :status, `rideTimeStart` = NOW() WHERE id = :rideId AND `status` IN ('waiting', 'wait') "; $stmtUpdate = $con->prepare($sqlUpdate); $stmtUpdate->bindParam(":driverId", $driverId); $stmtUpdate->bindParam(":status", $status); $stmtUpdate->bindParam(":rideId", $rideId); $stmtUpdate->execute(); error_log("✅ [accept_ride.php] Ride accepted and started successfully for Driver: $driverId"); jsonSuccess(null, "Ride accepted and started successfully at " . date('Y-m-d H:i:s')); } else { error_log("⚠️ [accept_ride.php] Failed to accept ride. It might be already taken, canceled, or invalid status."); jsonError("Ride cannot be accepted (Already taken, Canceled, or Invalid Status)."); } } catch (PDOException $e) { error_log("❌ [accept_ride.php] Database Error: " . $e->getMessage()); jsonError("Database Error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/gterideForDriverManyTime.php ``` prepare($sql); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); echo json_encode([ "status" => "success", "data" => $row ]); ?> ``` ## File: ride/rides/getRideStatusFromStartApp.php ``` prepare(" SELECT id AS rideId, status, start_location, end_location, carType, driver_id,distance, price, created_at FROM ride WHERE passenger_id = ? AND ( status IN ( 'Apply', 'Begin') AND created_at >= NOW() - INTERVAL 2 HOUR OR (status = 'Finished' AND created_at >= NOW() - INTERVAL 24 HOUR) ) ORDER BY created_at DESC LIMIT 1 "); $stmt->execute([$passenger_id]); $ride = $stmt->fetch(PDO::FETCH_ASSOC); if (!$ride) { echo json_encode(["status" => "failure", "message" => "No active ride found"]); exit; } // ========================================================= // 2. السيرفر الرئيسي: جلب اسم السائق + متوسط تقييمه العام // ========================================================= // ملاحظة: تم الحفاظ على الاستعلام كما هو // rateDriver: هو الاسم الذي سنستخدمه في PHP $stmt2 = $con->prepare(" SELECT d.first_name AS driverName, (SELECT AVG(rating) FROM ratingDriver WHERE driver_id = d.id) AS rateDriver, (SELECT COUNT(*) FROM ratingDriver WHERE ride_id = ?) AS thisRideRated FROM driver d WHERE d.id = ? "); $stmt2->execute([$ride['rideId'], $ride['driver_id']]); $driverData = $stmt2->fetch(PDO::FETCH_ASSOC); // ========================================================= // 3. المعالجة النهائية // ========================================================= if ($driverData) { // فك التشفير $ride['driverName'] = $encryptionHelper->decryptData($driverData['driverName']); // --- تصحيح الخطأ هنا --- // كان يستدعي driverAvg وهو غير موجود، تم تغييره لـ rateDriver $ride['rateDriver'] = $driverData['rateDriver'] ? round($driverData['rateDriver'], 2) : 5; // --- منطق هل تحتاج الرحلة لتقييم (needsReview) --- $isFinished = ($ride['status'] === 'Finished'); $isRated = ($driverData['thisRideRated'] > 0); $ride['needsReview'] = ($isFinished && !$isRated) ? 1 : 0; } else { // حالة عدم وجود سائق (نادراً ما تحدث إذا كان driver_id موجوداً في جدول الرحلات) $ride['driverName'] = null; $ride['rateDriver'] = 5; $ride['needsReview'] = 0; } // تنظيف البيانات unset($ride['created_at']); echo json_encode([ "status" => "success", "data" => $ride ]); } catch (Exception $e) { echo json_encode(["status" => "failure", "message" => $e->getMessage()]); } ?> ``` ## File: ride/rides/update.php ``` $id]; // قائمة الحقول القابلة للتحديث $fields = [ "start_location", "end_location", "date", "time", "endtime", "price", "passenger_id", "driver_id", "status", "created_at", "updated_at", "rideTimeStart", "rideTimeFinish", "price_for_driver", "driverGoToPassengerTime", "price_for_passenger", "distance" ]; // بناء الاستعلام ديناميكياً باستخدام filterRequest foreach ($fields as $field) { // نتحقق من وجود المفتاح في الـ POST if (isset($_POST[$field])) { // نستخدم دالة الفلترة الخاصة بك $value = filterRequest($field); $columnValues[] = "`$field` = :$field"; $params[":$field"] = $value; } } // إذا لم يتم إرسال أي حقول للتحديث if (empty($columnValues)) { error_log("⚠️ [update.php] No data provided in request to update."); jsonError("No data provided for update."); exit; } // تجميع جملة SQL $setClause = implode(", ", $columnValues); $sql = "UPDATE `ride` SET $setClause WHERE `id` = :id"; try { // --------------------------------------------------------- // 1. التحديث على سيرفر التتبع (Remote DB) - هو الأساس // --------------------------------------------------------- error_log("🔄 [update.php] Attempting to update REMOTE Tracking DB for Ride ID: $id"); $stmtRemote = $con_ride->prepare($sql); $stmtRemote->execute($params); $count = $stmtRemote->rowCount(); error_log("ℹ️ [update.php] Remote DB Rows Affected: $count"); // التحقق: هل نجح التحديث هناك؟ if ($count > 0) { // --------------------------------------------------------- // 2. التحديث على السيرفر المحلي (Local DB) للمطابقة // --------------------------------------------------------- error_log("🔄 [update.php] Remote success. Updating LOCAL Main DB..."); $stmtLocal = $con->prepare($sql); $stmtLocal->execute($params); error_log("✅ [update.php] Update successful on both servers."); // استخدام دالة النجاح الخاصة بك jsonSuccess(null, "Ride data updated successfully"); } else { // لم يتم التحديث (إما البيانات نفسها لم تتغير، أو المعرف غير موجود في السيرفر البعيد) error_log("⚠️ [update.php] Remote Update returned 0 rows (Data same or ID not found)."); // استخدام دالة الفشل (يمكنك تغيير الرسالة لتكون success إذا كنت لا تعتبر عدم تغيير البيانات خطأ) jsonError("No changes made (Remote DB affected 0 rows). Check ID or Data."); } } catch (PDOException $e) { error_log("❌ [update.php] Database Error: " . $e->getMessage()); jsonError("Database Error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/cancel_ride_by_passenger.php ``` prepare("SELECT driver_id, status FROM ride WHERE id = ?"); $stmt->execute([$rideId]); $ride = $stmt->fetch(PDO::FETCH_ASSOC); if (!$ride) { jsonError("Ride not found"); exit; } $driverId = $ride['driver_id']; $currentStatus = $ride['status']; if ($currentStatus == 'Begin') { jsonError("Cannot cancel started ride"); exit; } // ================================================================= // 1. تحديث قواعد البيانات (Transaction) // ================================================================= $con->beginTransaction(); // تحديث waitingRides $updateWaiting = $con->prepare("UPDATE waitingRides SET status = ? WHERE id = ?"); $updateWaiting->execute(['cancelled_by_passenger', $rideId]); // تحديث ride (محلي) $updateRide = $con->prepare("UPDATE ride SET status = ?, updated_at = NOW() WHERE id = ?"); $updateRide->execute(['cancelled_by_passenger', $rideId]); // تحديث driver_orders if ($driverId > 0) { $updateOrder = $con->prepare("UPDATE driver_orders SET status = 'cancelled_by_passenger', notes = ? WHERE order_id = ? AND driver_id = ?"); $updateOrder->execute([$reason, $rideId, $driverId]); } $con->commit(); // تحديث السيرفر البعيد (Remote DB) if (isset($con_ride)) { try { $updateRide2 = $con_ride->prepare("UPDATE ride SET status = ?, updated_at = NOW() WHERE id = ?"); $updateRide2->execute(['cancelled_by_passenger', $rideId]); } catch (PDOException $e) { error_log("Secondary DB update failed: " . $e->getMessage()); } } // ================================================================= // 2. إشعار السائق (Socket + FCM) // ================================================================= if ($driverId > 0) { // أ) Socket (إشعار السائق في التطبيق فوراً) $socketUrl = 'http://188.68.36.205:2021'; $internalKeyPath = '/home/siro-api/.internal_socket_key'; $internalKey = file_exists($internalKeyPath) ? trim(file_get_contents($internalKeyPath)) : ''; $ch = curl_init($socketUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'action' => 'cancel_ride', 'driver_id' => $driverId, 'ride_id' => $rideId, 'reason' => $reason ])); if (!empty($internalKey)) curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $internalKey"]); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 500); curl_setopt($ch, CURLOPT_NOSIGNAL, 1); @curl_exec($ch); curl_close($ch); // ب) FCM (باستخدام الدالة الجديدة مع فك التشفير) $stmtToken = $con->prepare("SELECT token FROM driverToken WHERE captain_id = ?"); $stmtToken->execute([$driverId]); $rawToken = $stmtToken->fetchColumn(); if ($rawToken) { $driverToken = $rawToken; // 🔥 محاولة فك التشفير (لأن التوكنات غالباً مشفرة) if (!empty($encryptionHelper)) { try { $decrypted = $encryptionHelper->decryptData($rawToken); if ($decrypted !== false && !empty($decrypted)) { $driverToken = trim($decrypted); } } catch (Exception $e) { // في حال الفشل نستخدم الخام } } // تجهيز البيانات $fcmData = [ 'category' => 'Cancel Trip', 'ride_id' => (string)$rideId, 'reason' => $reason ]; // إرسال الإشعار sendFCM_Internal( $driverToken, // الهدف "إلغاء الرحلة 🚫", // العنوان "قام الراكب بإلغاء الرحلة: $reason", // النص $fcmData, // البيانات 'Cancel Trip', // التصنيف false // ليس Topic ); } } jsonSuccess(null, "Ride cancelled successfully"); } catch (PDOException $e) { if ($con->inTransaction()) $con->rollBack(); error_log("Cancel ride error: " . $e->getMessage()); jsonError("Database error occurred"); } ?> ``` ## File: ride/rides/get.php ``` prepare($baseSql); $stmt->execute($params); $row = $stmt->fetch(PDO::FETCH_ASSOC); $total_rows = $row['total_rows'] ?? 0; if ($total_rows > 0) { // Step 2: Fetch the latest 10 ride records $rideSql = "SELECT * FROM `ride`"; if (!empty($passenger_id)) { $rideSql .= " WHERE passenger_id = :passenger_id ORDER BY created_at DESC LIMIT 10"; } elseif (!empty($driver_id)) { $rideSql .= " WHERE driver_id = :driver_id ORDER BY created_at DESC LIMIT 10"; } $rideStmt = $con->prepare($rideSql); $rideStmt->execute($params); $rides = $rideStmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode([ "status" => "success", "data" => $rides ]); } else { jsonError("No rides found"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/get_driver_location.php ``` "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"); // إعادة بناء الهاش للمقارنة $generatedToken = md5($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"]); } ?> ``` ## File: ride/rides/update_ride_cancel_wait.php ``` beginTransaction(); // 1. تحديث جدول الرحلات $stmtRide = $con->prepare("UPDATE ride SET status = ?, rideTimeStart = NOW() WHERE id = ?"); $stmtRide->execute([$status, $rideId]); // 2. تحديث جدول طلبات السائقين // نستخدم Check لضمان عدم تكرار التحديث إذا كان محدثاً مسبقاً $stmtOrder = $con->prepare("UPDATE driver_orders SET status = ? WHERE order_id = ? AND driver_id = ?"); $stmtOrder->execute([$status, $rideId, $driverId]); $con->commit(); jsonSuccess(null, "Ride status updated"); } catch (PDOException $e) { $con->rollBack(); jsonError("DB Error"); } ?> ``` ## File: ride/rides/updateRideAndCheckIfApplied.php ``` prepare($sqlCheck); $stmtCheck->bindParam(":rideId", $rideId); $stmtCheck->execute(); $ride = $stmtCheck->fetch(PDO::FETCH_ASSOC); if (!$ride) { jsonError("Ride not found."); exit; } if ($ride['status'] === 'Apply') { jsonError("This ride is already applied by another driver."); exit; } // Step 2: تحديث حالة الرحلة وربط السائق بها $sqlUpdate = "UPDATE `ride` SET `driver_id` = :driverId, `status` = 'Apply', `rideTimeStart` = :rideTimeStart WHERE `id` = :rideId"; $stmtUpdate = $con->prepare($sqlUpdate); $stmtUpdate->bindParam(":driverId", $driverId); $stmtUpdate->bindParam(":rideTimeStart", $rideTimeStart); $stmtUpdate->bindParam(":rideId", $rideId); $stmtUpdate->execute(); if ($stmtUpdate->rowCount() > 0) { jsonSuccess(null, "Ride data updated successfully"); // يمكنك هنا إرسال إشعار للسائقين الآخرين إذا أردت // FirebaseMessagesController()->sendNotificationToOtherDrivers(...) } else { jsonError("Failed to update ride data."); } ?> ``` ## File: ride/rides/retry_search_drivers.php ``` prepare("UPDATE ride SET status = 'waiting', driver_id = 0, updated_at = NOW() WHERE id = ?"); $updateStmt->execute([$rideId]); // 3. حساب العمولة (Kazan) $kazan = (double)$price - (double)$priceForDriver; // 4. بناء Payload مطابق لـ add_ride.php (0 - 33) $payloadTemplate = []; $payloadTemplate[0] = (string)$startLat; $payloadTemplate[1] = (string)$startLng; $payloadTemplate[2] = (string)number_format((float)$price, 2, '.', ''); $payloadTemplate[3] = (string)$endLat; $payloadTemplate[4] = (string)$endLng; $payloadTemplate[5] = (string)$distanceText; $payloadTemplate[6] = ""; // Driver ID placeholder $payloadTemplate[7] = (string)$passengerId; $payloadTemplate[8] = (string)$passengerName; $payloadTemplate[9] = (string)$passengerToken; $payloadTemplate[10] = (string)$passengerPhone; $payloadTemplate[11] = (string)$distance; $payloadTemplate[12] = "1"; $payloadTemplate[13] = (string)$isWallet; $payloadTemplate[14] = (string)$distance; $payloadTemplate[15] = (string)$durationText; $payloadTemplate[16] = (string)$rideId; $payloadTemplate[17] = ""; $payloadTemplate[18] = ""; // Driver ID placeholder $payloadTemplate[19] = (string)$durationText; $payloadTemplate[20] = (string)$hasSteps; $payloadTemplate[21] = (string)$step0; $payloadTemplate[22] = (string)$step1; $payloadTemplate[23] = (string)$step2; $payloadTemplate[24] = (string)$step3; $payloadTemplate[25] = (string)$step4; $payloadTemplate[26] = (string)number_format((float)$priceForDriver, 2, '.', ''); $payloadTemplate[27] = (string)$passengerWallet; $payloadTemplate[28] = (string)$passengerEmail; $payloadTemplate[29] = (string)$startName; $payloadTemplate[30] = (string)$endName; $payloadTemplate[31] = (string)$carType; $payloadTemplate[32] = (string)number_format($kazan, 2, '.', ''); $payloadTemplate[33] = (string)$passengerRating; ksort($payloadTemplate); $payloadTemplate = array_values($payloadTemplate); // 5. البحث عن السائقين وإرسال الطلب (Using Helper Function) $latVal = doubleval($startLat); $lngVal = doubleval($startLng); $driversData = findBestDrivers($con, $con_tracking, $latVal, $lngVal, $carType); if (!empty($driversData)) { // استدعاء دالة الإرسال الموحدة (الموجودة في functions.php) dispatchRideToDrivers($driversData, $rideId, $payloadTemplate, $startName); } jsonSuccess(null, "Ride reset and resent to drivers"); } catch (PDOException $e) { jsonError("DB Error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/acceptRide.php ``` prepare(" UPDATE `ride` SET `status` = ?, `driver_id` = ?, `rideTimeStart` = NOW() WHERE `id` = ? AND `status` IN ('waiting', 'wait') "); $stmtRemote->execute([$status, $driverId, $rideId]); // Check if the update actually changed a row. // If rowCount > 0, IT MEANS SUCCESS! This driver won the ride. if ($stmtRemote->rowCount() > 0) { // 4. Synchronization: Update Local Database // Now that we secured the ride, we update the main server's DB ($con) to match. if (isset($con)) { $stmtLocal = $con->prepare("UPDATE `ride` SET `driver_id` = ?, `status` = ?, `rideTimeStart` = NOW() WHERE id = ?"); $stmtLocal->execute([$driverId, $status, $rideId]); } // 5. Update/Insert Driver Orders Table // This tracks the driver's history or active orders. $checkSql = "SELECT `order_id` FROM `driver_orders` WHERE `order_id` = ?"; $checkStmt = $con->prepare($checkSql); $checkStmt->execute([$rideId]); if ($checkStmt->rowCount() > 0) { // If entry exists, update it $updateSql = "UPDATE `driver_orders` SET `driver_id` = ?, `status` = ?, `created_at` = NOW() WHERE `order_id` = ?"; $con->prepare($updateSql)->execute([$driverId, $status, $rideId]); } else { // If not, insert new record $insertSql = "INSERT INTO `driver_orders` (`driver_id`, `order_id`, `created_at`, `status`) VALUES (?, ?, NOW(), ?)"; $con->prepare($insertSql)->execute([$driverId, $rideId, $status]); } // ================================================================= // 6. 👤 GET DRIVER INFO (For the Passenger) // We need to fetch driver details (Car, Name, Rating) to show to the passenger. // ================================================================= $driverInfo = []; $sqlDetails = "SELECT d.id as driver_id, d.first_name, d.last_name, d.gender, d.phone, c.make, c.model, c.car_plate, c.year, c.color, c.color_hex, (SELECT ROUND(AVG(rating), 2) FROM ratingDriver WHERE driver_id = d.id) AS ratingDriver, dt.token FROM driver d LEFT JOIN CarRegistration c ON c.driverID = d.id LEFT JOIN driverToken dt ON dt.captain_id = d.id WHERE d.id = ?"; $stmtDetails = $con->prepare($sqlDetails); $stmtDetails->execute([$driverId]); $driverRawData = $stmtDetails->fetch(PDO::FETCH_ASSOC); if ($driverRawData) { // List of encrypted fields that need decryption $fieldsToDecrypt = ['first_name', 'last_name', 'gender', 'phone', 'car_plate', 'token']; foreach ($driverRawData as $key => $value) { if (in_array($key, $fieldsToDecrypt) && !empty($value)) { // Decrypt sensitive data $driverInfo[$key] = $encryptionHelper->decryptData($value); } else { $driverInfo[$key] = $value; } } // Format Full Name $driverInfo['driverName'] = trim(($driverInfo['first_name'] ?? '') . ' ' . ($driverInfo['last_name'] ?? '')); // Default rating if null if (empty($driverInfo['ratingDriver'])) { $driverInfo['ratingDriver'] = "5.0"; } } // ================================================================= // 7. 🔔 NOTIFY PASSENGER (Socket + FCM) // Inform the passenger that a driver has been found. // ================================================================= // Fetch Passenger ID based on Ride ID $stmtPas = $con->prepare("SELECT passenger_id FROM ride WHERE id = ?"); $stmtPas->execute([$rideId]); $passenger_id = $stmtPas->fetchColumn(); if ($passenger_id) { // A. Send Socket Notification (Real-time update on map) if (function_exists('notifyPassengerOnRideServer')) { notifyPassengerOnRideServer($passenger_id, [ 'status' => 'accepted', 'ride_id' => $rideId, 'driver_id' => $driverId, 'driver_info' => $driverInfo ]); } // B. Send FCM Notification (Push Notification) if (!empty($passengerToken)) { // Using the standardized FCM function sendFCM_Internal( $passengerToken, "Ride Accepted 🚖", // Title "Captain " . ($driverInfo['driverName'] ?? 'Driver') . " is coming to you.", // Body ['ride_id' => (string)$rideId, 'driver_info' => $driverInfo], // Data Payload "Accepted Ride", // Category false // Not a topic ); } } // ================================================================= // 8. 🧹 MARKETPLACE CLEANUP (Notify Location Server) // Crucial Step: We tell the Location Server that this ride is taken. // The Location Server will: // 1. Remove the ride from Redis (geo:rides:waiting). // 2. Broadcast 'ride_taken' to other drivers to remove it from their screens. // ================================================================= sendToLocationServer('ride_taken_event', [ 'ride_id' => $rideId, 'taken_by_driver_id' => $driverId ]); // 9. Final Response to the Driver App echo json_encode([ "status" => "success", "message" => "Ride Accepted", "data" => $driverInfo ]); } else { // Failure: This means rowCount was 0. // Reason: The ride status was NOT 'waiting' (another driver took it milliseconds ago). jsonError("Ride not available (Already taken)"); } } catch (Exception $e) { // Handle unexpected errors jsonError("Error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/heatmap_live.json ``` [] ``` ## File: ride/rides/getRealTimeHeatmap.php ``` prepare("SELECT start_lat, start_lng FROM waitingRides WHERE status IN ('wait', 'waiting')"); $stmtW->execute(); while ($row = $stmtW->fetch(PDO::FETCH_ASSOC)) { addToGrid($grid, $row['start_lat'], $row['start_lng'], $precision, $WEIGHT_WAITING); } // 2. طلبات ضائعة (Timeout) $stmtM = $con->prepare("SELECT start_location FROM ride WHERE (status = 'timeout' OR status = 'cancelled_no_driver_found') AND created_at >= DATE_SUB(NOW(), INTERVAL 20 MINUTE)"); $stmtM->execute(); while ($row = $stmtM->fetch(PDO::FETCH_ASSOC)) { $parts = explode(',', $row['start_location']); if (count($parts) == 2) addToGrid($grid, $parts[0], $parts[1], $precision, $WEIGHT_MISSED); } // 3. طلبات نشطة (Active) $stmtA = $con->prepare("SELECT start_location FROM ride WHERE created_at >= DATE_SUB(NOW(), INTERVAL 15 MINUTE) AND status NOT IN ('timeout', 'cancelled_no_driver_found')"); $stmtA->execute(); while ($row = $stmtA->fetch(PDO::FETCH_ASSOC)) { $parts = explode(',', $row['start_location']); if (count($parts) == 2) addToGrid($grid, $parts[0], $parts[1], $precision, $WEIGHT_ACTIVE); } // تجهيز البيانات النهائية $finalData = []; foreach ($grid as $cell) { $score = $cell['score']; // مجموع النقاط (الوزن) $count = $cell['count']; // العدد الحقيقي للطلبات // 🧠 المنطق المزدوج: نحدد اللون بناءً على النقاط أو العدد $intensity = "low"; $surge = 1.0; // المعادلة: منطقة حمراء إذا كان السكور عالي جداً (مشاكل) أو العدد كبير جداً (زحمة) if ($score >= 15 || $count >= 5) { $intensity = "high"; // أحمر (خطر/فرصة ذهبية) $surge = 1.5; } elseif ($score >= 8 || $count >= 3) { $intensity = "medium"; // برتقالي $surge = 1.2; } elseif ($score >= 3 || $count >= 1) { $intensity = "normal"; // أصفر } if ($score > 0) { $finalData[] = [ 'lat' => $cell['lat'], 'lng' => $cell['lng'], 'count' => $count, // ✅ العدد الحقيقي (مهم للعرض) 'intensity' => $intensity, // ✅ التصنيف الذكي 'surge' => $surge ]; } } file_put_contents('heatmap_live.json', json_encode($finalData)); // الكاش echo json_encode(["status" => "success", "data" => $finalData]); } catch (Exception $e) { echo json_encode(["status" => "failure", "message" => $e->getMessage()]); } function addToGrid(&$grid, $lat, $lng, $precision, $weight) { if (empty($lat) || empty($lng)) return; $rLat = round(floatval($lat), $precision); $rLng = round(floatval($lng), $precision); $key = "$rLat,$rLng"; if (!isset($grid[$key])) { $grid[$key] = ['lat' => $rLat, 'lng' => $rLng, 'count' => 0, 'score' => 0]; } $grid[$key]['count']++; // زيادة العدد (+1 دائماً) $grid[$key]['score'] += $weight; // زيادة الوزن (حسب نوع الطلب) } ?> ``` ## File: ride/rides/getTripCountByCaptain.php ``` prepare($sql); $stmt->bindParam(':driver_id', $driver_id, PDO::PARAM_INT); // أو PARAM_STR حسب نوع الـ ID $stmt->execute(); if ($stmt->rowCount() > 0) { $row = $stmt->fetch(PDO::FETCH_ASSOC); jsonSuccess($row); } else { jsonError($message = "No finished ride records found for this driver"); } ?> ``` ## File: ride/rides/arrive_ride.php ``` prepare("UPDATE ride SET status = 'arrived', updated_at = NOW() WHERE id = ? AND driver_id = ? AND status = 'Apply'"); $stmtRemote->execute([$rideId, $driverId]); // 2. تحديث الحالة في السيرفر المحلي (Local DB - con) if (isset($con)) { $stmtLocal = $con->prepare("UPDATE ride SET status = 'arrived', updated_at = NOW() WHERE id = ? AND driver_id = ? AND status = 'Apply'"); $stmtLocal->execute([$rideId, $driverId]); } // 3. جلب بيانات الراكب للإرسال // نستخدم con_ride لضمان الدقة $stmtPas = $con_ride->prepare("SELECT passenger_id FROM ride WHERE id = ?"); $stmtPas->execute([$rideId]); $passenger_id = $stmtPas->fetchColumn(); if ($passenger_id) { // أ) إرسال Socket (الأسرع) $payload = [ 'status' => 'arrived', 'ride_id' => $rideId, 'msg' => 'السائق وصل إلى موقعك 🚖' ]; if (function_exists('notifyPassengerOnRideServer')) { notifyPassengerOnRideServer($passenger_id, $payload); } // ب) إرسال FCM (باستخدام الدالة الجديدة) if (!empty($passengerToken)) { $fcmData = [ 'category' => 'Arrive Ride', // نفس الاسم القديم لضمان عمل التطبيق 'ride_id' => (string)$rideId ]; // 🔥 استخدام sendFCM_Internal sendFCM_Internal( $passengerToken, // الهدف "السائق وصل 📍", // العنوان "الكابتن ينتظرك في الموقع المحدد.", // النص $fcmData, // البيانات "Arrive Ride", // التصنيف false // ليس Topic ); } } jsonSuccess(null, "Arrival notified successfully"); } catch (Exception $e) { jsonError("Error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/add_ride.php ``` (string)$rideId, 'start_lat' => $lat, 'start_lng' => $lng, 'price' => $payloadData[2], // السعر 'carType' => $payloadData[31], // نوع السيارة 'startName' => $payloadData[29], // اسم موقع البدء 'endName' => $payloadData[30], // اسم موقع الوصول 'distance' => $payloadData[11], // المسافة 'duration' => $payloadData[15], // الوقت 'passengerRate' => $payloadData[33], // تقييم الراكب // يمكنك إضافة المزيد هنا حسب الحاجة ]; $postData = [ 'action' => 'market_new_ride', // اسم الحدث في السوكيت 'payload' => $marketPayload ]; // إرسال الطلب (cURL) $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // وقت انتظار قصير جداً (200ms) لأننا لا نريد تأخير استجابة الراكب curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $INTERNAL_KEY"]); curl_exec($ch); curl_close($ch); } // ================================================================================= // 2. استقبال وتصفية البيانات من التطبيق // ================================================================================= $start_location = filterRequest("start_location"); $end_location = filterRequest("end_location"); $date_raw = filterRequest("date"); $time_raw = filterRequest("time"); $endtime_raw = filterRequest("endtime"); $price = filterRequest("price"); $passenger_id = filterRequest("passenger_id"); $driver_id = filterRequest("driver_id") ?: 0; $status = filterRequest("status"); $price_for_driver = filterRequest("price_for_driver"); $price_for_passenger = filterRequest("price_for_passenger"); $distance = filterRequest("distance"); $carType = filterRequest("carType"); // بيانات الراكب الإضافية $passenger_name = filterRequest("passenger_name"); $passenger_phone = filterRequest("passenger_phone"); $passenger_token = filterRequest("passenger_token"); $passenger_email = filterRequest("passenger_email"); $passenger_wallet = filterRequest("passenger_wallet"); $passenger_rating = filterRequest("passenger_rating"); // تفاصيل الرحلة والنصوص $start_name_loc = filterRequest("start_name"); $end_name_loc = filterRequest("end_name"); $duration_text = filterRequest("duration_text"); $distance_text = filterRequest("distance_text"); $is_wallet = filterRequest("is_wallet"); $has_steps = filterRequest("has_steps"); $step0 = filterRequest("step0"); $step1 = filterRequest("step1"); $step2 = filterRequest("step2"); $step3 = filterRequest("step3"); $step4 = filterRequest("step4"); // معالجة الإحداثيات (فصل النص إلى Lat/Lng) $startLat = ""; $startLng = ""; if (!empty($start_location)) { $parts = explode(',', $start_location); $startLat = trim($parts[0] ?? ""); $startLng = trim($parts[1] ?? ""); } $endLat = ""; $endLng = ""; if (!empty($end_location)) { $parts = explode(',', $end_location); $endLat = trim($parts[0] ?? ""); $endLng = trim($parts[1] ?? ""); } // تنسيق التواريخ $date_formatted = date("Y-m-d", strtotime($date_raw)); $time_formatted = date("H:i:s", strtotime($time_raw)); $endtime_formatted = $endtime_raw ? date("H:i:s", strtotime($endtime_raw)) : "00:00:00"; // مصفوفة البيانات للإدخال $data = [ ":start_location" => $start_location, ":end_location" => $end_location, ":date" => $date_formatted, ":time" => $time_formatted, ":endtime" => $endtime_formatted, ":price" => $price, ":passenger_id" => $passenger_id, ":driver_id" => $driver_id, ":status" => $status, ":carType" => $carType, ":price_for_driver" => $price_for_driver, ":price_for_passenger" => $price_for_passenger, ":distance" => $distance, ]; // جملة SQL للإدخال $sql = "INSERT INTO `ride` ( `start_location`, `end_location`, `date`, `time`, `endtime`, `price`, `passenger_id`, `driver_id`, `status`, `carType`, `price_for_driver`, `price_for_passenger`, `distance` ) VALUES ( :start_location, :end_location, :date, :time, :endtime, :price, :passenger_id, :driver_id, :status, :carType, :price_for_driver, :price_for_passenger, :distance )"; try { // 3. الإدخال في قاعدة البيانات الرئيسية (Main DB) $stmtMain = $con->prepare($sql); $stmtMain->execute($data); $insertedId = $con->lastInsertId(); // ID الرحلة الجديد // 4. الإدخال في قاعدة بيانات الرحلات (Ride DB) للأرشفة والتزامن try { $stmtRide = $con_ride->prepare($sql); $stmtRide->execute($data); } catch (Exception $e) { error_log("⚠️ RideDB Insert Warning: " . $e->getMessage()); } if ($insertedId) { error_log("📝 Ride #$insertedId added successfully."); // 5. تجهيز الـ Payload (قائمة البيانات للتطبيق) $kazan = (double)$price - (double)$price_for_driver; $payloadTemplate = []; // تعبئة البيانات بالترتيب الذي يتوقعه التطبيق (Indices 0-33) $payloadTemplate[0] = (string)$startLat; $payloadTemplate[1] = (string)$startLng; $payloadTemplate[2] = (string)number_format($price, 2, '.', ''); $payloadTemplate[3] = (string)$endLat; $payloadTemplate[4] = (string)$endLng; $payloadTemplate[5] = (string)$distance_text; $payloadTemplate[6] = ""; $payloadTemplate[7] = (string)$passenger_id; $payloadTemplate[8] = (string)$passenger_name; $payloadTemplate[9] = (string)$passenger_token; $payloadTemplate[10] = (string)$passenger_phone; $payloadTemplate[11] = (string)$distance; $payloadTemplate[12] = "1"; $payloadTemplate[13] = (string)$is_wallet; $payloadTemplate[14] = (string)$distance; $payloadTemplate[15] = (string)$duration_text; $payloadTemplate[16] = (string)$insertedId; $payloadTemplate[17] = ""; $payloadTemplate[18] = ""; $payloadTemplate[19] = (string)$duration_text; $payloadTemplate[20] = $has_steps ?: 'false'; $payloadTemplate[21] = (string)$step0; $payloadTemplate[22] = (string)$step1; $payloadTemplate[23] = (string)$step2; $payloadTemplate[24] = (string)$step3; $payloadTemplate[25] = (string)$step4; $payloadTemplate[26] = (string)number_format($price_for_driver, 2, '.', ''); $payloadTemplate[27] = (string)$passenger_wallet; $payloadTemplate[28] = (string)$passenger_email; $payloadTemplate[29] = (string)$start_name_loc; $payloadTemplate[30] = (string)$end_name_loc; $payloadTemplate[31] = (string)$carType; $payloadTemplate[32] = (string)number_format($kazan, 2, '.', ''); $payloadTemplate[33] = (string)$passenger_rating; ksort($payloadTemplate); $payloadTemplate = array_values($payloadTemplate); // 6. البحث عن السائقين للتوزيع المباشر (Direct Dispatch) $driversData = findBestDrivers($con, $startLat, $startLng, $carType); // متغير لنعرف هل وجدنا سائقين للتوجيه المباشر أم لا $foundDirectDrivers = false; if (!empty($driversData)) { // أ. إرسال إشعار مباشر للسائقين المختارين dispatchRideToDrivers($driversData, $insertedId, $payloadTemplate, $start_name_loc, $encryptionHelper); error_log("📨 Dispatched Ride #$insertedId to " . count($driversData) . " drivers."); $foundDirectDrivers = true; } else { error_log("⚠️ No specific drivers found for Direct Dispatch for Ride #$insertedId. Moved to Market only."); } // ب. 🔥 نشر الرحلة في السوق المفتوح (Marketplace) دائماً 🔥 // هذا هو طوق النجاة: حتى لو لم نجد سائقين أعلاه، نضعها في السوق broadcastRideToMarket($insertedId, $startLat, $startLng, $payloadTemplate); // ج. ✅ إرجاع نجاح للتطبيق دائماً (ليبقى الراكب في شاشة البحث) // يمكنك إرسال معلومة إضافية للتطبيق أن البحث "عام" وليس "مباشر" إذا أردت jsonSuccess($insertedId); // ملاحظة: قمنا بإزالة كود الإلغاء (UPDATE ride SET status = 'cancelled...') // لأننا نريد منح الفرصة للسائقين البعيدين قليلاً أو الذين فتحوا التطبيق للتو /* else { // 🛑 حالة عدم العثور على سائقين error_log("⚠️ No drivers found for Ride #$insertedId."); // أ. إلغاء الرحلة فوراً في قواعد البيانات // ملاحظة: غيرنا الحالة إلى رسالة واضحة $con->prepare("UPDATE ride SET status = 'cancelled_no_driver_found' WHERE id = ?")->execute([$insertedId]); $con_ride->prepare("UPDATE ride SET status = 'cancelled_no_driver_found' WHERE id = ?")->execute([$insertedId]); // ب. إشعار الراكب عبر السوكيت (لإظهار Popup) if (function_exists('notifyPassengerSocket')) { notifyPassengerSocket($passenger_id, 'no_drivers_found', [ 'ride_id' => $insertedId, 'message' => 'No drivers available nearby' ]); } // ج. إرجاع فشل للتطبيق jsonError("no_drivers_found"); */ } else { jsonError("Failed to add ride"); } } catch (Exception $e) { error_log("AddRide Critical Error: " . $e->getMessage()); jsonError("Database Error"); } ?> ``` ## File: ride/rides/cancelRideFromDriver.php ``` prepare($sql); $stmtRemote->execute([$newStatus, $id]); $count = $stmtRemote->rowCount(); error_log("ℹ️ [cancelRide.php] Remote DB Rows Affected: $count"); // التحقق: هل تم التحديث؟ if ($count > 0) { // --------------------------------------------------------- // 2. التحديث على السيرفر المحلي (Local DB) // --------------------------------------------------------- // نبدأ معاملة لضمان تكامل البيانات if (isset($con)) { $con->beginTransaction(); try { $stmtLocal = $con->prepare($sql); $stmtLocal->execute([$newStatus, $id]); // تحديث جدول driver_orders أيضاً لتوحيد الحالة (اختياري ولكنه مفضل) $stmtDriverOrder = $con->prepare("UPDATE driver_orders SET status = ? WHERE order_id = ?"); $stmtDriverOrder->execute([$newStatus, $id]); $con->commit(); } catch (Exception $eLocal) { $con->rollBack(); error_log("⚠️ Local DB Update Failed: " . $eLocal->getMessage()); } } // --------------------------------------------------------- // 3. 🔥 إشعار الراكب عبر السوكيت (القطعة المفقودة) 🔥 // --------------------------------------------------------- // أ. جلب معرف الراكب لإرسال الإشعار له // نستخدم connection الرحلات لضمان وجود البيانات $stmtPas = $con_ride->prepare("SELECT passenger_id FROM ride WHERE id = ?"); $stmtPas->execute([$id]); $passenger_id = $stmtPas->fetchColumn(); if ($passenger_id) { $payload = [ 'ride_id' => $id, 'status' => 'cancelled', // هذه الحالة يستقبلها الفلاتر ويغلق الواجهة 'msg' => 'للأسف، قام السائق بإلغاء الرحلة.' ]; // استدعاء الدالة المعرفة في functions.php/connect.php if (function_exists('notifyPassengerOnRideServer')) { notifyPassengerOnRideServer($passenger_id, $payload); error_log("📡 [cancelRide.php] Notification sent to Passenger ID: $passenger_id"); } else { error_log("⚠️ [cancelRide.php] Function notifyPassengerOnRideServer not found!"); } } // --------------------------------------------------------- // 4. إنهاء العملية // --------------------------------------------------------- error_log("✅ [cancelRide.php] Ride cancelled successfully."); jsonSuccess(null, "Ride cancelled successfully"); } else { // الفشل يعني أن الرحلة غير موجودة أو حالتها لا تسمح بالإلغاء (مثلاً بدأت بالفعل) error_log("⚠️ [cancelRide.php] Failed. ID invalid OR Status not allowed (maybe started?)."); jsonError("Cannot cancel ride. Status might be started or already completed."); } } catch (PDOException $e) { error_log("❌ [cancelRide.php] Database Error: " . $e->getMessage()); jsonError("Database Error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/finish_ride_updates.php ``` prepare("UPDATE ride SET status = ?, rideTimeFinish = NOW(), price = ? WHERE id = ? AND status = 'Begin'"); $stmtRemote->execute([$newStatus, $price, $rideId]); if ($stmtRemote->rowCount() == 0) { // إذا لم يجد الصف (ربما تم إنهاؤها بالفعل) // jsonError("Could not finish ride (Remote)."); // exit; // ملاحظة: الأفضل إكمال العملية محلياً احتياطاً } // 2. التحديث المحلي (Local DB) $con->beginTransaction(); $con->prepare("UPDATE ride SET status = ?, rideTimeFinish = NOW(), price = ? WHERE id = ? AND status = 'Begin'") ->execute([$newStatus, $price, $rideId]); // تحديث driver_orders $checkStmt = $con->prepare("SELECT order_id FROM driver_orders WHERE order_id = ?"); $checkStmt->execute([$rideId]); if ($checkStmt->rowCount() > 0) { $con->prepare("UPDATE driver_orders SET driver_id = ?, status = ?, created_at = NOW() WHERE order_id = ?") ->execute([$driver_id, $newStatus, $rideId]); } else { $con->prepare("INSERT INTO driver_orders (driver_id, order_id, created_at, status) VALUES (?, ?, NOW(), ?)") ->execute([$driver_id, $rideId, $newStatus]); } // ================================================================= // 🔥 الخطوة 3: إشعار الراكب (Socket + FCM) // ================================================================= if ($passenger_id) { // تجهيز القائمة المتوافقة مع الكود القديم (Legacy List) // [driver_id, ride_id, driver_token, price] $legacyList = [ (string)$driver_id, (string)$rideId, (string)$driver_token, (string)$price ]; // أ) إرسال Socket $socketPayload = [ 'ride_id' => $rideId, 'status' => 'finished', 'price' => $price, 'DriverList' => $legacyList // إرسال القائمة للسوكيت أيضاً ]; if (function_exists('notifyPassengerOnRideServer')) { notifyPassengerOnRideServer($passenger_id, $socketPayload); } // ب) إرسال FCM (Internal) if (!empty($passengerToken)) { $fcmData = [ 'ride_id' => (string)$rideId, 'price' => (string)$price, 'DriverList' => $legacyList // ✅ نمرر المصفوفة، والدالة الداخلية تحولها لـ JSON ]; sendFCM_Internal( $passengerToken, // الهدف "تم إنهاء الرحلة 🏁", // العنوان "المبلغ المطلوب: " . $price . " ل.س", // النص (أضفت العملة افتراضياً) $fcmData, // البيانات 'Driver Finish Trip', // التصنيف (كما هو في التطبيق القديم) false // ليس Topic ); } } $con->commit(); jsonSuccess(null, "Ride finished successfully"); } catch (PDOException $e) { if ($con->inTransaction()) $con->rollBack(); jsonError("DB Error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/getRideStatusBegin.php ``` prepare($sql); $stmt->bindParam(':ride_id', $ride_id, PDO::PARAM_INT); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row) { echo json_encode([ "status" => "success", "data" => $row ]); } else { jsonError("Ride not found."); } ?> ``` ## File: ride/rides/cron_ride_timeout.php ``` prepare($sqlUpdate); $stmtUpdate->execute(); $updatedCount = $stmtUpdate->rowCount(); // ========================================================= // الخطوة 2: الحذف من جدول الانتظار (تنظيف Hot Data) // ========================================================= $sqlDelete = "DELETE FROM waitingRides WHERE created_at < DATE_SUB(NOW(), INTERVAL $minutesLimit MINUTE)"; $stmtDelete = $con->prepare($sqlDelete); $stmtDelete->execute(); $deletedCount = $stmtDelete->rowCount(); // ========================================================= // الخطوة 3: (اختياري) تنظيف الريدز // ========================================================= // بما أنك تستخدم Redis، المفترض أن تحذفها منه أيضاً. // لكن بما أن الريدز يعتمد على TTL (Expire) أو سيتم تحديثه عند الطلب القادم، // فالحذف من الـ MySQL يكفي لأن getRideWaiting سيفحص MySQL ولن يجدها. // تقرير العملية if ($deletedCount > 0) { $msg = "✅ [Cleanup Cron] Success: Timed out $updatedCount rides in Main DB, and Deleted $deletedCount rides from Waiting DB."; error_log($msg); echo json_encode(["status" => "success", "message" => $msg]); } else { $msg = "💤 [Cleanup Cron] No expired rides found."; error_log($msg); echo json_encode(["status" => "success", "message" => "Nothing to clean."]); } } catch (PDOException $e) { $errorMsg = "❌ [Cleanup Cron] Error: " . $e->getMessage(); error_log($errorMsg); echo json_encode(["status" => "failure", "message" => $e->getMessage()]); } ?> ``` ## File: ride/rides/delete.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); // التحقق من نجاح العملية if ($stmt->rowCount() > 0) { jsonSuccess(null, "Ride deleted successfully"); } else { jsonError("Failed to delete ride"); } ?> ``` ## File: ride/rides/public_track_location.php ``` "failure", "message" => $message], $extra)); exit; } try { $rideID = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT); $token = filter_input(INPUT_GET, 'token', FILTER_SANITIZE_SPECIAL_CHARS); if (!$rideID || !$token) { sendError("Missing parameters"); } $stmtRide = $con_ride->prepare("SELECT driver_id, status FROM ride WHERE id = ? LIMIT 1"); $stmtRide->execute([$rideID]); $rideData = $stmtRide->fetch(PDO::FETCH_ASSOC); if (!$rideData) sendError("Ride not found"); $driverID = $rideData['driver_id']; $status = $rideData['status']; $secretSalt = "Siro_Secure_Track_2025"; $generatedToken = md5(trim(strval($rideID)) . trim(strval($driverID)) . $secretSalt); if ($token !== $generatedToken) sendError("Invalid Token"); $allowedStatuses = ['Applied', 'Arrived', 'Begin', 'inProgress']; if (!in_array($status, $allowedStatuses)) { sendError("Ride not active", 200, ["current_status" => $status]); } $stmtLoc = $con_tracking->prepare("SELECT latitude, longitude, heading, speed, updated_at FROM car_locations WHERE driver_id = ? ORDER BY updated_at DESC LIMIT 1"); $stmtLoc->execute([$driverID]); $locData = $stmtLoc->fetch(PDO::FETCH_ASSOC); if (!$locData) sendError("Waiting for driver signal...", 200); $stmtDriver = $con->prepare("SELECT d.first_name, c.model, c.color, c.car_plate FROM driver d LEFT JOIN CarRegistration c ON d.id = c.driverID WHERE d.id = ? LIMIT 1"); $stmtDriver->execute([$driverID]); $driverInfo = $stmtDriver->fetch(PDO::FETCH_ASSOC); $driverName = "Captain"; $carModel = "Car"; $carColor = ""; $plate = ""; if ($driverInfo) { if (!empty($driverInfo['first_name'])) $driverName = $encryptionHelper->decryptData($driverInfo['first_name']); if (!empty($driverInfo['model'])) $carModel = $driverInfo['model']; if (!empty($driverInfo['color'])) $carColor = $driverInfo['color']; if (!empty($driverInfo['car_plate'])) $plate = $encryptionHelper->decryptData($driverInfo['car_plate']); } $response = [ "status" => "success", "data" => [ "lat" => $locData['latitude'], "lng" => $locData['longitude'], "heading" => $locData['heading'], "speed" => $locData['speed'], "last_update" => $locData['updated_at'], "driver_name" => $driverName, "car_model" => $carModel, "car_color" => $carColor, "plate" => $plate, "ride_status" => $status ] ]; // التنظيف النهائي قبل الطباعة ob_clean(); echo json_encode($response); } catch (Exception $e) { error_log("Tracking API Error: " . $e->getMessage()); sendError("Server Error"); } ``` ## File: ride/rides/getRideOrderID.php ``` prepare($sqlRide); // ربط المتغيرات حسب نوع البحث if (!empty($rideID)) { $stmtRide->bindParam(':rideID', $rideID); } else { $stmtRide->bindParam(':passengerID', $passengerID); } $stmtRide->execute(); $rideData = $stmtRide->fetch(PDO::FETCH_ASSOC); // إذا لم يتم العثور على رحلة في سيرفر الرحلات، نوقف العملية if (!$rideData) { echo json_encode(["status" => "failure", "message" => "No ride found"]); exit; } // ================================================================= // 2. الخطوة الثانية: جلب البيانات الثابتة (سائق، سيارة، تقييم) من السيرفر الرئيسي ($con) // نستخدم المعرفات التي حصلنا عليها من نتيجة الاستعلام الأول // ================================================================= $driverID = $rideData['driver_id']; $pID = $rideData['passenger_id']; // نأخذ معرف الراكب من الرحلة نفسها لضمان التطابق // ملاحظة: استخدام :driverID_Sub في الاستعلام الفرعي لتجنب أخطاء PDO $sqlDetails = "SELECT passengers.first_name AS passengerName, passengers.last_name, CarRegistration.make, CarRegistration.model, CarRegistration.car_plate, CarRegistration.year, CarRegistration.color, CarRegistration.color_hex, driver.first_name AS driverName, driver.gender, driver.phone, ( SELECT ROUND(AVG(ratingDriver.rating), 2) FROM ratingDriver WHERE ratingDriver.driver_id = :driverID_Sub ) AS ratingDriver, driverToken.token AS token FROM driver LEFT JOIN passengers ON passengers.id = :passengerID LEFT JOIN CarRegistration ON CarRegistration.driverID = driver.id LEFT JOIN driverToken ON driverToken.captain_id = driver.id WHERE driver.id = :driverID"; // نستخدم المتغير الأصلي $con للسيرفر الرئيسي $stmtDetails = $con->prepare($sqlDetails); // نربط المتغيرات $stmtDetails->bindParam(':driverID', $driverID); $stmtDetails->bindParam(':driverID_Sub', $driverID); $stmtDetails->bindParam(':passengerID', $pID); $stmtDetails->execute(); $detailsData = $stmtDetails->fetch(PDO::FETCH_ASSOC); // ================================================================= // 3. الخطوة الثالثة: دمج البيانات وتجهيز الرد // ================================================================= $finalData = []; if ($detailsData) { // دمج مصفوفة الرحلة (من سيرفر الرحلات) مع مصفوفة التفاصيل (من الرئيسي) $finalData = array_merge($rideData, $detailsData); } else { // في حال كانت الرحلة بدون سائق بعد، نكتفي ببيانات الرحلة $finalData = $rideData; } // ================================================================= // 4. فك التشفير (Decrypt) // ================================================================= if ($finalData) { $fieldsToDecrypt = ['driverName', 'gender', 'phone', 'car_plate', 'passengerName', 'last_name', 'token']; foreach ($fieldsToDecrypt as $field) { if (!empty($finalData[$field])) { $finalData[$field] = $encryptionHelper->decryptData($finalData[$field]); } } } echo json_encode([ "status" => "success", "data" => $finalData ]); } catch (Exception $e) { error_log("API Error: " . $e->getMessage()); http_response_code(500); echo json_encode(["status" => "failure", "message" => "Server Error: " . $e->getMessage()]); } ?> ``` ## File: ride/rides/test_notification.php ``` 'dispatch_order', 'drivers_ids' => json_encode([$driverId]), 'ride_id' => $rideId, 'payload' => $payload ]; $ch = curl_init($socketUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $INTERNAL_KEY"]); curl_setopt($ch, CURLOPT_TIMEOUT, 3); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch)) { die("Curl error: " . curl_error($ch)); } curl_close($ch); echo "HTTP Code: $httpCode\n"; echo "Response: $response\n"; ``` ## File: ride/rides/getRideStatus.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row && isset($row['status'])) { echo json_encode([ "status" => "success", "data" => $row['status'] ]); } else { jsonError("Ride not found."); } ?> ``` ## File: ride/rides/cancel_ride_by_driver.php ``` beginTransaction(); // --------------------------------------------------------- // 1. معالجة driver_orders (Insert or Update) // --------------------------------------------------------- $checkStmt = $con->prepare("SELECT order_id FROM driver_orders WHERE order_id = ? AND driver_id = ?"); $checkStmt->execute([$rideId, $driverId]); if ($checkStmt->rowCount() > 0) { // موجود: تحديث $stmtLog = $con->prepare("UPDATE driver_orders SET status = ?, notes = ?, created_at = NOW() WHERE order_id = ? AND driver_id = ?"); $stmtLog->execute([$statusText, $reason, $rideId, $driverId]); } else { // غير موجود: إدخال $stmtLog = $con->prepare("INSERT INTO driver_orders (driver_id, order_id, status, created_at, notes) VALUES (?, ?, ?, NOW(), ?)"); $stmtLog->execute([$driverId, $rideId, $statusText, $reason]); } // --------------------------------------------------------- // 2. منطق الحظر (Business Logic) // --------------------------------------------------------- $stmtCount = $con->prepare(" SELECT COUNT(*) FROM driver_orders WHERE driver_id = ? AND status = ? AND created_at >= NOW() - INTERVAL 1 DAY "); $stmtCount->execute([$driverId, $statusText]); $cancelCount = $stmtCount->fetchColumn(); $isBlocked = false; $blockUntil = ""; if ($cancelCount >= 3) { $isBlocked = true; $blockUntil = date('Y-m-d H:i:s', strtotime('+4 hours')); // يمكنك هنا تحديث حالة السائق في جدول driver إذا لزم الأمر } // --------------------------------------------------------- // 3. تحديث حالة الرحلة في جدول ride // --------------------------------------------------------- $sqlRide = "UPDATE ride SET status = ?, driver_id = 0 WHERE id = ?"; // Local DB $con->prepare($sqlRide)->execute([$statusText, $rideId]); // Remote DB (إن وجد) if (isset($con_ride)) { $con_ride->prepare($sqlRide)->execute([$statusText, $rideId]); } // --------------------------------------------------------- // 4. إشعار الراكب // --------------------------------------------------------- // أ) Socket (يحتاج Passenger ID) $stmtPas = $con->prepare("SELECT passenger_id FROM ride WHERE id = ?"); $stmtPas->execute([$rideId]); $passenger_id = $stmtPas->fetchColumn(); if ($passenger_id) { $socketPayload = [ 'ride_id' => $rideId, 'status' => 'cancelled_by_driver', 'msg' => 'تم إلغاء الرحلة من قبل السائق' ]; if (function_exists('notifyPassengerOnRideServer')) { notifyPassengerOnRideServer($passenger_id, $socketPayload); } } // ب) FCM (Internal) if (!empty($passengerToken)) { $fcmData = [ 'ride_id' => (string)$rideId ]; // 🔥 استخدام الدالة الجديدة sendFCM_Internal( $passengerToken, // الهدف "تم إلغاء الرحلة ❌", // العنوان "عذراً، قام السائق بإلغاء الرحلة.", // النص $fcmData, // البيانات "Cancel Trip from driver", // التصنيف (تأكد أنه يطابق ما في تطبيق الراكب) false // ليس Topic ); } $con->commit(); // 5. الرد للفلاتر echo json_encode([ "status" => "success", "cancel_count" => $cancelCount, "is_blocked" => $isBlocked, "block_until" => $blockUntil ]); } catch (PDOException $e) { if ($con->inTransaction()) $con->rollBack(); jsonError("DB Error: " . $e->getMessage()); } ?> ``` ## File: ride/rides/emailToPassengerTripDetail.php ``` Tripz Logo

Hi $passengerName,

Thank you for booking your ride with Tripz. Here are the details of your recent trip:

DetailValue
Passenger$passengerName
Email$passengerEmail
Phone$passengerPhone
Fee$$fee
Start Location$startLocation ($startNameLocation)
End Location$endLocation ($endNameLocation)
Time of Trip$timeOfTrip
Duration$duration minutes
"; if ($discount > 0) { $bodyEmail .= "

You have received a 12% discount on your trip from $startNameLocation to $endNameLocation. The original fee was $$beforDiscount. Your discounted fee is $$fee.

"; } $bodyEmail .= "

Thank you for using Tripz. We hope you have a great day!

Best regards,
Tripz Team

"; // إعداد البريد $mail = new PHPMailer(true); try { $mail->isSMTP(); $mail->Host = 'smtp.hostinger.com'; $mail->SMTPAuth = true; $mail->Username = 'hamzaayed@tripz-egypt.com'; $mail->Password = $TRIPZ_SMTP_PASSWORD; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; $mail->setFrom('hamzaayed@tripz-egypt.com', 'Tripz'); $mail->addAddress($passengerEmail, $passengerName); $mail->isHTML(true); $mail->Subject = 'Your Tripz Trip Details'; $mail->Body = $bodyEmail; $mail->send(); echo json_encode(["status" => "success", "message" => "Email sent successfully"]); } catch (Exception $e) { echo json_encode(["status" => "error", "message" => $mail->ErrorInfo]); } ``` ## File: ride/rides/getRideOrderIDNew.php ``` prepare($sqlRide); // ربط المتغيرات حسب نوع البحث if (!empty($rideID)) { $stmtRide->bindParam(':rideID', $rideID); } else { $stmtRide->bindParam(':passengerID', $passengerID); } $stmtRide->execute(); $rideData = $stmtRide->fetch(PDO::FETCH_ASSOC); // إذا لم يتم العثور على رحلة في سيرفر الرحلات، نوقف العملية if (!$rideData) { echo json_encode(["status" => "failure", "message" => "No ride found"]); exit; } // ================================================================= // 2. الخطوة الثانية: جلب البيانات الثابتة (سائق، سيارة، تقييم) من السيرفر الرئيسي ($con) // نستخدم المعرفات التي حصلنا عليها من نتيجة الاستعلام الأول // ================================================================= $driverID = $rideData['driver_id']; $pID = $rideData['passenger_id']; // نأخذ معرف الراكب من الرحلة نفسها لضمان التطابق // ملاحظة: استخدام :driverID_Sub في الاستعلام الفرعي لتجنب أخطاء PDO $sqlDetails = "SELECT passengers.first_name AS passengerName, passengers.last_name, CarRegistration.make, CarRegistration.model, CarRegistration.car_plate, CarRegistration.year, CarRegistration.color, CarRegistration.color_hex, driver.first_name AS driverName, driver.gender, driver.phone, ( SELECT ROUND(AVG(ratingDriver.rating), 2) FROM ratingDriver WHERE ratingDriver.driver_id = :driverID_Sub ) AS ratingDriver, driverToken.token AS token FROM driver LEFT JOIN passengers ON passengers.id = :passengerID LEFT JOIN CarRegistration ON CarRegistration.driverID = driver.id LEFT JOIN driverToken ON driverToken.captain_id = driver.id WHERE driver.id = :driverID"; // نستخدم المتغير الأصلي $con للسيرفر الرئيسي $stmtDetails = $con->prepare($sqlDetails); // نربط المتغيرات $stmtDetails->bindParam(':driverID', $driverID); $stmtDetails->bindParam(':driverID_Sub', $driverID); $stmtDetails->bindParam(':passengerID', $pID); $stmtDetails->execute(); $detailsData = $stmtDetails->fetch(PDO::FETCH_ASSOC); // ================================================================= // 3. الخطوة الثالثة: دمج البيانات وتجهيز الرد // ================================================================= $finalData = []; if ($detailsData) { // دمج مصفوفة الرحلة (من سيرفر الرحلات) مع مصفوفة التفاصيل (من الرئيسي) $finalData = array_merge($rideData, $detailsData); } else { // في حال كانت الرحلة بدون سائق بعد، نكتفي ببيانات الرحلة $finalData = $rideData; } // ================================================================= // 4. فك التشفير (Decrypt) // ================================================================= if ($finalData) { $fieldsToDecrypt = ['driverName', 'gender', 'phone', 'car_plate', 'passengerName', 'last_name', 'token']; foreach ($fieldsToDecrypt as $field) { if (!empty($finalData[$field])) { $finalData[$field] = $encryptionHelper->decryptData($finalData[$field]); } } } echo json_encode([ "status" => "success", "data" => $finalData ]); } catch (Exception $e) { error_log("API Error: " . $e->getMessage()); http_response_code(500); echo json_encode(["status" => "failure", "message" => "Server Error: " . $e->getMessage()]); } ?> ``` ## File: ride/license/add.php ``` prepare($sql); $stmt->bindParam(':driverID', $driverID); $stmt->bindParam(':name', $name); $stmt->bindParam(':licenseClass', $licenseClass); $stmt->bindParam(':documentNo', $documentNo); $stmt->bindParam(':address', $address); $stmt->bindParam(':height', $height); $stmt->bindParam(':postalCode', $postalCode); $stmt->bindParam(':sex', $sex); $stmt->bindParam(':stateCode', $stateCode); $stmt->bindParam(':expireDate', $expireDate); $stmt->bindParam(':dateOfBirth', $dateOfBirth); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = "Data saved successfully"); } else { // Print a failure message jsonError($message = "Failed to save data"); } ?> ``` ## File: ride/license/update.php ``` ``` ## File: ride/license/get.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($result) { // Print all promo records jsonSuccess($result); } else { // Print a failure message jsonError($message = "Failed to retrieve promo records"); } ?> ``` ## File: ride/license/delete.php ``` ``` ## File: ride/notificationPassenger/add.php ``` prepare($sql); $stmt->execute([ ':title' => $title, ':body' => $body, ':passengerID' => $passengerID ]); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Notification data saved successfully"); } else { jsonError("Failed to save notification data"); } ?> ``` ## File: ride/notificationPassenger/update.php ``` $id]; $mapping = [ "title" => "title", "body" => "body", "passengerID" => "passenger_id", "isShown" => "isShown", "updatedAt" => "updated_at" ]; // تجهيز الـ SET والأرقام المقابلة foreach ($mapping as $requestKey => $dbColumn) { if (isset($_POST[$requestKey])) { $value = filterRequest($requestKey); $fields[] = "`$dbColumn` = :$requestKey"; $params[":$requestKey"] = $value; } } if (empty($fields)) { jsonError("No fields to update"); exit; } $setClause = implode(", ", $fields); $sql = "UPDATE `notifications` SET $setClause WHERE `id` = :id"; $stmt = $con->prepare($sql); $stmt->execute($params); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Notification data updated successfully"); } else { jsonError("Failed to update notification data"); } ?> ``` ## File: ride/notificationPassenger/get.php ``` = CURDATE() - INTERVAL 7 DAY ORDER BY `created_at` DESC LIMIT 10"; $stmt = $con->prepare($sql); $stmt->bindParam(':passenger_id', $passenger_id, PDO::PARAM_STR); $stmt->execute(); $notifications = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($notifications) { jsonSuccess($notifications); } else { jsonError("No notification data found"); } ?> ``` ## File: ride/notificationPassenger/delete.php ``` ``` ## File: ride/card-image-driver/add.php ``` // require_once __DIR__ . '/../../connect.php'; // $driverID = filterRequest("driver_id"); // $imageName = filterRequest("image_name"); // $link = filterRequest("link"); // // Check if the driverID exists in the table // $checkSQL = "SELECT * FROM `card_images` WHERE `driver_id` = '$driverID'"; // $checkStmt = $con->prepare($checkSQL); // $checkStmt->execute(); // if ($checkStmt->rowCount() > 0) { // // Driver ID found, update the upload_date // $uploadDate = date("Y-m-d H:i:s"); // $updateSQL = "UPDATE `card_images` SET `upload_date` = '$uploadDate' WHERE `driver_id` = '$driverID'"; // $updateStmt = $con->prepare($updateSQL); // $updateStmt->execute(); // if ($updateStmt->rowCount() > 0) { // // Print a success message for update // jsonSuccess($message = "Record updated successfully"); // } else { // // Print a failure message for update // jsonError($message = "Failed to update record"); // } // } else { // // Driver ID not found, insert a new record // $sql = "INSERT INTO `card_images` (`id`, `driver_id`, `image_name`, `link`) // VALUES (SHA2(UUID(), 256), '$driverID', '$imageName', '$link')"; // $stmt = $con->prepare($sql); // $stmt->execute(); // if ($stmt->rowCount() > 0) { // // Print a success message for insert // jsonSuccess($message = "Record inserted successfully"); // } else { // // Print a failure message for insert // jsonError($message = "Failed to insert record"); // } // } 'The image file was not uploaded successfully.')); exit; } // Get the file name of the image file. $image_name = $image_file['name']; // Get the file extension of the image file. $image_extension = pathinfo($image_name, PATHINFO_EXTENSION); // Check if the image file is a valid image file. if (!in_array($image_extension, array('jpg', 'jpeg', 'png'))) { echo json_encode(array('status' => 'The image file is not a valid image file.')); exit; } // Generate a new filename using the driver ID. $new_filename = $driverID . '.' . $image_extension; // Move the image file to the uploads directory with the new filename. $target_dir = "card_image/"; $target_file = $target_dir . $new_filename; move_uploaded_file($image_file['tmp_name'], $target_file); // Update the image name variable with the new filename. $image_name = $new_filename; // Check if the driverID already exists in the database. $sql = "SELECT * FROM card_images WHERE driver_id = '$driverID'"; $result = mysqli_query($conn, $sql); if (mysqli_num_rows($result) > 0) { // The driverID already exists in the database, so update the upload_date $uploadDate = date("Y-m-d H:i:s"); $linlImage='https://ride.mobile-app.store/card_image/'.$image_name; $updateSQL = "UPDATE card_images SET upload_date = '$uploadDate' WHERE driver_id = '$driverID'"; mysqli_query($conn, $updateSQL); if (mysqli_affected_rows($conn) > 0) { // Print a success message for update echo json_encode(array('status' => 'Record updated successfully')); } else { // Print a failure message for update echo json_encode(array('status' => 'Failed to update record')); } } else { // The driverID does not exist in the database, so insert a new row. $insertSQL = "INSERT INTO card_images (id, driver_id, image_name, `link`) VALUES (SHA2(UUID(), 256), '$driverID', '$image_name',)"; mysqli_query($conn, $insertSQL); if (mysqli_affected_rows($conn) > 0) { // Print a success message for insert echo json_encode(array('status' => 'Record inserted successfully')); } else { // Print a failure message for insert echo json_encode(array('status' => 'Failed to insert record')); } } ?> ``` ## File: ride/card-image-driver/update.php ``` ``` ## File: ride/card-image-driver/get.php ``` ``` ## File: ride/card-image-driver/delete.php ``` ``` ## File: ride/mishwari/add.php ``` encryptData($phone); $gender = $encryptionHelper->encryptData($gender); $name = $encryptionHelper->encryptData($name); $name_english = $encryptionHelper->encryptData($name_english); $car_plate = $encryptionHelper->encryptData($car_plate); $token = $encryptionHelper->encryptData($token); $education = $encryptionHelper->encryptData($education); $national_number = $encryptionHelper->encryptData($national_number); $age = $encryptionHelper->encryptData($age); // ⏰ تحويل الوقت للفحص $selectedTime = new DateTime($timeSelected); $startTime = $selectedTime->format('Y-m-d H:i:s'); $endTime = $selectedTime->add(new DateInterval('PT6H'))->format('Y-m-d H:i:s'); // ✅ فحص هل السائق لديه أكثر من رحلتين خلال 6 ساعات $sqlCheck = "SELECT COUNT(*) as trip_count FROM `mishwaritrips` WHERE `driverId` = :driverId AND `timeSelected` BETWEEN :startTime AND :endTime"; $stmtCheck = $con->prepare($sqlCheck); $stmtCheck->bindParam(':driverId', $driverId); $stmtCheck->bindParam(':startTime', $startTime); $stmtCheck->bindParam(':endTime', $endTime); $stmtCheck->execute(); $result = $stmtCheck->fetch(PDO::FETCH_ASSOC); if ($result['trip_count'] >= 2) { jsonError("Driver already has 2 trips within the specified period."); exit; } // ✅ فحص إن الراكب لا يملك رحلة فعالة بنفس اليوم $sqlCheckPassenger = " SELECT * FROM `mishwaritrips` WHERE `passengerId` = :passengerId AND `status` != 'Finished' AND DATE(`timeSelected`) = CURDATE() "; $stmtCheckPassenger = $con->prepare($sqlCheckPassenger); $stmtCheckPassenger->bindParam(':passengerId', $passengerId); $stmtCheckPassenger->execute(); $existingTrip = $stmtCheckPassenger->fetch(PDO::FETCH_ASSOC); // إذا كانت موجودة يتم التحديث if ($existingTrip) { $sqlUpdate = "UPDATE `mishwaritrips` SET `driverId` = :driverId, `phone` = :phone, `gender` = :gender, `name` = :name, `name_english` = :name_english, `address` = :address, `religion` = :religion, `age` = :age, `startNameAddress` = :startNameAddress, `locationCoordinate` = :locationCoordinate, `education` = :education, `license_type` = :license_type, `national_number` = :national_number, `car_plate` = :car_plate, `make` = :make, `model` = :model, `color` = :color, `color_hex` = :color_hex, `token` = :token, `rating` = :rating, `countRide` = :countRide, `timeSelected` = :timeSelected, `status` = :status WHERE `passengerId` = :passengerId"; $stmtUpdate = $con->prepare($sqlUpdate); $stmtUpdate->execute([ ':driverId' => $driverId, ':phone' => $phone, ':gender' => $gender, ':name' => $name, ':name_english' => $name_english, ':address' => $address, ':religion' => $religion, ':age' => $age, ':startNameAddress' => $startNameAddress, ':locationCoordinate' => $locationCoordinate, ':education' => $education, ':license_type' => $license_type, ':national_number' => $national_number, ':car_plate' => $car_plate, ':make' => $make, ':model' => $model, ':color' => $color, ':color_hex' => $color_hex, ':token' => $token, ':rating' => $rating, ':countRide' => $countRide, ':timeSelected' => $timeSelected, ':status' => $status, ':passengerId' => $passengerId ]); if ($stmtUpdate->rowCount() > 0) { jsonSuccess(null, "Trip updated successfully"); } else { jsonError("Failed to update trip data"); } } else { // إدخال رحلة جديدة $sqlInsert = "INSERT INTO `mishwaritrips` ( `driverId`, `phone`, `gender`, `name`, `name_english`, `address`, `religion`, `age`, `startNameAddress`, `locationCoordinate`, `education`, `license_type`, `national_number`, `car_plate`, `make`, `model`, `color`, `color_hex`, `token`, `rating`, `countRide`, `passengerId`, `timeSelected`, `createdAt`, `status` ) VALUES ( :driverId, :phone, :gender, :name, :name_english, :address, :religion, :age, :startNameAddress, :locationCoordinate, :education, :license_type, :national_number, :car_plate, :make, :model, :color, :color_hex, :token, :rating, :countRide, :passengerId, :timeSelected, NOW(), :status )"; $stmtInsert = $con->prepare($sqlInsert); $stmtInsert->execute([ ':driverId' => $driverId, ':phone' => $phone, ':gender' => $gender, ':name' => $name, ':name_english' => $name_english, ':address' => $address, ':religion' => $religion, ':age' => $age, ':startNameAddress' => $startNameAddress, ':locationCoordinate' => $locationCoordinate, ':education' => $education, ':license_type' => $license_type, ':national_number' => $national_number, ':car_plate' => $car_plate, ':make' => $make, ':model' => $model, ':color' => $color, ':color_hex' => $color_hex, ':token' => $token, ':rating' => $rating, ':countRide' => $countRide, ':passengerId' => $passengerId, ':timeSelected' => $timeSelected, ':status' => $status ]); if ($stmtInsert->rowCount() > 0) { jsonSuccess(null, "New trip inserted successfully"); } else { jsonError("Failed to insert new trip data"); } } ?> ``` ## File: ride/mishwari/get.php ``` = CURDATE() - INTERVAL 4 DAY AND mi.timeSelected > NOW() ORDER BY mi. `createdAt` DESC LIMIT 1 "; $stmt = $con->prepare($sql); $stmt->bindParam(':driverId', $driverId, PDO::PARAM_STR); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/mishwari/cancel.php ``` prepare($sql); $stmt->bindParam(':status', $status, PDO::PARAM_STR); $stmt->bindParam(':id', $id, PDO::PARAM_INT); // Bind the ID parameter // Execute the update if ($stmt->execute()) { // Check if the update was successful if ($stmt->rowCount() > 0) { // Trip status updated successfully jsonSuccess(null, "Trip cancelled successfully."); } else { // No rows updated, meaning the trip might not have been found or was already cancelled jsonError("No trip found to cancel."); } } else { // Print failure if the update query failed $errorInfo = $stmt->errorInfo(); error_log('SQL Error: ' . implode(", ", $errorInfo)); jsonError("Failed to cancel the trip."); } ?> ``` ## File: ride/mishwari/getDriver.php ``` = CURDATE() - INTERVAL 4 DAY AND mi.timeSelected > NOW() ORDER BY mi. `createdAt` DESC LIMIT 1 "; $stmt = $con->prepare($sql); $stmt->bindParam(':driverId', $driverId, PDO::PARAM_STR); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/mishwari/test.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير للحقول الحساسة foreach ($rows as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); $row['email'] = $encryptionHelper->decryptData($row['email']); $row['gender'] = $encryptionHelper->decryptData($row['gender']); $row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']); $row['site'] = $encryptionHelper->decryptData($row['site']); $row['first_name'] = $encryptionHelper->decryptData($row['first_name']); $row['last_name'] = $encryptionHelper->decryptData($row['last_name']); $row['sosPhone'] = $encryptionHelper->decryptData($row['sosPhone']); $row['education'] = $encryptionHelper->decryptData($row['education']); $row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']); $row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']); } jsonSuccess($rows); } else { jsonError("No passengers found"); } ?> ``` ## File: ride/driverWallet/driverStatistic.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/driverWallet/add.php ``` prepare("SELECT * FROM payment_tokens WHERE token = :token AND isUsed = FALSE"); $stmt->execute(array( ':token' => $token )); $tokenData = $stmt->fetch(); if ($tokenData) { // Add payment to the driver's wallet table $sql = "INSERT INTO `driverWallet` ( `driverID`, `paymentID`, `amount`, `paymentMethod` ) VALUES ( :driverID, :paymentID, :amount, :paymentMethod );"; $stmt = $con->prepare($sql); $stmt->execute(array( ':driverID' => $driverID, ':paymentID' => $paymentID, ':amount' => $amount, ':paymentMethod' => $paymentMethod )); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess(null, "Record saved successfully"); // Mark the token as used in the database $stmt = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE id = :tokenID"); $stmt->execute(array( ':tokenID' => $tokenData['id'] )); } else { // Print a failure message jsonError("Failed to save record"); } } else { jsonError("Invalid or already used token"); } ``` ## File: ride/driverWallet/update.php ``` ``` ## File: ride/driverWallet/get.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/driverWallet/getDriverWeekPaymentMove.php ``` = DATE_SUB(NOW(), INTERVAL 1 WEEK) ) AS totalAmount FROM `driverWallet` WHERE `driverID` = '$driverID' AND `dateCreated` >= DATE_SUB(NOW(), INTERVAL 1 WEEK) ORDER BY `dateCreated` DESC; "; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/driverWallet/getWalletByDriver.php ``` = DATE_SUB(NOW(), INTERVAL 1 MONTH) ORDER BY `paymentsDriverPoints`.`id` DESC"; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/driverWallet/getDriverDetails.php ``` prepare($sql); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($data) { // Print the car location data as JSON echo json_encode([ 'status' => 'success', 'data' => $data ]); } else { // Print a failure message jsonError($message = "No car locations found"); } ?> ``` ## File: ride/driverWallet/sendEmailTransfer.php ```

تفاصيل نقلك على سفر

شكراً لاستخدام خدمتنا. نتمنى لك يوماً رائعاً!

نريد إعلامك أن مبلغ $amount تم نقله من حسابك إلى السائق الجديد، $newDriverName (هاتف: $driverPhone).

مع خالص التحية،
فريق سفر

"; } else { $bodyEmail = "
SEFER App Logo

Your SEFER Transfer Details

Thank you for using our service. We hope you have a great day!

We want to inform you that an amount of $amount has been transferred from your account to the new driver: $newDriverName (Phone: $driverPhone).

Regards,
SEFER Team

"; } // Email headers $supportEmail = 'seferteam@sefer.live'; $headers = "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: text/html; charset=UTF-8\r\n"; $headers .= "From: $supportEmail\r\n"; // Send email if (!empty($driverEmail)) { if (mail($driverEmail, "Your SEFER Transfer Details", $bodyEmail, $headers)) { mail($newEmail, "Your SEFER Transfer Details", $bodyEmail, $headers); echo "Email sent successfully."; } else { echo "Email sending failed."; } } else { echo "Invalid email address: $driverEmail"; } ``` ## File: ride/driverWallet/delete.php ``` ``` ## File: ride/driverWallet/addPaymentToken.php ``` prepare("INSERT INTO payment_tokens (token, driverID, dateCreated, amount) VALUES (?, ?, NOW(), ?)"); try { $stmt->execute([$token, $driverID, $amount]); if ($stmt->rowCount() > 0) { jsonSuccess($token); } else { jsonError("Failed to save record"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } function generateSecureToken($driverID, $amount) { global $secretKey; // Concatenate the parameters $data = $driverID . $amount . time(); // Add the secret key from the environment variable $data .= $secretKey; // Generate a hash $hash = hash('sha256', $data); // Add some randomness $randomBytes = bin2hex(random_bytes(16)); // Combine hash and random bytes $token = $hash . $randomBytes; // Truncate to a reasonable length (e.g., 64 characters) return substr($token, 0, 64); } ``` ## File: ride/location/getSpeed.php ``` = NOW() - INTERVAL :freshSeconds SECOND ORDER BY updated_at DESC LIMIT 100; -- نجلب 100 مرشح محتمل "; $stmt_locations = $con_tracking->prepare($sql_locations); $stmt_locations->bindValue(':boundingBox', $boundingBoxWKT); $stmt_locations->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT); $stmt_locations->execute(); $locations = $stmt_locations->fetchAll(PDO::FETCH_ASSOC); if (!$locations) { jsonError("No car locations found in the specified area."); exit; } // ================================================================= // الخطوة 2: تجميع معرفات السائقين (driver_id) // ================================================================= $driver_ids = array_column($locations, 'driver_id'); // ================================================================= // الخطوة 3: جلب البيانات الثابتة من القاعدة الأساسية وتطبيق الفلاتر الإضافية // ================================================================= $drivers_info = []; if (!empty($driver_ids)) { $placeholders = implode(',', array_fill(0, count($driver_ids), '?')); // هنا نطبق الشروط الخاصة بهذا السكريبت (موديل السيارة > 2000) $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, cr.make, cr.model, cr.color, cr.color_hex, cr.year, dt.token, COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver, COALESCE(rdAvg.ratingCount, 0) AS ratingCount 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, COUNT(id) AS ratingCount FROM ratingDriver GROUP BY driver_id ) rdAvg ON rdAvg.driver_id = d.id WHERE d.id IN ($placeholders) -- AND COALESCE(cr.year, 0) > 2000 -- ⭐ الشرط الخاص بهذا السكريبت -- AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%') AND (cr.model NOT LIKE '%Van%' AND cr.make NOT LIKE '%Van%') "; $stmt_drivers_info = $con->prepare($sql_drivers_info); $stmt_drivers_info->execute($driver_ids); $drivers_info_raw = $stmt_drivers_info->fetchAll(PDO::FETCH_ASSOC); // تحويل المصفوفة لتسهيل عملية الدمج لاحقاً foreach ($drivers_info_raw as $driver) { $drivers_info[$driver['driver_id']] = $driver; } } // ================================================================= // الخطوة 4: دمج النتائج في PHP // ================================================================= $final_results = []; foreach ($locations as $location) { $driver_id = $location['driver_id']; if (isset($drivers_info[$driver_id])) { $final_results[] = array_merge($location, $drivers_info[$driver_id]); } } // ================================================================= // الخطوة 5: تطبيق الترتيب والحد النهائي في PHP // ================================================================= usort($final_results, function ($a, $b) { if ($a['ratingDriver'] != $b['ratingDriver']) { return $b['ratingDriver'] <=> $a['ratingDriver']; } if ($a['ratingCount'] != $b['ratingCount']) { return $b['ratingCount'] <=> $a['ratingCount']; } return strtotime($b['updated_at']) <=> strtotime($a['updated_at']); }); $limited_results = array_slice($final_results, 0, 10); if (empty($limited_results)) { jsonError("No cars matching the specific criteria (year > 2000) found."); exit; } // ================================================================= // الخطوة 6: فك التشفير وحساب العمر (بدون تغيير) // ================================================================= $fieldsToDecrypt = [ 'phone','email','gender','birthdate', 'first_name','last_name', 'token','car_plate','vin' ]; foreach ($limited_results as &$row) { foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && !empty($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; } } unset($row); jsonSuccess($limited_results); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ``` ## File: ride/location/add.php ``` 99999999.99) { $dist = 99999999.99; } if ($dist < -99999999.99){ $dist = -99999999.99; } if (empty($driver_id) || ($lat == 0.0 && $lng == 0.0)) { jsonError("Invalid payload"); exit; } $created_at = date("Y-m-d H:i:s"); $sql = "INSERT INTO `car_tracks` (`driver_id`,`latitude`,`longitude`,`heading`,`speed`,`distance`,`status`,`created_at`) VALUES (:driver_id,:latitude,:longitude,:heading,:speed,:distance,:status,:created_at)"; $stmt = $con->prepare($sql); $ok = $stmt->execute([ ':driver_id' => $driver_id, ':latitude' => $lat, ':longitude' => $lng, ':heading' => $head, ':speed' => $spd, ':distance' => $dist, // ← now DECIMAL(10,2)-friendly ':status' => (string)($status ?? 'on'), ':created_at' => $created_at, ]); if ($ok) { jsonSuccess(null, "car_tracks saved successfully"); } else { jsonError("Failed to save car track"); } } catch (PDOException $e) { error_log("car_tracks insert error: " . $e->getMessage()); jsonError("Database error"); } catch (Throwable $e) { error_log("car_tracks insert fatal: " . $e->getMessage()); jsonError("Server error"); } ``` ## File: ride/location/getfemalbehavior.php ``` = :southwestLat AND cl.latitude <= :northeastLat AND cl.longitude >= :southwestLon AND cl.longitude <= :northeastLon AND cl.status = 'off' AND cl.updated_at >= NOW() - INTERVAL 5 SECOND AND (cr.make NOT LIKE '%دراجة%' OR cr.model NOT LIKE '%دراجة%') AND d.gender = 'Female' GROUP BY cl.driver_id ORDER BY ratingDriver DESC, cl.updated_at DESC LIMIT 10; "; $stmt = $con->prepare($sql); $stmt->bindParam(':southwestLat', $southwestLat); $stmt->bindParam(':southwestLon', $southwestLon); $stmt->bindParam(':northeastLat', $northeastLat); $stmt->bindParam(':northeastLon', $northeastLon); $stmt->execute(); $car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($car_locations) { jsonSuccess($car_locations); } else { jsonError("No car locations found"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: ride/location/getDriverTimeOnline.php ``` = DATE_SUB(CURDATE(), INTERVAL ? DAY) GROUP BY driver_id HAVING grand_total_seconds > 60 -- (اختياري) تجاهل من عمل أقل من دقيقة ORDER BY grand_total_seconds DESC "; $stmt = $con_tracking->prepare($sql_summary); $stmt->execute([$daysToLookBack]); $summary_data = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($summary_data)) { // حفظ ملف فارغ وإنهاء saveJsonFile($savePath, ["last_updated" => date('Y-m-d H:i:s'), "data" => []]); printSuccess("No active drivers found in summary.", $savePath); exit; } // ================================================================= // 2. جلب تفاصيل السائقين (الأسماء) من السيرفر الرئيسي 📝 // ================================================================= // استخراج الـ IDs $driver_ids = array_column($summary_data, 'driver_id'); // تجهيز الـ Placeholders (?,?,?) $placeholders = implode(',', array_fill(0, count($driver_ids), '?')); $sql_drivers = "SELECT id, name_arabic, phone, created_at FROM driver WHERE id IN ($placeholders)"; $stmt_d = $con->prepare($sql_drivers); $stmt_d->execute($driver_ids); $drivers_raw = $stmt_d->fetchAll(PDO::FETCH_ASSOC); // تحويل البيانات لـ Map لسرعة الدمج: [id => data] $drivers_map = []; foreach ($drivers_raw as $d) { $drivers_map[$d['id']] = $d; } // ================================================================= // 3. دمج البيانات وفك التشفير وتنسيق الوقت 🔄 // ================================================================= $final_report = []; $fieldsToDecrypt = ['phone', 'name_arabic']; // الحقول المشفرة foreach ($summary_data as $row) { $did = $row['driver_id']; $seconds = $row['grand_total_seconds']; // البيانات الشخصية $personalData = isset($drivers_map[$did]) ? $drivers_map[$did] : ['name_arabic' => 'Unknown', 'phone' => '']; // فك التشفير foreach ($fieldsToDecrypt as $field) { if (!empty($personalData[$field])) { try { $personalData[$field] = $encryptionHelper->decryptData($personalData[$field]); } catch (Exception $e) { // ابقها مشفرة أو ضع قيمة افتراضية عند الفشل } } } // تنسيق الوقت (مقروء للبشر) $hours = floor($seconds / 3600); $minutes = floor(($seconds % 3600) / 60); $human_time = sprintf("%d ساعة و %d دقيقة", $hours, $minutes); // بناء الصف النهائي $final_report[] = [ 'driver_id' => $did, 'name' => $personalData['name_arabic'], 'phone' => $personalData['phone'], 'join_date' => $personalData['created_at'], // تاريخ انضمام السائق 'total_seconds' => $seconds, 'active_time' => $human_time, 'days_active' => $row['days_worked'] // عدد الأيام التي عمل فيها خلال الـ 10 أيام ]; } // ================================================================= // 4. الحفظ والنشر 💾 // ================================================================= $output = [ "last_updated" => date('Y-m-d H:i:s'), "period_days" => $daysToLookBack, "total_drivers" => count($final_report), "data" => $final_report ]; saveJsonFile($savePath, $output); printSuccess("Report generated based on Daily Summary.", $savePath); } catch (Exception $e) { jsonError("Error: " . $e->getMessage()); } // --- دوال مساعدة --- function saveJsonFile($path, $data) { $json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); file_put_contents($path, $json); } ?> ``` ## File: ride/location/update.php ``` prepare($sql); // The execute method returns true on success and false on failure. $success = $stmt->execute([ ':latitude' => $latitude, ':longitude' => $longitude, ':heading' => $heading, ':speed' => $speed, ':distance' => $distance, ':status' => $status, ':updated_at' => $updated_at, ':driver_id' => $driver_id ]); // The reliable way to check for success is if execute() returns true // and doesn't throw an exception. We no longer need rowCount(). if ($success) { // Print a success message jsonSuccess(null, "Car location updated successfully"); } else { // This case is rare but might happen if execute fails without an exception jsonError("Failed to update car location"); } } catch (PDOException $e) { // A real database error occurred. http_response_code(500); // You can log the detailed error for debugging // error_log('Database error: ' . $e->getMessage()); jsonError('Database error occurred'); } ?> ``` ## File: ride/location/get.php ``` $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)) { jsonError("No drivers nearby"); 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, cr.make, cr.car_plate, cr.model, cr.color, cr.vin, cr.color_hex, cr.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, 0) > 2000 AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%') "; $stmt = $con->prepare($sql_drivers_info); $stmt->execute($driverIds); $drivers_db = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($drivers_db)) { jsonError("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()); } ?> ``` ## File: ride/location/getPinkBike.php ``` = NOW() - INTERVAL 5 SECOND AND (cr.make LIKE '%دراجة%' OR cr.model LIKE '%دراجة%') GROUP BY cl.driver_id ORDER BY ratingDriver DESC, cl.updated_at DESC LIMIT 10; "; $stmt = $con->prepare($sql); $stmt->bindParam(':southwestLat', $southwestLat); $stmt->bindParam(':southwestLon', $southwestLon); $stmt->bindParam(':northeastLat', $northeastLat); $stmt->bindParam(':northeastLon', $northeastLon); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($rows) { $fieldsToDecrypt = [ 'phone', 'email', 'gender', 'birthdate', 'first_name', 'last_name', 'maritalStatus', 'token', 'make', 'car_plate', 'vin' ]; $filteredRows = []; foreach ($rows as &$row) { foreach ($fieldsToDecrypt as $field) { if (isset($row[$field])) { $row[$field] = $encryptionHelper->decryptData($row[$field]); } } // فلترة حسب الجنس if (strtolower($row['gender']) !== 'female') { continue; } // حساب العمر if (!empty($row['birthdate'])) { $birthDate = new DateTime($row['birthdate']); $today = new DateTime(); $row['age'] = $today->diff($birthDate)->y; } else { $row['age'] = null; } $filteredRows[] = $row; } jsonSuccess($filteredRows); } else { jsonError("No car locations found"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ``` ## File: ride/location/get_location_area_links.php ``` prepare($sql); $stmt->execute(); $car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($car_locations) { jsonSuccess($car_locations); } else { jsonError("No car locations found"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ``` ## File: ride/location/getLocationParents.php ``` يتصل بقاعدة البيانات الأساسية (driver, CarRegistration) // $con_tracking -> يتصل بقاعدة بيانات التتبع (car_locations) require_once __DIR__ . '/../../connect.php'; try { $driver_id = filterRequest("driver_id"); if ($driver_id === false || empty($driver_id)) { jsonError("Invalid driver_id provided"); exit; } // ================================================================= // الخطوة 1: جلب آخر موقع للسائق من قاعدة بيانات التتبع // ================================================================= // هذا الاستعلام يعمل على قاعدة بيانات التتبع السريعة // (ملاحظة: تم التغيير إلى ORDER BY updated_at لجلب آخر تحديث) $sql_location = "SELECT id, driver_id, latitude, longitude, heading, speed, status, created_at, updated_at FROM car_locations WHERE driver_id = ? ORDER BY updated_at DESC LIMIT 1"; $stmt_location = $con_tracking->prepare($sql_location); $stmt_location->execute([$driver_id]); $location_data = $stmt_location->fetch(PDO::FETCH_ASSOC); // إذا لم نجد أي موقع، لا داعي لإكمال البحث if (empty($location_data)) { jsonError("No car locations found"); exit; } // ================================================================= // الخطوة 2: جلب البيانات الثابتة للسائق من القاعدة الأساسية // ================================================================= // هذا الاستعلام يعمل على قاعدة البيانات الأساسية الهادئة // (ملاحظة: تم إصلاح الخطأ في جملة JOIN) $sql_driver_info = "SELECT d.gender, cr.model FROM driver d LEFT JOIN CarRegistration cr ON d.id = cr.driverID WHERE d.id = ?"; $stmt_driver_info = $con->prepare($sql_driver_info); $stmt_driver_info->execute([$driver_id]); $driver_info = $stmt_driver_info->fetch(PDO::FETCH_ASSOC); // ================================================================= // الخطوة 3: دمج النتائج (Application-Side Join) // ================================================================= // دمج بيانات الموقع مع بيانات السائق if (empty($driver_info)) { $driver_info = []; // اجعله مصفوفة فارغة لتجنب خطأ في الدمج } $final_result = array_merge($location_data, $driver_info); // السكربت الأصلي كان يستخدم fetchAll، لذا كان يرجع مصفوفة بداخلها عنصر واحد // [ [ ... بيانات ... ] ] // سنحافظ على نفس البنية لإرجاع البيانات jsonSuccess([$final_result]); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ?> ``` ## File: ride/location/getUpdatedLocationForAdmin.php ``` = NOW() - INTERVAL $freshSeconds SECOND"; } // تحديد المسار الكامل بدقة $savePath = __DIR__ . '/' . $fileName; // === فحص صلاحيات الكتابة === if (!is_writable(__DIR__)) { // إذا لم تكن هناك صلاحية، سنطبع الخطأ ونوقف التنفيذ echo json_encode([ "status" => "error", "message" => "Permission Denied: Cannot write to directory. Please chmod 777 this folder.", "path" => __DIR__ ]); exit; } // 1. جلب المواقع $sql_locations = " SELECT t.driver_id, t.latitude AS lat, t.longitude AS lon, t.heading, t.speed, t.created_at FROM car_tracks t INNER JOIN ( SELECT driver_id, MAX(id) AS max_id FROM car_tracks WHERE $timeCondition GROUP BY driver_id ) latest ON t.id = latest.max_id ORDER BY t.created_at DESC "; $stmt = $con_tracking->prepare($sql_locations); $stmt->execute(); $locations = $stmt->fetchAll(PDO::FETCH_ASSOC); // 2. جلب بيانات السائقين $driver_ids = array_unique(array_column($locations, 'driver_id')); $drivers_info = []; if (!empty($driver_ids)) { $placeholders = implode(',', array_fill(0, count($driver_ids), '?')); $sql_drivers = "SELECT id, first_name, last_name, phone, (SELECT COUNT(*) FROM ride WHERE driver_id = driver.id AND status = 'Completed') as completed, (SELECT COUNT(*) FROM ride WHERE driver_id = driver.id AND status = 'CancelFromDriverAfterApply') as cancelled FROM driver WHERE id IN ($placeholders)"; $stmt_drivers = $con->prepare($sql_drivers); $stmt_drivers->execute(array_values($driver_ids)); foreach ($stmt_drivers->fetchAll(PDO::FETCH_ASSOC) as $row) { $drivers_info[$row['id']] = $row; } } // 3. الدمج $final_drivers = []; foreach ($locations as $loc) { $d_id = $loc['driver_id']; $merged = [ 'id' => $d_id, 'lat' => $loc['lat'], 'lon' => $loc['lon'], 'heading' => $loc['heading'], 'speed' => $loc['speed'], 'name' => 'Unknown', 'phone' => '', 'completed' => 0, 'cancelled' => 0 ]; if (isset($drivers_info[$d_id])) { $info = $drivers_info[$d_id]; // فك التشفير البسيط (تأكد من عمل encryptionHelper) if (isset($encryptionHelper)) { try { $info['first_name'] = $encryptionHelper->decryptData($info['first_name']); } catch(Exception $e){} try { $info['last_name'] = $encryptionHelper->decryptData($info['last_name']); } catch(Exception $e){} try { $info['phone'] = $encryptionHelper->decryptData($info['phone']); } catch(Exception $e){} } $merged['name'] = trim(($info['first_name']??'') . ' ' . ($info['last_name']??'')); $merged['phone'] = $info['phone'] ?? ''; $merged['completed'] = $info['completed'] ?? 0; $merged['cancelled'] = $info['cancelled'] ?? 0; } $final_drivers[] = $merged; } // 4. الحفظ $jsonContent = json_encode(['drivers' => $final_drivers, 'last_updated' => date('Y-m-d H:i:s')], JSON_UNESCAPED_UNICODE); // محاولة الحفظ if (file_put_contents($savePath, $jsonContent) !== false) { echo json_encode(["status" => "success", "message" => "File written successfully to $savePath"]); } else { echo json_encode(["status" => "error", "message" => "Failed to write file. Check permissions."]); } } catch (Exception $e) { echo json_encode(["status" => "error", "message" => $e->getMessage()]); } ?> ``` ## File: ride/location/save_behavior.php ``` يتصل بقاعدة البيانات الأساسية // $con_tracking -> يتصل بقاعدة بيانات التتبع (driver_behavior, car_locations) require_once __DIR__ . '/../../connect.php'; try { // استلام البيانات من Flutter $driver_id = filterRequest("driver_id"); $trip_id = filterRequest("trip_id"); $max_speed = filterRequest("max_speed"); $avg_speed = filterRequest("avg_speed"); $hard_brakes = filterRequest("hard_brakes"); $total_distance = filterRequest("total_distance"); $behavior_score = filterRequest("behavior_score"); // تحقق من القيم الأساسية if (empty($driver_id) || empty($trip_id)) { jsonError("Missing driver_id or trip_id"); exit(); } // إدخال البيانات في جدول driver_behavior باستخدام اتصال التتبع // تم تغيير $con إلى $con_tracking $stmt = $con_tracking->prepare(" INSERT INTO driver_behavior ( driver_id, trip_id, max_speed, avg_speed, hard_brakes, total_distance, behavior_score ) VALUES (?, ?, ?, ?, ?, ?, ?) "); $stmt->execute([ $driver_id, $trip_id, $max_speed, $avg_speed, $hard_brakes, $total_distance, $behavior_score ]); // التحقق من نجاح العملية if ($stmt->rowCount() > 0) { jsonSuccess(null, "Behavior data saved"); } else { // في حالة عدم حدوث خطأ، ولكن لم يتم إدخال صف (قد يحدث)، // من الأفضل إرجاع رسالة فشل عامة. jsonError("Failed to save data (No rows affected)"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } // تم حذف exit() من هنا ليتم التعامل معها داخل try/catch ?> ``` ## File: ride/location/getDriverCarsLocationToPassengerAfterApplied.php ``` يتصل بقاعدة البيانات الأساسية (driver, CarRegistration) // $con_tracking -> يتصل بقاعدة بيانات التتبع (car_locations) // وأنه يحتوي على كائن التشفير $encryptionHelper require_once __DIR__ . '/../../connect.php'; try { $driver_id = filterRequest("driver_id"); if ($driver_id === false || empty($driver_id)) { jsonError("Invalid driver_id provided"); exit; } // ================================================================= // الخطوة 1: جلب آخر موقع للسائق من قاعدة بيانات التتبع // ================================================================= $sql_location = "SELECT driver_id, latitude, longitude, heading, speed, status, created_at, updated_at FROM car_locations WHERE driver_id = ? ORDER BY updated_at DESC LIMIT 1"; $stmt_location = $con_tracking->prepare($sql_location); $stmt_location->execute([$driver_id]); $location_data = $stmt_location->fetch(PDO::FETCH_ASSOC); // إذا لم نجد أي موقع، لا داعي لإكمال البحث if (empty($location_data)) { jsonError("No car locations found"); exit; } // ================================================================= // الخطوة 2: جلب البيانات الثابتة للسائق من القاعدة الأساسية // ================================================================= $sql_driver_info = "SELECT d.gender, cr.model FROM driver d LEFT JOIN CarRegistration cr ON d.id = cr.driverID WHERE d.id = ?"; $stmt_driver_info = $con->prepare($sql_driver_info); $stmt_driver_info->execute([$driver_id]); // نستخدم fetch وليس fetchAll لأننا نتوقع سائق واحد فقط $driver_info = $stmt_driver_info->fetch(PDO::FETCH_ASSOC); // ================================================================= // الخطوة 2.5: فك تشفير الجندر (New Step) // ================================================================= if (!empty($driver_info)) { // التحقق من وجود قيمة في حقل الجندر قبل فك تشفيرها if (isset($driver_info['gender']) && !empty($driver_info['gender'])) { $driver_info['gender'] = $encryptionHelper->decryptData($driver_info['gender']); } } else { $driver_info = []; // اجعله مصفوفة فارغة لتجنب خطأ في الدمج } // ================================================================= // الخطوة 3: دمج النتائج (Application-Side Join) // ================================================================= // دمج بيانات الموقع مع بيانات السائق (التي تم فك تشفيرها الآن) $final_result = array_merge($location_data, $driver_info); // إرجاع النتيجة داخل مصفوفة كما في السكربت الأصلي jsonSuccess([$final_result]); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ?> ``` ## File: ride/location/print.php ```

⚠️ Error: Data File Not Found

Please ensure '.$source_file.' exists in the same directory.

'); } // Get content $json_data = file_get_contents($source_file); $data = json_decode($json_data, true); if (!$data) { die('Error decoding JSON data.'); } $drivers = $data['data']; $last_updated = $data['last_updated'] ?? date('Y-m-d H:i:s'); // ============================================================ // 2. DATA PROCESSING (Logic Layer) // ============================================================ $processed_drivers = []; $stats = [ 'total' => 0, 'elite' => 0, // +50 hours 'stable' => 0, // +20 hours 'experimental' => 0, // +5 hours 'inactive' => 0 ]; foreach ($drivers as $driver) { // Parse Active Time String (e.g., "293 ساعة و 48 دقيقة") $timeStr = $driver['active_time'] ?? "0 ساعة و 0 دقيقة"; preg_match('/(\d+)\s*ساعة/', $timeStr, $hoursMatch); preg_match('/(\d+)\s*دقيقة/', $timeStr, $minsMatch); $hours = isset($hoursMatch[1]) ? (int)$hoursMatch[1] : 0; $mins = isset($minsMatch[1]) ? (int)$minsMatch[1] : 0; $totalMinutes = ($hours * 60) + $mins; // Categorize Driver $category = 'inactive'; $catLabel = 'خامل'; $catClass = 'cat-inactive'; if ($totalMinutes >= 3000) { // 50 hours $category = 'elite'; $catLabel = 'نخبة'; $catClass = 'cat-elite'; $stats['elite']++; } elseif ($totalMinutes >= 1200) { // 20 hours $category = 'stable'; $catLabel = 'مستقر'; $catClass = 'cat-stable'; $stats['stable']++; } elseif ($totalMinutes >= 300) { // 5 hours $category = 'experimental'; $catLabel = 'تجريبي'; $catClass = 'cat-experimental'; $stats['experimental']++; } else { $stats['inactive']++; } $driver['total_minutes'] = $totalMinutes; $driver['category_label'] = $catLabel; $driver['category_class'] = $catClass; $processed_drivers[] = $driver; } $stats['total'] = count($processed_drivers); // Sort by Active Time (High to Low) usort($processed_drivers, function($a, $b) { return $b['total_minutes'] <=> $a['total_minutes']; }); ?> تقرير السائقين - Siro

تقرير أداء السائقين

تاريخ الطباعة:

Siro

:آخر تحديث بيانات
إجمالي السائقين
النخبة (+50 ساعة)
مستقرون (+20 ساعة)
يحتاجون متابعة
# اسم السائق رقم الهاتف ساعات النشاط الحالة تاريخ الانضمام ملاحظات إدارية
``` ## File: ride/location/getTotalDriverDurationToday.php ``` = '$current_date' AND car_tracks.created_at < DATE_ADD('$current_date', INTERVAL 1 DAY);"; $stmt = $con->prepare($sql); $stmt->execute(); $car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($car_locations) { // Print the car location data as JSON jsonSuccess($car_locations); } else { // Print a failure message jsonError($message = "No car locations found"); } ?> ``` ## File: ride/location/getCarsLocationByPassengerVan.php ``` = NOW() - INTERVAL :freshSeconds SECOND ORDER BY updated_at DESC LIMIT 100; -- نجلب 100 مرشح محتمل "; $stmt_locations = $con_tracking->prepare($sql_locations); $stmt_locations->bindValue(':boundingBox', $boundingBoxWKT); $stmt_locations->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT); $stmt_locations->execute(); $locations = $stmt_locations->fetchAll(PDO::FETCH_ASSOC); if (!$locations) { jsonError("No car locations found in the specified area."); exit; } // ================================================================= // الخطوة 2: تجميع معرفات السائقين (driver_id) // ================================================================= $driver_ids = array_column($locations, 'driver_id'); // ================================================================= // الخطوة 3: جلب البيانات الثابتة من القاعدة الأساسية وتطبيق الفلاتر الإضافية // ================================================================= $drivers_info = []; if (!empty($driver_ids)) { $placeholders = implode(',', array_fill(0, count($driver_ids), '?')); // هنا نطبق الشروط الخاصة بهذا السكريبت (سيارات كهربائية فقط) $sql_drivers_info = " SELECT d.id AS driver_id, d.phone, d.email, d.birthdate, d.first_name, d.last_name, cr.make, cr.model, cr.color, cr.color_hex, cr.year, cr.fuel, dt.token, COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver, COALESCE(rdAvg.ratingCount, 0) AS ratingCount 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, COUNT(*) AS ratingCount FROM ratingDriver GROUP BY driver_id ) rdAvg ON rdAvg.driver_id = d.id WHERE d.id IN ($placeholders) AND cr.make = 'Van'or cr.model='Van' "; $stmt_drivers_info = $con->prepare($sql_drivers_info); $stmt_drivers_info->execute($driver_ids); $drivers_info_raw = $stmt_drivers_info->fetchAll(PDO::FETCH_ASSOC); // تحويل المصفوفة لتسهيل عملية الدمج لاحقاً foreach ($drivers_info_raw as $driver) { $drivers_info[$driver['driver_id']] = $driver; } } // ================================================================= // الخطوة 4: دمج النتائج في PHP // ================================================================= $final_results = []; foreach ($locations as $location) { $driver_id = $location['driver_id']; // ندمج فقط السائقين الذين طابقوا شروطنا في الاستعلام الثاني if (isset($drivers_info[$driver_id])) { $final_results[] = array_merge($location, $drivers_info[$driver_id]); } } // ================================================================= // الخطوة 5: تطبيق الترتيب والحد النهائي في PHP // ================================================================= usort($final_results, function ($a, $b) { if ($a['ratingDriver'] != $b['ratingDriver']) { return $b['ratingDriver'] <=> $a['ratingDriver']; } if ($a['ratingCount'] != $b['ratingCount']) { return $b['ratingCount'] <=> $a['ratingCount']; } return strtotime($b['updated_at']) <=> strtotime($a['updated_at']); }); // وأخيراً، نأخذ أفضل 10 نتائج فقط $limited_results = array_slice($final_results, 0, 10); if (empty($limited_results)) { jsonError("No electric cars matching the criteria found."); exit; } // ================================================================= // الخطوة 6: فك التشفير وحساب العمر (بدون تغيير) // ================================================================= $fieldsToDecrypt = [ 'phone','email','gender','birthdate', 'first_name','last_name', 'token','car_plate','vin' ]; foreach ($limited_results as &$row) { foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && !empty($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; } } unset($row); jsonSuccess($limited_results); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ``` ## File: ride/location/getTotalDriverDuration.php ``` = :first_day_of_month AND car_tracks.created_at < :last_day_of_month GROUP BY day ORDER BY day ASC;"; $stmt = $con->prepare($sql); $stmt->bindParam(':driver_id', $driver_id, PDO::PARAM_STR); $stmt->bindParam(':first_day_of_month', $first_day_of_month, PDO::PARAM_STR); $stmt->bindParam(':last_day_of_month', $last_day_of_month, PDO::PARAM_STR); $stmt->execute(); $car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($car_locations) { // Print the car location data as JSON jsonSuccess($data = $car_locations); } else { // Print a failure message jsonError($message = "No car locations found"); } ?> ``` ## File: ride/location/getComfort.php ``` = NOW() - INTERVAL :freshSeconds SECOND ORDER BY updated_at DESC LIMIT 100; -- نجلب 100 مرشح محتمل "; $stmt_locations = $con_tracking->prepare($sql_locations); $stmt_locations->bindValue(':boundingBox', $boundingBoxWKT); $stmt_locations->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT); $stmt_locations->execute(); $locations = $stmt_locations->fetchAll(PDO::FETCH_ASSOC); if (!$locations) { jsonError("No car locations found in the specified area."); exit; } // ================================================================= // الخطوة 2: تجميع معرفات السائقين (driver_id) // ================================================================= $driver_ids = array_column($locations, 'driver_id'); // ================================================================= // الخطوة 3: جلب البيانات الثابتة من القاعدة الأساسية وتطبيق الفلاتر الإضافية // ================================================================= $drivers_info = []; if (!empty($driver_ids)) { $placeholders = implode(',', array_fill(0, count($driver_ids), '?')); // هنا نطبق الشروط الخاصة بهذا السكريبت (موديل السيارة > 2017) $sql_drivers_info = " SELECT d.id AS driver_id, d.phone, d.email, d.birthdate, d.first_name, d.last_name, cr.make, cr.model, cr.color, cr.color_hex, cr.year, dt.token, COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver, COALESCE(rdAvg.ratingCount, 0) AS ratingCount FROM driver d -- 1. تغيير LEFT JOIN إلى INNER JOIN لضمان عدم جلب سائق إلا إذا كانت بيانات سيارته مطابقة تماماً INNER 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, COUNT(*) AS ratingCount FROM ratingDriver GROUP BY driver_id ) rdAvg ON rdAvg.driver_id = d.id WHERE d.id IN ($placeholders) -- 2. الفلترة الصارمة للسنة AND cr.year IS NOT NULL AND TRIM(cr.year) != '' AND CAST(TRIM(cr.year) AS UNSIGNED) > 2017 AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%') AND (cr.model NOT LIKE '%Van%' AND cr.make NOT LIKE '%Van%') "; $stmt_drivers_info = $con->prepare($sql_drivers_info); $stmt_drivers_info->execute($driver_ids); $drivers_info_raw = $stmt_drivers_info->fetchAll(PDO::FETCH_ASSOC); // تحويل المصفوفة لتسهيل عملية الدمج لاحقاً foreach ($drivers_info_raw as $driver) { $drivers_info[$driver['driver_id']] = $driver; } } // ================================================================= // الخطوة 4: دمج النتائج في PHP // ================================================================= $final_results = []; foreach ($locations as $location) { $driver_id = $location['driver_id']; // ندمج فقط السائقين الذين طابقوا شروطنا في الاستعلام الثاني if (isset($drivers_info[$driver_id])) { $final_results[] = array_merge($location, $drivers_info[$driver_id]); } } // ================================================================= // الخطوة 5: تطبيق الترتيب والحد النهائي في PHP // ================================================================= // الآن بعد أن دمجنا كل البيانات، يمكننا تطبيق الترتيب المعقد usort($final_results, function ($a, $b) { // الترتيب الأول: حسب التقييم (تنازلي) if ($a['ratingDriver'] != $b['ratingDriver']) { return $b['ratingDriver'] <=> $a['ratingDriver']; } // الترتيب الثاني: حسب عدد التقييمات (تنازلي) if ($a['ratingCount'] != $b['ratingCount']) { return $b['ratingCount'] <=> $a['ratingCount']; } // الترتيب الثالث: حسب حداثة الموقع (تنازلي) return strtotime($b['updated_at']) <=> strtotime($a['updated_at']); }); // وأخيراً، نأخذ أفضل 5 نتائج فقط $limited_results = array_slice($final_results, 0, 5); if (empty($limited_results)) { jsonError("No cars matching the specific criteria (year > 2017) found."); exit; } // ================================================================= // الخطوة 6: فك التشفير وحساب العمر (بدون تغيير) // ================================================================= $fieldsToDecrypt = [ 'phone','email','gender','birthdate', 'first_name','last_name', 'token','car_plate','vin' ]; foreach ($limited_results as &$row) { foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && !empty($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; } } unset($row); jsonSuccess($limited_results); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ``` ## File: ride/location/delete.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = "Car location deleted successfully"); } else { // Print a failure message jsonError($message = "Failed to delete car location"); } ?> ``` ## File: ride/location/getBalash.php ``` = NOW() - INTERVAL :freshSeconds SECOND ORDER BY updated_at DESC LIMIT 20; -- نجلب 100 مرشح محتمل للفلترة والترتيب لاحقاً "; $stmt_locations = $con_tracking->prepare($sql_locations); $stmt_locations->bindValue(':boundingBox', $boundingBoxWKT); $stmt_locations->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT); $stmt_locations->execute(); $locations = $stmt_locations->fetchAll(PDO::FETCH_ASSOC); if (!$locations) { jsonError("No car locations found in the specified area."); exit; } // ================================================================= // الخطوة 2: تجميع معرفات السائقين (driver_id) // ================================================================= $driver_ids = array_column($locations, 'driver_id'); // ================================================================= // الخطوة 3: جلب البيانات الثابتة من القاعدة الأساسية وتطبيق الفلاتر الإضافية // ================================================================= $drivers_info = []; if (!empty($driver_ids)) { $placeholders = implode(',', array_fill(0, count($driver_ids), '?')); // هنا نطبق الشروط الخاصة بهذا السكريبت (موديل السيارة < 2000) $sql_drivers_info = " SELECT d.id AS driver_id, d.phone, d.email, d.birthdate, d.first_name, d.last_name, cr.make, cr.model, cr.color, cr.color_hex, cr.year, dt.token, COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver, COALESCE(rdAvg.ratingCount, 0) AS ratingCount 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, COUNT(id) AS ratingCount FROM ratingDriver GROUP BY driver_id ) rdAvg ON rdAvg.driver_id = d.id WHERE d.id IN ($placeholders) AND COALESCE(cr.year, 0) < 2000 -- ⭐ الشرط الخاص بهذا السكريبت AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%') AND (cr.model NOT LIKE '%Van%' AND cr.make NOT LIKE '%Van%') "; $stmt_drivers_info = $con->prepare($sql_drivers_info); $stmt_drivers_info->execute($driver_ids); $drivers_info_raw = $stmt_drivers_info->fetchAll(PDO::FETCH_ASSOC); // تحويل المصفوفة لتسهيل عملية الدمج لاحقاً foreach ($drivers_info_raw as $driver) { $drivers_info[$driver['driver_id']] = $driver; } } // ================================================================= // الخطوة 4: دمج النتائج في PHP // ================================================================= $final_results = []; foreach ($locations as $location) { $driver_id = $location['driver_id']; // ندمج فقط السائقين الذين طابقوا شروطنا في الاستعلام الثاني if (isset($drivers_info[$driver_id])) { $final_results[] = array_merge($location, $drivers_info[$driver_id]); } } // ================================================================= // الخطوة 5: تطبيق الترتيب والحد النهائي في PHP // ================================================================= // الآن بعد أن دمجنا كل البيانات، يمكننا تطبيق الترتيب المعقد usort($final_results, function ($a, $b) { // الترتيب الأول: حسب التقييم (تنازلي) if ($a['ratingDriver'] != $b['ratingDriver']) { return $b['ratingDriver'] <=> $a['ratingDriver']; } // الترتيب الثاني: حسب عدد التقييمات (تنازلي) if ($a['ratingCount'] != $b['ratingCount']) { return $b['ratingCount'] <=> $a['ratingCount']; } // الترتيب الثالث: حسب حداثة الموقع (تنازلي) return strtotime($b['updated_at']) <=> strtotime($a['updated_at']); }); // وأخيراً، نأخذ أفضل 5 نتائج فقط $limited_results = array_slice($final_results, 0, 5); if (empty($limited_results)) { jsonError("No cars matching the specific criteria (year < 2000) found."); exit; } // ================================================================= // الخطوة 6: فك التشفير وحساب العمر (بدون تغيير) // ================================================================= $fieldsToDecrypt = [ 'phone','email','gender','birthdate', 'first_name','last_name', 'token','car_plate','vin' ]; foreach ($limited_results as &$row) { foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && !empty($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; } } unset($row); jsonSuccess($limited_results); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ``` ## File: ride/location/getLatestLocationPassenger.php ``` prepare($sql); $stmt->execute([':rideId' => $rideId]); $car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($car_locations) { // Print the car location data as JSON jsonSuccess($data = $car_locations); } else { // Print a failure message jsonError($message = "No car locations found"); } ?> ``` ## File: ride/location/getRidesDriverByDay.php ``` = :first_day_total AND `ride`.created_at < :last_day_total AND `ride`.`status` = 'Finished' ) AS totalPrice, ( SELECT COUNT(`ride`.`id`) FROM `ride` WHERE `ride`.`driver_id` = :driver_id_count AND `ride`.`created_at` >= :first_day_count AND `ride`.created_at < :last_day_count AND `ride`.`status` = 'Finished' ) AS totalCount FROM `ride` WHERE `ride`.`driver_id` = :driver_id_main AND `ride`.`created_at` >= :first_day_main AND `ride`.created_at < :last_day_main AND `ride`.`status` = 'Finished' GROUP BY day ORDER BY day ASC;"; $stmt = $con->prepare($sql); // Bind each parameter uniquely $stmt->bindParam(':driver_id_total', $driver_id, PDO::PARAM_STR); $stmt->bindParam(':first_day_total', $first_day_of_month, PDO::PARAM_STR); $stmt->bindParam(':last_day_total', $last_day_of_month, PDO::PARAM_STR); $stmt->bindParam(':driver_id_count', $driver_id, PDO::PARAM_STR); $stmt->bindParam(':first_day_count', $first_day_of_month, PDO::PARAM_STR); $stmt->bindParam(':last_day_count', $last_day_of_month, PDO::PARAM_STR); $stmt->bindParam(':driver_id_main', $driver_id, PDO::PARAM_STR); $stmt->bindParam(':first_day_main', $first_day_of_month, PDO::PARAM_STR); $stmt->bindParam(':last_day_main', $last_day_of_month, PDO::PARAM_STR); $stmt->execute(); $car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($car_locations) { // Print the car location data as JSON jsonSuccess($data = $car_locations); } else { // Print a failure message jsonError($message = "No car locations found"); } ?> ``` ## File: ride/location/getFemalDriver.php ``` = NOW() - INTERVAL :freshSeconds SECOND ORDER BY updated_at DESC LIMIT 100; -- نجلب 100 مرشح محتمل "; $stmt_locations = $con_tracking->prepare($sql_locations); $stmt_locations->bindValue(':boundingBox', $boundingBoxWKT); $stmt_locations->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT); $stmt_locations->execute(); $locations = $stmt_locations->fetchAll(PDO::FETCH_ASSOC); if (!$locations) { jsonError("No car locations found in the specified area."); exit; } // ================================================================= // الخطوة 2: تجميع معرفات السائقين (driver_id) // ================================================================= $driver_ids = array_column($locations, 'driver_id'); // ================================================================= // الخطوة 3: جلب البيانات الثابتة من القاعدة الأساسية وتطبيق الفلاتر الإضافية // ================================================================= $drivers_info = []; if (!empty($driver_ids)) { $placeholders = implode(',', array_fill(0, count($driver_ids), '?')); // هنا نطبق الشروط الخاصة بهذا السكريبت (سائقات إناث فقط) $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, cr.make, cr.model, cr.color, cr.color_hex, cr.year, dt.token, COALESCE(AVG(rd.rating), 0) AS ratingDriver, COUNT(rd.id) AS ratingCount FROM driver d LEFT JOIN CarRegistration cr ON cr.driverID = d.id LEFT JOIN driverToken dt ON dt.captain_id = d.id LEFT JOIN ratingDriver rd ON rd.driver_id = d.id WHERE d.id IN ($placeholders) AND d.gender = 'Female' -- ⭐ الشرط الخاص بهذا السكريبت AND (cr.make NOT LIKE '%دراجة%' AND cr.model NOT LIKE '%دراجة%') AND (cr.model NOT LIKE '%Van%' AND cr.make NOT LIKE '%Van%') GROUP BY d.id -- تجميع النتائج حسب السائق لحساب التقييم بشكل صحيح "; $stmt_drivers_info = $con->prepare($sql_drivers_info); $stmt_drivers_info->execute($driver_ids); $drivers_info_raw = $stmt_drivers_info->fetchAll(PDO::FETCH_ASSOC); // تحويل المصفوفة لتسهيل عملية الدمج لاحقاً foreach ($drivers_info_raw as $driver) { $drivers_info[$driver['driver_id']] = $driver; } } // ================================================================= // الخطوة 4: دمج النتائج في PHP // ================================================================= $final_results = []; foreach ($locations as $location) { $driver_id = $location['driver_id']; // ندمج فقط السائقين الذين طابقوا شروطنا في الاستعلام الثاني (أنثى) if (isset($drivers_info[$driver_id])) { $final_results[] = array_merge($location, $drivers_info[$driver_id]); } } // ================================================================= // الخطوة 5: تطبيق الترتيب والحد النهائي في PHP // ================================================================= usort($final_results, function ($a, $b) { if ($a['ratingDriver'] != $b['ratingDriver']) { return $b['ratingDriver'] <=> $a['ratingDriver']; } if ($a['ratingCount'] != $b['ratingCount']) { return $b['ratingCount'] <=> $a['ratingCount']; } return strtotime($b['updated_at']) <=> strtotime($a['updated_at']); }); // وأخيراً، نأخذ أفضل 10 نتائج فقط $limited_results = array_slice($final_results, 0, 10); if (empty($limited_results)) { jsonError("No female drivers matching the criteria found."); exit; } // ================================================================= // الخطوة 6: فك التشفير وحساب العمر (بدون تغيير) // ================================================================= $fieldsToDecrypt = [ 'phone','email','gender','birthdate', 'first_name','last_name', 'token','car_plate','vin' ]; foreach ($limited_results as &$row) { foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && !empty($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; } } unset($row); jsonSuccess($limited_results); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ``` ## File: ride/location/getDelivery.php ``` = NOW() - INTERVAL :freshSeconds SECOND ORDER BY updated_at DESC LIMIT 100; -- نجلب 100 مرشح محتمل "; $stmt_locations = $con_tracking->prepare($sql_locations); $stmt_locations->bindValue(':boundingBox', $boundingBoxWKT); $stmt_locations->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT); $stmt_locations->execute(); $locations = $stmt_locations->fetchAll(PDO::FETCH_ASSOC); if (!$locations) { jsonError("No car locations found in the specified area."); exit; } // ================================================================= // الخطوة 2: تجميع معرفات السائقين (driver_id) // ================================================================= $driver_ids = array_column($locations, 'driver_id'); // ================================================================= // الخطوة 3: جلب البيانات الثابتة من القاعدة الأساسية وتطبيق الفلاتر الإضافية // ================================================================= $drivers_info = []; if (!empty($driver_ids)) { $placeholders = implode(',', array_fill(0, count($driver_ids), '?')); // هنا نطبق الشروط الخاصة بهذا السكريبت (دراجات فقط) $sql_drivers_info = " SELECT d.id AS driver_id, d.phone, d.email, d.birthdate, d.first_name, d.last_name, cr.make, cr.model, cr.color, cr.color_hex, cr.year, dt.token, COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver, COALESCE(rdAvg.ratingCount, 0) AS ratingCount 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, COUNT(*) AS ratingCount FROM ratingDriver GROUP BY driver_id ) rdAvg ON rdAvg.driver_id = d.id WHERE d.id IN ($placeholders) AND (cr.make LIKE '%دراج%' OR cr.model LIKE '%دراج%') -- ⭐ الشرط الخاص بهذا السكريبت "; $stmt_drivers_info = $con->prepare($sql_drivers_info); $stmt_drivers_info->execute($driver_ids); $drivers_info_raw = $stmt_drivers_info->fetchAll(PDO::FETCH_ASSOC); // تحويل المصفوفة لتسهيل عملية الدمج لاحقاً foreach ($drivers_info_raw as $driver) { $drivers_info[$driver['driver_id']] = $driver; } } // ================================================================= // الخطوة 4: دمج النتائج في PHP // ================================================================= $final_results = []; foreach ($locations as $location) { $driver_id = $location['driver_id']; // ندمج فقط السائقين الذين طابقوا شروطنا في الاستعلام الثاني if (isset($drivers_info[$driver_id])) { $final_results[] = array_merge($location, $drivers_info[$driver_id]); } } // ================================================================= // الخطوة 5: تطبيق الترتيب والحد النهائي في PHP // ================================================================= usort($final_results, function ($a, $b) { if ($a['ratingDriver'] != $b['ratingDriver']) { return $b['ratingDriver'] <=> $a['ratingDriver']; } if ($a['ratingCount'] != $b['ratingCount']) { return $b['ratingCount'] <=> $a['ratingCount']; } return strtotime($b['updated_at']) <=> strtotime($a['updated_at']); }); // وأخيراً، نأخذ أفضل 10 نتائج فقط $limited_results = array_slice($final_results, 0, 10); if (empty($limited_results)) { jsonError("No motorcycles matching the criteria found."); exit; } // ================================================================= // الخطوة 6: فك التشفير وحساب العمر (بدون تغيير) // ================================================================= $fieldsToDecrypt = [ 'phone','email','gender','birthdate', 'first_name','last_name','maritalStatus', 'token','make','car_plate','vin' ]; foreach ($limited_results as &$row) { foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && !empty($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; } } unset($row); jsonSuccess($limited_results); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ``` ## File: ride/location/getElectric.php ``` = NOW() - INTERVAL :freshSeconds SECOND ORDER BY updated_at DESC LIMIT 100; -- نجلب 100 مرشح محتمل "; $stmt_locations = $con_tracking->prepare($sql_locations); $stmt_locations->bindValue(':boundingBox', $boundingBoxWKT); $stmt_locations->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT); $stmt_locations->execute(); $locations = $stmt_locations->fetchAll(PDO::FETCH_ASSOC); if (!$locations) { jsonError("No car locations found in the specified area."); exit; } // ================================================================= // الخطوة 2: تجميع معرفات السائقين (driver_id) // ================================================================= $driver_ids = array_column($locations, 'driver_id'); // ================================================================= // الخطوة 3: جلب البيانات الثابتة من القاعدة الأساسية وتطبيق الفلاتر الإضافية // ================================================================= $drivers_info = []; if (!empty($driver_ids)) { $placeholders = implode(',', array_fill(0, count($driver_ids), '?')); // هنا نطبق الشروط الخاصة بهذا السكريبت (سيارات كهربائية فقط) $sql_drivers_info = " SELECT d.id AS driver_id, d.phone, d.email, d.birthdate, d.first_name, d.last_name, cr.make, cr.model, cr.color, cr.color_hex, cr.year, cr.fuel, dt.token, COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver, COALESCE(rdAvg.ratingCount, 0) AS ratingCount 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, COUNT(*) AS ratingCount FROM ratingDriver GROUP BY driver_id ) rdAvg ON rdAvg.driver_id = d.id WHERE d.id IN ($placeholders) AND cr.fuel = 'كهربائي' AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%') AND (cr.model NOT LIKE '%Van%' AND cr.make NOT LIKE '%Van%') "; $stmt_drivers_info = $con->prepare($sql_drivers_info); $stmt_drivers_info->execute($driver_ids); $drivers_info_raw = $stmt_drivers_info->fetchAll(PDO::FETCH_ASSOC); // تحويل المصفوفة لتسهيل عملية الدمج لاحقاً foreach ($drivers_info_raw as $driver) { $drivers_info[$driver['driver_id']] = $driver; } } // ================================================================= // الخطوة 4: دمج النتائج في PHP // ================================================================= $final_results = []; foreach ($locations as $location) { $driver_id = $location['driver_id']; // ندمج فقط السائقين الذين طابقوا شروطنا في الاستعلام الثاني if (isset($drivers_info[$driver_id])) { $final_results[] = array_merge($location, $drivers_info[$driver_id]); } } // ================================================================= // الخطوة 5: تطبيق الترتيب والحد النهائي في PHP // ================================================================= usort($final_results, function ($a, $b) { if ($a['ratingDriver'] != $b['ratingDriver']) { return $b['ratingDriver'] <=> $a['ratingDriver']; } if ($a['ratingCount'] != $b['ratingCount']) { return $b['ratingCount'] <=> $a['ratingCount']; } return strtotime($b['updated_at']) <=> strtotime($a['updated_at']); }); // وأخيراً، نأخذ أفضل 10 نتائج فقط $limited_results = array_slice($final_results, 0, 10); if (empty($limited_results)) { jsonError("No electric cars matching the criteria found."); exit; } // ================================================================= // الخطوة 6: فك التشفير وحساب العمر (بدون تغيير) // ================================================================= $fieldsToDecrypt = [ 'phone','email','gender','birthdate', 'first_name','last_name', 'token','car_plate','vin' ]; foreach ($limited_results as &$row) { foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && !empty($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; } } unset($row); jsonSuccess($limited_results); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Throwable $e) { jsonError("Internal error: " . $e->getMessage()); } ``` ## File: ride/location/addpassengerLocation.php ``` prepare($sql); // Bind the parameters to the SQL query $stmt->bindParam(':passengerId', $passengerId); $stmt->bindParam(':lat', $lat); $stmt->bindParam(':lng', $lng); $stmt->bindParam(':rideId', $rideId); // Execute the statement if ($stmt->execute()) { // Print a success message jsonSuccess(null, "Passenger location saved successfully"); } else { // Print a failure message jsonError("Failed to save passenger location"); } ?> ``` ## File: ride/payment/add.php ``` prepare("SELECT * FROM payment_tokens WHERE token = :token AND isUsed = FALSE"); $stmt->execute(array( ':token' => $token )); $tokenData = $stmt->fetch(); if ($tokenData) { $sql = "INSERT INTO `payments` (`id`,`amount`, `payment_method`, `passengerID`, `rideId`, `driverID`) VALUES ( SHA2(UUID(), 256),'$amount', '$payment_method', '$passengerID', '$rideId', '$driverID')"; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess(null, "Payment record created successfully"); // Mark the token as used in the database $stmt = $con->prepare("UPDATE payment_tokens SET isUsed = TRUE WHERE id = :tokenID"); $stmt->execute(array( ':tokenID' => $tokenData['id'] )); } else { // Print a failure message jsonError("Failed to save record"); } } else { jsonError("Invalid or already used token"); } ``` ## File: ride/payment/update.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = "Payment data updated successfully"); } else { // Print a failure message jsonError($message = "Failed to update payment data"); } ?> ``` ## File: ride/payment/get.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); $count = $stmt->rowCount(); // $response = array( // "message" => "Payment data saved successfully", // "id" => "0", // "count" => $count, // "data" => $rows // ); // echo json_encode($response); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/payment/getAllPayment.php ``` CURRENT_DATE() - INTERVAL 1 WEEK ) AS total_amount_last_week FROM dual LIMIT 1; "; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/payment/getAllPaymentVisa.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/payment/getCountRide.php ``` = CURDATE(); "; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/payment/updatePaymetToPaid.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = "Payment data updated successfully"); } else { // Print a failure message jsonError($message = "Failed to update payment data"); } ?> ``` ## File: ride/payment/delete.php ``` ``` ## File: ride/places/add.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = 'Place inserted successfully'); } else { // Print a failure message for duplicate jsonSuccess($message = 'Duplicate place, no new entry added'); } ?> ``` ## File: ride/cancelRide/add.php ``` prepare($sql); $stmt->bindParam(':driverID', $driverID); $stmt->bindParam(':passengerID', $passengerID); $stmt->bindParam(':rideID', $rideID); $stmt->bindParam(':note', $note); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Record inserted successfully"); } else { jsonError("Failed to insert record"); } ?> ``` ## File: ride/cancelRide/update.php ``` prepare($sql); $stmt->execute($params); // التحقق من النتيجة if ($stmt->rowCount() > 0) { jsonSuccess(null, "Data updated successfully"); } else { jsonError("Failed to update data or no changes made"); } ?> ``` ## File: ride/cancelRide/get.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($stmt->rowCount() > 0) { jsonSuccess($result); } else { jsonError("No records found"); } ?> ``` ## File: ride/cancelRide/addCancelTripFromDriverAfterApplied.php ``` $rideId]; try { // ================================================================================= // المرحلة الأولى: إلغاء الرحلة (نفس منطق السكريبت الأول) // ================================================================================= // 1. التحديث على سيرفر التتبع (Remote DB) error_log("🔄 [Step 1] Attempting to cancel on REMOTE Tracking DB..."); $stmtRemote = $con_ride->prepare($sqlCancel); $stmtRemote->execute($params); $count = $stmtRemote->rowCount(); // إذا نجح التحديث في السيرفر البعيد (أو لم ينجح نتحقق من المحلي أيضا لضمان التزامن) // لكن المنطق الأساسي يعتمد على أن الرحلة قابلة للتعديل if ($count > 0) { // 2. التحديث على السيرفر المحلي (Local DB) error_log("🔄 [Step 1] Remote success. Cancelling on LOCAL Main DB..."); $stmtLocal = $con->prepare($sqlCancel); $stmtLocal->execute($params); error_log("✅ [Step 1] Ride cancelled successfully on database."); // ================================================================================= // المرحلة الثانية: تسجيل الطلب وتنظيف البيانات (نفس منطق السكريبت الثاني) // لن يتم الدخول هنا إلا إذا نجح الإلغاء فعلياً // ================================================================================= error_log("🔄 [Step 2] Inserting into driver_orders and cleaning background tasks..."); // أ. إضافة سجل في driver_orders $orderStatus = 'pending'; // كما في السكريبت الثاني $sqlInsertOrder = "INSERT INTO driver_orders (driver_id, order_id, notes, status) VALUES (?, ?, ?, ?)"; $stmtInsert = $con->prepare($sqlInsertOrder); $stmtInsert->execute([$driverID, $rideId, $note, $orderStatus]); // ب. حذف آخر سجل من write_argument_after_applied_from_background // نستخدم نفس الاستعلام الفرعي الذي كنت تستخدمه $sqlDelete = "DELETE FROM write_argument_after_applied_from_background WHERE id = ( SELECT id FROM ( SELECT id FROM write_argument_after_applied_from_background WHERE driver_id = ? ORDER BY time_of_order DESC LIMIT 1 ) AS t )"; $stmtDelete = $con->prepare($sqlDelete); $stmtDelete->execute([$driverID]); error_log("✅ [Step 2] Driver order logged and background task cleaned."); // ================================================================================= // النهاية: إرجاع رسالة النجاح // ================================================================================= jsonSuccess(null, "Ride cancelled and driver log updated successfully"); } else { // فشل الإلغاء (الرحلة غير موجودة أو حالتها لا تسمح) error_log("⚠️ [cancelRideAndLog.php] Failed to cancel. Status might be started/completed or ID invalid."); jsonError("Cannot cancel ride. Status might be started or already completed."); } } catch (PDOException $e) { error_log("❌ [cancelRideAndLog.php] Database Error: " . $e->getMessage()); jsonError("Database Error: " . $e->getMessage()); */ require_once __DIR__ . '/../../connect.php'; $rideId = filterRequest("id"); $driverID = filterRequest("driver_id"); $note = filterRequest("notes"); $status = "cancelRideFromDriver"; if (!$rideId || !$driverID) { jsonError("Missing Data"); exit; } try { // 1. محاولة الإلغاء في السيرفر البعيد $stmtRemote = $con_ride->prepare("UPDATE `ride` SET `status` = ?, `updated_at` = NOW() WHERE `id` = ? AND `status` IN ('wait', 'waiting', 'Apply', 'accepted')"); $stmtRemote->execute([$status, $rideId]); if ($stmtRemote->rowCount() > 0) { // 2. التحديث المحلي $con->prepare("UPDATE `ride` SET `status` = ?, `updated_at` = NOW() WHERE `id` = ?")->execute([$status, $rideId]); // 3. تسجيل اللوج (كما في ملفك) $con->prepare("INSERT INTO driver_orders (driver_id, order_id, notes, status) VALUES (?, ?, ?, 'pending')")->execute([$driverID, $rideId, $note]); // تنظيف الخلفية (اختياري حسب الحاجة) // ... كود التنظيف ... // 4. 🔥 إشعار الراكب بالإلغاء 🔥 $stmtPas = $con->prepare("SELECT passenger_id FROM ride WHERE id = ?"); $stmtPas->execute([$rideId]); $passenger_id = $stmtPas->fetchColumn(); if ($passenger_id) { notifyPassengerOnRideServer($passenger_id, [ 'ride_id' => $rideId, 'status' => 'cancelled', 'msg' => 'نعتذر، قام السائق بإلغاء الرحلة' ]); } jsonSuccess(null, "Ride Cancelled"); } else { jsonError("Cannot cancel ride (Status might be started or finished)"); } } catch (PDOException $e) { jsonError("DB Error: " . $e->getMessage()); } ?> ?> ``` ## File: ride/cancelRide/delete.php ``` prepare($sql); $stmt->bindParam(":id", $id, PDO::PARAM_INT); // تأكيد أن id رقم $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Record deleted successfully"); } else { jsonError("Failed to delete record"); } ?> ``` ## File: ride/helpCenter/add.php ``` prepare($sql); $stmt->bindParam(':driverID', $driverID); $stmt->bindParam(':helpQuestion', $helpQuestion); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Help question saved successfully"); } else { jsonError("Failed to save help question"); } ?> ``` ## File: ride/helpCenter/update.php ``` prepare($sql); $stmt->bindParam(':helpQuestion', $newHelpQuestion); $stmt->bindParam(':id', $helpID, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Help question updated successfully"); } else { jsonError("Failed to update help question"); } ?> ``` ## File: ride/helpCenter/get.php ``` prepare($sql); $stmt->bindParam(':driverID', $driverID, PDO::PARAM_STR); $stmt->execute(); if ($stmt->rowCount() > 0) { $record = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($record); } else { jsonError("Help question not found"); } ?> ``` ## File: ride/helpCenter/getById.php ``` prepare($sql); $stmt->bindParam(':id', $helpID, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { $record = $stmt->fetch(PDO::FETCH_ASSOC); jsonSuccess($record); } else { jsonError("Help question not found"); } ?> ``` ## File: ride/helpCenter/delete.php ``` prepare($sql); $stmt->bindParam(':id', $helpID, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Help question deleted successfully"); } else { jsonError("Failed to delete help question"); } ?> ``` ## File: ride/feedBack/add.php ``` encryptData($feedBack); $sql = "INSERT INTO `feedBack`( `passengerId`, `feedBack`, `datecreated`) VALUES ( :passengerId, :feedBack, NOW() )"; $stmt = $con->prepare($sql); $stmt->bindParam(':passengerId', $passengerId); $stmt->bindParam(':feedBack', $feedBack); $stmt->execute(); if ($stmt->rowCount() > 0) { // Success response echo json_encode([ "status" => "success", "message" => "Feedback data saved successfully" ]); } else { // Failure response echo json_encode([ "status" => "failure", "message" => "Failed to save feedback data" ]); } ?> ``` ## File: ride/feedBack/update.php ``` ``` ## File: ride/feedBack/get.php ``` prepare($sql); $stmt->bindParam(':passengerId', $passengerId, PDO::PARAM_STR); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($result) { // Print all promo records jsonSuccess($result); } else { // Print a failure message jsonError($message = "Failed to retrieve promo records"); } ?> ``` ## File: ride/feedBack/delete.php ``` ``` ## File: ride/feedBack/add_solve_all.php ``` prepare("SELECT * FROM ride WHERE id = ? AND (status = 'Finished' OR status = 'Begin')"); $stmt->execute([$rideId]); $ride = $stmt->fetch(PDO::FETCH_ASSOC); if (!$ride) { // رسالة خطأ أوضح للمستخدم error_log("WARNING: Complaint filing failed for ride ID: $rideId. Ride not found or status is invalid."); // ⚠️ تسجيل الخطأ jsonError("Complaint cannot be filed for this ride. It may not have been completed or started."); exit; } $passengerId = $ride['passenger_id']; $driverId = $ride['driver_id']; // --- دوال مساعدة لجلب البيانات (تم افتراض أن الدوال تصل إلى $con و $encryptionHelper عبر النطاق global أو تمريرها كـ arguments) --- /** * جلب بيانات ومعلومات تقييم السائق */ function getDriverFullProfile($con, $encryptionHelper, $driverId) { $profile = ['info' => null, 'ratings' => null, 'comments' => []]; // جلب معلومات السائق الأساسية $stmt = $con->prepare("SELECT id, first_name, last_name, created_at FROM driver WHERE id = ?"); $stmt->execute([$driverId]); $driverInfo = $stmt->fetch(PDO::FETCH_ASSOC); // فك تشفير البيانات الحساسة if ($driverInfo) { // التحقق من وجود ودوال فك التشفير قبل الاستخدام if (isset($encryptionHelper) && method_exists($encryptionHelper, 'decryptData')) { $decryptedFirstName = $encryptionHelper->decryptData($driverInfo['first_name']); $decryptedLastName = $encryptionHelper->decryptData($driverInfo['last_name']); $driverInfo['full_name'] = trim($decryptedFirstName . ' ' . $decryptedLastName); } else { $driverInfo['full_name'] = 'Decryption Failed'; } unset($driverInfo['first_name'], $driverInfo['last_name']); // إزالة الحقول المشفرة $profile['info'] = $driverInfo; } // جلب ملخص التقييمات والتعليقات $stmt = $con->prepare("SELECT AVG(rating) as avg_rating, COUNT(id) as total_ratings FROM ratingDriver WHERE driver_id = ?"); $stmt->execute([$driverId]); $profile['ratings'] = $stmt->fetch(PDO::FETCH_ASSOC); $stmt = $con->prepare("SELECT comment FROM ratingDriver WHERE driver_id = ? AND comment IS NOT NULL AND comment != '' ORDER BY created_at DESC LIMIT 5"); $stmt->execute([$driverId]); $profile['comments'] = $stmt->fetchAll(PDO::FETCH_COLUMN); return $profile; } /** * جلب بيانات ومعلومات تقييم الراكب */ function getPassengerFullProfile($con, $encryptionHelper, $passengerId) { $profile = ['info' => null, 'ratings' => null, 'comments' => []]; $stmt = $con->prepare("SELECT id, first_name, last_name, created_at FROM passengers WHERE id = ?"); $stmt->execute([$passengerId]); $passengerInfo = $stmt->fetch(PDO::FETCH_ASSOC); // فك تشفير البيانات الحساسة if ($passengerInfo) { if (isset($encryptionHelper) && method_exists($encryptionHelper, 'decryptData')) { $decryptedFirstName = $encryptionHelper->decryptData($passengerInfo['first_name']); $decryptedLastName = $encryptionHelper->decryptData($passengerInfo['last_name']); $passengerInfo['full_name'] = trim($decryptedFirstName . ' ' . $decryptedLastName); } else { $passengerInfo['full_name'] = 'Decryption Failed'; } unset($passengerInfo['first_name'], $passengerInfo['last_name']); $profile['info'] = $passengerInfo; } $stmt = $con->prepare("SELECT AVG(rating) as avg_rating, COUNT(id) as total_ratings FROM ratingPassenger WHERE passenger_id = ?"); $stmt->execute([$passengerId]); $profile['ratings'] = $stmt->fetch(PDO::FETCH_ASSOC); $stmt = $con->prepare("SELECT comment FROM ratingPassenger WHERE passenger_id = ? AND comment IS NOT NULL AND comment != '' ORDER BY created_at DESC LIMIT 5"); $stmt->execute([$passengerId]); $profile['comments'] = $stmt->fetchAll(PDO::FETCH_COLUMN); return $profile; } /** * جلب بيانات سلوك السائق في الرحلة المحددة */ function getDriverBehavior($con, $rideId, $driverId) { $stmt = $con->prepare("SELECT max_speed, avg_speed, hard_brakes, behavior_score FROM driver_behavior WHERE trip_id = ? AND driver_id = ?"); $stmt->execute([$rideId, $driverId]); return $stmt->fetch(PDO::FETCH_ASSOC) ?: null; } // استدعاء الدوال لجلب البيانات $passengerProfile = getPassengerFullProfile($con, $encryptionHelper, $passengerId); $driverProfile = getDriverFullProfile($con, $encryptionHelper, $driverId); $driverBehavior = getDriverBehavior($con, $rideId, $driverId); // --- 4. بناء الـ Prompt وإرساله إلى Gemini --- $prompt = " أنت خبير في حل النزاعات في خدمات نقل الركاب لتطبيق intaleqapp.com. قم بتحليل الشكوى التالية بين راكب وسائق بناءً على البيانات الشاملة التالية: **1. تفاصيل الرحلة:** " . json_encode($ride, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . " **2. ملف الراكب:** " . json_encode($passengerProfile, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . " **3. ملف السائق:** " . json_encode($driverProfile, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . " **4. بيانات سلوك السائق (في هذه الرحلة):** " . json_encode($driverBehavior, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . " **5. الشكوى نفسها:** - نص الشكوى من الراكب: '" . $complaintText . "' - رابط تسجيل صوتي للشكوى (إن وجد): " . $audioLink . " **مهمتك هي:** 1. تحليل جميع البيانات المتاحة لتحديد الطرف المخطئ على الأرجح. 2. تحديد ما إذا كانت الشكوى كيدية أم حقيقية. 3. **تصنيف الشكوى** (مثال: سلوك السائق، مشكلة في الأجرة، مسار الرحلة، حالة السيارة، أخرى). 4. اقتراح حلين واضحين ومختلفين لفريق خدمة العملاء. 5. كتابة تقرير موجز ومناسب للراكب. 6. كتابة تقرير موجز ومناسب للسائق. **الخرج المطلوب:** أعد الرد بصيغة JSON فقط، بدون أي نصوص إضافية، وباللغة العربية (لهجة مصرية)، بالهيكل التالي: { \"customerServiceSolutions\": [\"الحل المقترح الأول\", \"الحل المقترح الثاني\"], \"passengerReport\": { \"title\": \"بخصوص شكوتك في رحلة Siro\", \"body\": \"رسالة واضحة للراكب بنتيجة الشكوى\" }, \"driverReport\": { \"title\": \"بخصوص بلاغ رحلتك الأخيرة في Siro\", \"body\": \"رسالة واضحة للسائق بنتيجة الشكوى\" }, \"fault_determination\": \"الطرف المخطئ (الراكب/السائق/كلاهما/غير واضح)\", \"complaint_nature\": \"طبيعة الشكوى (حقيقية/كيدية/نزاع بسيط)\", \"complaint_type\": \"تصنيف الشكوى الذي حددته\" } "; // استخدام نموذج Gemini 1.5 Flash Lite $apiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-lite-latest:generateContent?key=$geminiApiKey"; $headers = ["Content-Type: application/json"]; $payload = ['contents' => [['parts' => [['text' => $prompt]]]]]; error_log("INFO: Submitting complaint analysis to Gemini for ride ID: $rideId."); // ℹ️ تسجيل الحدث $ch = curl_init($apiURL); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_TIMEOUT => 60 ]); $response = curl_exec($ch); if (curl_errno($ch)) { $errorMsg = curl_error($ch); error_log("ERROR: AI Service Curl Error for ride $rideId: $errorMsg"); // ⚠️ تسجيل الخطأ jsonError("AI Service Error: " . $errorMsg); curl_close($ch); exit; } curl_close($ch); $data = json_decode($response, true); $analysisResultText = $data['candidates'][0]['content']['parts'][0]['text'] ?? ''; $analysisResultJson = trim(preg_replace('/```json|```/', '', $analysisResultText)); $analysisResult = json_decode($analysisResultJson, true); if (json_last_error() !== JSON_ERROR_NONE || !isset($analysisResult['passengerReport']) || !isset($analysisResult['driverReport'])) { error_log("ERROR: Failed to parse AI response for ride $rideId. Raw Response: " . substr($response, 0, 500)); // ⚠️ تسجيل الخطأ jsonError("Failed to parse AI response. Please try again later."); exit; } error_log("INFO: Gemini analysis successful for ride $rideId. Type: " . ($analysisResult['complaint_type'] ?? 'N/A')); // ℹ️ تسجيل الحدث // --- 5. تنفيذ الإجراءات بناءً على التحليل --- // تجميع الوصف الكامل للشكوى $fullDescription = $complaintText; if (!empty($audioLink)) { $fullDescription .= "\n\n[رابط صوتي مرفق: " . $audioLink . "]"; } // ** التعديل: تم تحديث جملة الحفظ لتشمل جميع مخرجات التحليل ** $stmt = $con->prepare(" INSERT INTO complaint ( ride_id, passenger_id, driver_id, complaint_type, description, date_filed, statusComplaint, resolution, passenger_report, driver_report, cs_solutions, fault_determination, complaint_nature, date_resolved ) VALUES (?, ?, ?, ?, ?, NOW(), ?, ?, ?, ?, ?, ?, ?, NOW()) "); try { $success = $stmt->execute([ $rideId, $passengerId, $driverId, $analysisResult['complaint_type'] ?? 'General', $fullDescription, 'Resolved', // statusComplaint $analysisResultJson, // resolution (الـ JSON الكامل) json_encode($analysisResult['passengerReport'] ?? null, JSON_UNESCAPED_UNICODE), // passenger_report json_encode($analysisResult['driverReport'] ?? null, JSON_UNESCAPED_UNICODE), // driver_report json_encode($analysisResult['customerServiceSolutions'] ?? null, JSON_UNESCAPED_UNICODE), // cs_solutions $analysisResult['fault_determination'] ?? 'N/A', // fault_determination $analysisResult['complaint_nature'] ?? 'N/A' // complaint_nature ]); if (!$success) { // يمكنك تسجيل رسالة الخطأ من PDO إذا كانت متاحة (للتصحيح فقط وليس للإنتاج) error_log("CRITICAL: Failed to save complaint to DB for ride $rideId. PDO Error Info: " . json_encode($stmt->errorInfo())); // ⚠️ تسجيل الخطأ } $complaintId = $con->lastInsertId(); error_log("SUCCESS: Complaint ID $complaintId processed and saved for ride $rideId."); // ✅ تسجيل النجاح } catch (PDOException $e) { error_log("CRITICAL: PDO Exception when saving complaint for ride $rideId: " . $e->getMessage()); // ⚠️ تسجيل خطأ قاعدة البيانات jsonError("A database error occurred while saving the complaint."); exit; } // إرسال رسالة WhatsApp لخدمة العملاء if (function_exists('sendWhatsAppFromServer') && !empty($customerServiceWhatsapp)) { $csMessage = "*شكوى جديدة (رقم $complaintId)*\n" . "*- الرحلة:* $rideId\n" . "*- تصنيف الشكوى:* " . ($analysisResult['complaint_type'] ?? 'غير محدد') . "\n" . "*- المخطئ (تقدير النظام):* " . $analysisResult['fault_determination'] . "\n" . "*- طبيعة الشكوى:* " . $analysisResult['complaint_nature'] . "\n\n" . "*حلول مقترحة:*\n1. " . ($analysisResult['customerServiceSolutions'][0] ?? 'N/A') . "\n" . "2. " . ($analysisResult['customerServiceSolutions'][1] ?? 'N/A'); sendWhatsAppFromServer($customerServiceWhatsapp, $csMessage); error_log("INFO: WhatsApp notification sent to customer service for complaint ID $complaintId."); // ℹ️ تسجيل الحدث } // --- 6. إرسال الرد النهائي للتطبيق --- printSuccess([ 'message' => 'Complaint processed successfully.', 'passenger_response' => $analysisResult['passengerReport'], 'driver_response' => $analysisResult['driverReport'] ]); ?> ``` ## File: ride/driverPayment/add.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $insertedID = $con->lastInsertId(); // Get the last inserted ID jsonSuccess($message = $insertedID); } else { $response = array( "success" => false, "message" => "Failed to save payment data" ); echo json_encode($response); } ?> ``` ## File: ride/driverPayment/update.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message echo "Record updated successfully"; } else { // Print a failure message echo "Failed to update the record"; } ?> ``` ## File: ride/driverPayment/get.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else { // No records found echo "No records found."; } ?> ``` ## File: ride/driverPayment/delete.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message echo "Record deleted successfully"; } else { // Print a failure message echo "Failed to delete the record"; } ?> ``` ## File: ride/kazan/add.php ``` prepare($sql); // Bind the parameters to the SQL query $stmt->bindParam(':kazan', $kazan); $stmt->bindParam(':comfortPrice', $comfortPrice); $stmt->bindParam(':speedPrice', $speedPrice); $stmt->bindParam(':deliveryPrice', $deliveryPrice); $stmt->bindParam(':freePrice', $freePrice); $stmt->bindParam(':latePrice', $latePrice); $stmt->bindParam(':heavyPrice', $heavyPrice); $stmt->bindParam(':adminId', $adminId); $stmt->bindParam(':naturePrice', $naturePrice); $stmt->bindParam(':country', $country); $stmt->bindParam(':fuelPrice', $fuelPrice); // Execute the statement if ($stmt->execute()) { // Print a success message jsonSuccess(null, "Kazan saved successfully"); } else { // Print a failure message jsonError("Failed to save Kazan"); } // Close the statement $stmt->close(); ?> ``` ## File: ride/kazan/update.php ``` prepare($sql); $stmt->execute($params); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Kazan data updated successfully"); } else { jsonError("Failed to update kazan data"); } ?> ``` ## File: ride/kazan/get.php ``` prepare($sql); $stmt->bindParam(':country', $country, PDO::PARAM_STR); $stmt->execute(); $row = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($row) { jsonSuccess($row); } else { jsonError("No Kazan record found"); } ?> ``` ## File: ride/kazan/delete.php ``` ``` ## File: ride/apiKey/add.php ``` ``` ## File: ride/apiKey/update.php ``` ``` ## File: ride/apiKey/get.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); return $result; } ?> ``` ## File: ride/apiKey/delete.php ``` ``` ## File: ride/firebase/addToken.php ``` encryptData($token); // التحقق مما إذا كان السجل موجودًا $sqlCheck = "SELECT * FROM `tokens` WHERE `passengerID` = :passengerID"; $stmtCheck = $con->prepare($sqlCheck); $stmtCheck->bindParam(':passengerID', $passengerID); $stmtCheck->execute(); $result = $stmtCheck->fetch(PDO::FETCH_ASSOC); if ($result) { // تحديث السجل الموجود $sqlUpdate = "UPDATE `tokens` SET `token` = :token, `fingerPrint` = :fingerPrint WHERE `passengerID` = :passengerID"; $stmtUpdate = $con->prepare($sqlUpdate); $stmtUpdate->bindParam(':token', $tokenEncrypted); $stmtUpdate->bindParam(':fingerPrint', $fingerPrint); // بدون تشفير إضافي $stmtUpdate->bindParam(':passengerID', $passengerID); $stmtUpdate->execute(); jsonSuccess(null, "Token updated successfully"); } else { // إدخال سجل جديد $sqlInsert = "INSERT INTO `tokens` (`token`, `passengerID`, `fingerPrint`) VALUES (:token, :passengerID, :fingerPrint)"; $stmtInsert = $con->prepare($sqlInsert); $stmtInsert->bindParam(':token', $tokenEncrypted); $stmtInsert->bindParam(':passengerID', $passengerID); $stmtInsert->bindParam(':fingerPrint', $fingerPrint); // بدون تشفير إضافي $stmtInsert->execute(); if ($stmtInsert->rowCount() > 0) { jsonSuccess(null, "Token inserted successfully"); } else { jsonError("Failed to insert token"); } } ?> ``` ## File: ride/firebase/add.php ``` encryptData($token); // التحقق مما إذا كان السجل موجودًا $sqlCheck = "SELECT * FROM `tokens` WHERE `passengerID` = :passengerID"; $stmtCheck = $con->prepare($sqlCheck); $stmtCheck->bindParam(':passengerID', $passengerID); $stmtCheck->execute(); $result = $stmtCheck->fetch(PDO::FETCH_ASSOC); if ($result) { // تحديث السجل الموجود $sqlUpdate = "UPDATE `tokens` SET `token` = :token, `fingerPrint` = :fingerPrint WHERE `passengerID` = :passengerID"; $stmtUpdate = $con->prepare($sqlUpdate); $stmtUpdate->bindParam(':token', $tokenEncrypted); $stmtUpdate->bindParam(':fingerPrint', $fingerPrint); // بدون تشفير إضافي $stmtUpdate->bindParam(':passengerID', $passengerID); $stmtUpdate->execute(); jsonSuccess(null, "Token updated successfully"); } else { // إدخال سجل جديد $sqlInsert = "INSERT INTO `tokens` (`token`, `passengerID`, `fingerPrint`) VALUES (:token, :passengerID, :fingerPrint)"; $stmtInsert = $con->prepare($sqlInsert); $stmtInsert->bindParam(':token', $tokenEncrypted); $stmtInsert->bindParam(':passengerID', $passengerID); $stmtInsert->bindParam(':fingerPrint', $fingerPrint); // بدون تشفير إضافي $stmtInsert->execute(); if ($stmtInsert->rowCount() > 0) { jsonSuccess(null, "Token inserted successfully"); } else { jsonError("Failed to insert token"); } } ?> ``` ## File: ride/firebase/get.php ``` prepare($sql); $stmt->bindParam(':passengerID', $passengerID, PDO::PARAM_STR); $stmt->execute(); $data = $stmt->fetch(PDO::FETCH_ASSOC); if ($data) { // فك تشفير التوكن فقط $data['token'] = $encryptionHelper->decryptData($data['token']); jsonSuccess($data); } else { jsonError("No token found for this passenger"); } ?> ``` ## File: ride/firebase/getTokensPassenger.php ``` prepare($sql); $stmt->bindParam(':passengerID', $passengerID, PDO::PARAM_STR); $stmt->execute(); $data = $stmt->fetch(PDO::FETCH_ASSOC); if ($data) { // فك تشفير التوكن فقط $data['token'] = $encryptionHelper->decryptData($data['token']); jsonSuccess($data); } else { jsonError("No token found for this passenger"); } ?> ``` ## File: ride/firebase/fcm_fun.php ``` 'RS256', 'typ' => 'JWT'])); $claim = base64UrlEncode(json_encode([ 'iss' => $clientEmail, 'scope' => 'https://www.googleapis.com/auth/firebase.messaging', 'aud' => 'https://oauth2.googleapis.com/token', 'exp' => $now + 3600, 'iat' => $now ])); $signature = ''; openssl_sign("$header.$claim", $signature, $privateKey, 'SHA256'); $jwt = "$header.$claim." . base64UrlEncode($signature); $ch = curl_init("https://oauth2.googleapis.com/token"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $res = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode != 200) { error_log("❌ FCM OAuth Error ($httpCode): $res"); return null; } return json_decode($res, true)['access_token'] ?? null; } // ============================================================================ // 🔥 الدالة الرئيسية: إرسال إشعار FCM (داخلي - بدون HTTP) // ============================================================================ function sendFCMNotification($params) { // استخراج البارامترات $token = $params['token'] ?? null; $title = $params['title'] ?? ''; $body = $params['body'] ?? ''; $category = $params['category'] ?? ''; $data = $params['data'] ?? []; $tone = $params['tone'] ?? 'default'; $isTopic = $params['isTopic'] ?? false; $serviceAccountPath = $params['service_account_path'] ?? __DIR__ . '/service-account.json'; // التحقق من البيانات الأساسية if (empty($token) || empty($title) || empty($body)) { error_log("❌ FCM: Missing required fields (token, title, or body)"); return [ 'success' => false, 'error' => 'Missing required parameters', 'http_code' => 400 ]; } // الحصول على Access Token $accessToken = getFCMAccessToken($serviceAccountPath); if (!$accessToken) { return [ 'success' => false, 'error' => 'Failed to get Access Token', 'http_code' => 500 ]; } // جلب Project ID $creds = json_decode(file_get_contents($serviceAccountPath), true); $projectId = $creds['project_id']; $fcmUrl = "https://fcm.googleapis.com/v1/projects/$projectId/messages:send"; // بناء الـ Payload $messagePayload = [ 'message' => [ 'notification' => [ 'title' => $title, 'body' => $body ], 'android' => [ 'priority' => 'HIGH', 'notification' => [ 'sound' => $tone, 'channel_id' => 'high_importance_channel' ] ], 'apns' => [ 'headers' => ['apns-priority' => '10'], 'payload' => [ 'aps' => [ 'sound' => $tone . '.caf', 'content-available' => 1 ] ] ] ] ]; // تحديد الهدف if ($isTopic) { $messagePayload['message']['topic'] = $token; } else { $messagePayload['message']['token'] = $token; } // إضافة الـ Data Payload $customData = ['category' => (string)$category]; if (is_array($data) && !empty($data)) { $customData = array_merge($customData, $data); } // تحويل كل القيم إلى String (FCM requirement) $processedData = []; foreach ($customData as $key => $val) { if (is_array($val) || is_object($val)) { $processedData[$key] = json_encode($val, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } else { $processedData[$key] = (string)$val; } } $messagePayload['message']['data'] = $processedData; // الإرسال إلى FCM $ch = curl_init($fcmUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $accessToken, 'Content-Type: application/json; charset=UTF-8' ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($messagePayload, JSON_UNESCAPED_UNICODE)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlError = curl_error($ch); curl_close($ch); // معالجة النتيجة if ($httpCode == 200) { error_log("✅ FCM Sent: Category=$category, Token=" . substr($token, 0, 15) . "..."); return [ 'success' => true, 'http_code' => $httpCode, 'response' => json_decode($result, true) ]; } else { error_log("❌ FCM Error ($httpCode): $result | CURL: $curlError"); return [ 'success' => false, 'http_code' => $httpCode, 'error' => json_decode($result, true), 'curl_error' => $curlError ]; } } // ============================================================================ // 🎯 دوال مُساعدة جاهزة للاستخدام المباشر // ============================================================================ /** * إرسال إشعار "وصول السائق" */ function notifyDriverArrival($passengerToken, $driverName, $rideId) { return sendFCMNotification([ 'token' => $passengerToken, 'title' => "السائق وصل إليك 📍", 'body' => "$driverName في انتظارك الآن.", 'category' => 'Arrive Ride', 'tone' => 'tone1', 'data' => [ 'ride_id' => (string)$rideId, 'timestamp' => date('Y-m-d H:i:s') ] ]); } /** * إرسال إشعار "بدأت الرحلة" */ function notifyTripBegin($passengerToken, $driverName, $rideId) { return sendFCMNotification([ 'token' => $passengerToken, 'title' => "بدأت الرحلة 🚗", 'body' => "السائق $driverName بدأ رحلتك الآن.", 'category' => 'Trip is Begin', 'tone' => 'start', 'data' => [ 'ride_id' => (string)$rideId, 'start_time' => date('Y-m-d H:i:s') ] ]); } /** * إرسال إشعار "قبول الطلب" */ function notifyRideAccepted($passengerToken, $driverInfo, $rideId) { return sendFCMNotification([ 'token' => $passengerToken, 'title' => "تم قبول الطلب 🚖", 'body' => "الكابتن {$driverInfo['driverName']} قادم إليك.", 'category' => 'Accepted Ride', 'tone' => 'start', 'data' => [ 'ride_id' => (string)$rideId, 'driver_id' => (string)$driverInfo['driverId'], 'driver_info' => $driverInfo // سيتم تحويلها لـ JSON تلقائياً ] ]); } /** * إرسال إشعار "إلغاء الرحلة من السائق" */ function notifyRideCancelled($passengerToken, $rideId, $reason = '') { return sendFCMNotification([ 'token' => $passengerToken, 'title' => "تم إلغاء الرحلة ❌", 'body' => "السائق اعتذر عن إكمال الرحلة.", 'category' => 'Cancel Trip from driver', 'tone' => 'cancel', 'data' => [ 'ride_id' => (string)$rideId, 'reason' => $reason, 'cancelled_at' => date('Y-m-d H:i:s') ] ]); } /** * إرسال إشعار "انتهاء الرحلة" */ function notifyTripFinished($passengerToken, $tripData) { return sendFCMNotification([ 'token' => $passengerToken, 'title' => "انتهت الرحلة 🏁", 'body' => "شكرًا لاستخدامك تطبيق Tripz", 'category' => 'Driver Finish Trip', 'tone' => 'default', 'data' => [ 'DriverList' => $tripData // Array سيتم تحويلها لـ JSON ] ]); } ?> ``` ## File: ride/firebase/getTokenParent.php ``` encryptData($phone); // 1️⃣ جلب passengerID بناءً على رقم الهاتف $sql = "SELECT `id` FROM `passengers` WHERE `phone` = :phone"; $stmt = $con->prepare($sql); $stmt->bindParam(':phone', $phoneEncrypted); $stmt->execute(); $data = $stmt->fetch(PDO::FETCH_ASSOC); if ($data) { $passengerID = $data['id']; } else { jsonError("No passenger found for the given phone number"); exit; } // 2️⃣ جلب التوكنات المرتبطة بـ passengerID $sql1 = "SELECT * FROM `tokens` WHERE `passengerID` = :passengerID"; $stmt = $con->prepare($sql1); $stmt->bindParam(':passengerID', $passengerID); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($data) { // فك تشفير التوكن فقط foreach ($data as &$row) { $row['token'] = $encryptionHelper->decryptData($row['token']); // fingerPrint يبقى كما هو } echo json_encode([ 'status' => 'success', 'count' => count($data), 'data' => $data ]); } else { jsonError("No tokens found for the passenger"); } ?> ``` ## File: ride/firebase/addDriver.php ``` encryptData($token); // التحقق مما إذا كان السجل موجودًا $sqlCheck = "SELECT * FROM `driverToken` WHERE `captain_id` = :captain_id"; $stmtCheck = $con->prepare($sqlCheck); $stmtCheck->bindParam(':captain_id', $captain_id); $stmtCheck->execute(); $result = $stmtCheck->fetch(PDO::FETCH_ASSOC); if ($result) { // تحديث السجل $sqlUpdate = "UPDATE `driverToken` SET `token` = :token, `fingerPrint` = :fingerPrint WHERE `captain_id` = :captain_id"; $stmtUpdate = $con->prepare($sqlUpdate); $stmtUpdate->bindParam(':token', $tokenEncrypted); $stmtUpdate->bindParam(':fingerPrint', $fingerPrint); // بدون إعادة تشفير $stmtUpdate->bindParam(':captain_id', $captain_id); $stmtUpdate->execute(); jsonSuccess(null, "Token updated successfully"); } else { // إدخال سجل جديد $sqlInsert = "INSERT INTO `driverToken` (`token`, `captain_id`, `fingerPrint`) VALUES (:token, :captain_id, :fingerPrint)"; $stmtInsert = $con->prepare($sqlInsert); $stmtInsert->bindParam(':token', $tokenEncrypted); $stmtInsert->bindParam(':captain_id', $captain_id); $stmtInsert->bindParam(':fingerPrint', $fingerPrint); // بدون إعادة تشفير $stmtInsert->execute(); if ($stmtInsert->rowCount() > 0) { jsonSuccess(null, "Token inserted successfully"); } else { jsonError("Failed to insert token"); } } ?> ``` ## File: ride/firebase/notify_driver_arrival.php ``` 'test'], // بيانات إضافية بسيطة "General" // التصنيف ); // 3. طباعة النتيجة //echo "النتيجة:\n"; print_r($result); ?> ``` ## File: ride/firebase/getAllTokenPassengers.php ``` prepare($sql); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($data) { // فك تشفير token فقط foreach ($data as &$item) { $item['token'] = $encryptionHelper->decryptData($item['token']); // fingerPrint يبقى كما هو (مشفّر من التطبيق) } echo json_encode([ 'status' => 'success', 'data' => $data ]); } else { jsonError("No token records found"); } ?> ``` ## File: ride/firebase/delete.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Token deleted successfully"); } else { jsonError("Failed to delete token"); } ?> ``` ## File: ride/firebase/getDriverToken.php ``` prepare($sql); $stmt->bindParam(':captain_id', $captain_id, PDO::PARAM_STR); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($data) { // فك تشفير token فقط foreach ($data as &$item) { $item['token'] = $encryptionHelper->decryptData($item['token']); // fingerPrint يبقى كما هو } echo json_encode([ 'status' => 'success', 'data' => $data ]); } else { jsonError("No driver token found"); } ?> ``` ## File: ride/firebase/send_fcm.php ``` 'error', 'message' => 'Only POST allowed.']); exit; } // استقبال البيانات $json_input = file_get_contents('php://input'); $requestData = json_decode($json_input, true); $target = $requestData['target'] ?? null; $title = $requestData['title'] ?? null; $body = $requestData['body'] ?? null; $isTopic = $requestData['isTopic'] ?? false; $tone = $requestData['tone'] ?? 'default'; $customData = $requestData['data'] ?? []; if (!$target) { http_response_code(400); echo json_encode(['status' => 'error', 'message' => 'Missing: target, title, or body.']); exit; } // ============================================================================ // دالة Base64 URL-Safe Encoding (ضرورية للـ JWT) // ============================================================================ function base64UrlEncode($data) { return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); } // ============================================================================ // دالة المصادقة (Google OAuth2) // ============================================================================ function getAccessToken($credentialsPath) { if (!file_exists($credentialsPath)) return null; $credentials = json_decode(file_get_contents($credentialsPath), true); $clientEmail = $credentials['client_email']; $privateKey = $credentials['private_key']; $now = time(); $header = base64UrlEncode(json_encode(['alg' => 'RS256', 'typ' => 'JWT'])); $claim = base64UrlEncode(json_encode([ 'iss' => $clientEmail, 'scope' => 'https://www.googleapis.com/auth/firebase.messaging', 'aud' => 'https://oauth2.googleapis.com/token', 'exp' => $now + 3600, 'iat' => $now ])); $signature = ''; openssl_sign("$header.$claim", $signature, $privateKey, 'SHA256'); $jwt = "$header.$claim." . base64UrlEncode($signature); $ch = curl_init("https://oauth2.googleapis.com/token"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($ch); curl_close($ch); return json_decode($res, true)['access_token'] ?? null; } // الحصول على Access Token $accessToken = getAccessToken($serviceAccountFile); if (!$accessToken) { http_response_code(500); echo json_encode(['status' => 'error', 'message' => 'Failed to get Access Token.']); exit; } // جلب Project ID $creds = json_decode(file_get_contents($serviceAccountFile), true); $projectId = $creds['project_id']; $fcmUrl = "https://fcm.googleapis.com/v1/projects/$projectId/messages:send"; // ============================================================================ // بناء هيكل الرسالة // ============================================================================ $messagePayload = [ 'message' => [ 'notification' => [ 'title' => $title, 'body' => $body ], 'android' => [ 'priority' => 'HIGH', 'notification' => [ 'sound' => $tone, 'channel_id' => 'high_importance_channel' // تأكد من تطابقه مع Android ] ], 'apns' => [ 'headers' => ['apns-priority' => '10'], 'payload' => [ 'aps' => [ 'sound' => $tone . '.caf', 'content-available' => 1 ] ] ] ] ]; // تحديد الهدف (Topic أو Token) if ($isTopic) { $messagePayload['message']['topic'] = $target; } else { $messagePayload['message']['token'] = $target; } // ============================================================================ // 🔥 معالجة Data Payload (يجب أن تكون String: String فقط) // ============================================================================ if (!empty($customData)) { $processedData = []; foreach ($customData as $key => $val) { if (is_array($val) || is_object($val)) { // تحويل المصفوفات/الكائنات إلى JSON String $processedData[$key] = json_encode($val, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } else { // تحويل أي قيمة أخرى إلى String $processedData[$key] = (string)$val; } } $messagePayload['message']['data'] = $processedData; } // ============================================================================ // الإرسال الفعلي إلى FCM // ============================================================================ $ch = curl_init($fcmUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $accessToken, 'Content-Type: application/json; charset=UTF-8' ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($messagePayload, JSON_UNESCAPED_UNICODE)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // الرد if ($httpCode == 200) { echo json_encode([ 'status' => 'success', 'message' => 'Notification sent successfully', 'fcm_response' => json_decode($result) ], JSON_UNESCAPED_UNICODE); } else { http_response_code($httpCode); echo json_encode([ 'status' => 'error', 'message' => 'FCM request failed', 'fcm_response' => json_decode($result) ], JSON_UNESCAPED_UNICODE); } ?> ``` ## File: ride/firebase/getALlTokenDrivers.php ``` prepare($sql); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($data) { // فك تشفير token فقط لكل سجل foreach ($data as &$item) { $item['token'] = $encryptionHelper->decryptData($item['token']); // لا يتم فك تشفير fingerPrint لأنه مشفّر من Flutter } echo json_encode([ 'status' => 'success', 'data' => $data ]); } else { jsonError("No driver tokens found"); } ?> ``` ## File: ride/RegisrationCar/add.php ``` $driverID, 'vin' => $vin, 'car_plate' => $carPlate, 'make' => $make, 'model' => $model, 'year' => $year, 'expirationDate' => $expirationDate, 'color' => $color, 'owner' => $owner, 'colorHex' => $colorHex, 'fuel' => $fuel, ]; foreach ($required as $field => $val) { if ($val === null || $val === '') { jsonError("Missing required field: $field"); exit; } } /* ───── 3) تشفير الحقول الحساسة ───── */ $vin = $encryptionHelper->encryptData($vin); $carPlate = $encryptionHelper->encryptData($carPlate); $owner = $encryptionHelper->encryptData($owner); /* ───── 4) هل لدى السائق مركبة مُسجلة سابقًا؟ ───── */ $hasCar = $con->prepare("SELECT 1 FROM CarRegistration WHERE driverID = :d LIMIT 1"); $hasCar->execute([':d' => $driverID]); $isDefault = $hasCar->rowCount() === 0 ? 1 : 0; /* ───── 5) إدراج السجل ───── */ $sql = " INSERT INTO CarRegistration ( driverID, vin, car_plate, make, model, year, expiration_date, color, owner, color_hex, fuel, isDefault, created_at, status ) VALUES ( :driverID, :vin, :carPlate, :make, :model, :year, :expirationDate, :color, :owner, :colorHex, :fuel, :isDefault, NOW(), 'yet' ) "; $ins = $con->prepare($sql); $ins->execute([ ':driverID' => $driverID, ':vin' => $vin, ':carPlate' => $carPlate, ':make' => $make, ':model' => $model, ':year' => $year, ':expirationDate' => $expirationDate, ':color' => $color, ':owner' => $owner, ':colorHex' => $colorHex, ':fuel' => $fuel, ':isDefault' => $isDefault, ]); if ($ins->rowCount() > 0) { jsonSuccess(null, "Car registration saved."); } else { jsonError("Failed to save car registration."); } ``` ## File: ride/RegisrationCar/selectDriverAndCarForMishwariTrip.php ``` = NOW() - INTERVAL 1 DAY AND cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%' ) SELECT d.id AS driver_id, d.phone, d.gender, d.name_arabic AS name_arabic, d.name_english, d.address, ll.latitude, ll.longitude, FLOOR(DATEDIFF(CURDATE(), STR_TO_DATE(CONCAT(d.birthdate, '-01-01'), '%Y-%m-%d')) / 365.25) AS age, c.car_plate, c.make, c.model, c.year, c.color, c.fuel, c.displacement, c.color_hex, dt.token, COALESCE(avg_rating.rating, 5) AS rating, COALESCE(ride_count.count, 0) AS ride_count FROM driver d JOIN CarRegistration c ON c.driverID = d.id JOIN LatestLocations ll ON ll.driver_id = d.id AND ll.row_num = 1 LEFT JOIN driverToken dt ON dt.captain_id = d.id LEFT JOIN ( SELECT driver_id, AVG(rating) AS rating FROM ratingDriver GROUP BY driver_id ) avg_rating ON avg_rating.driver_id = d.id LEFT JOIN ( SELECT driver_id, COUNT(*) AS count FROM ride WHERE status = 'Finished' GROUP BY driver_id ) ride_count ON ride_count.driver_id = d.id WHERE c.year BETWEEN ? AND ? ORDER BY rating DESC, c.year DESC, ride_count DESC LIMIT 10"; $stmt = $con->prepare($sql); $stmt->execute([ $swLat, $neLat, $swLon, $neLon, $yearMin, $yearMax, $yearMin, $yearMax ]); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير عن الحقول الحساسة foreach ($rows as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); $row['gender'] = $encryptionHelper->decryptData($row['gender']); $row['name_arabic'] = $encryptionHelper->decryptData($row['name_arabic']); $row['name_english'] = $encryptionHelper->decryptData($row['name_english']); $row['address'] = $encryptionHelper->decryptData($row['address']); $row['car_plate'] = $encryptionHelper->decryptData($row['car_plate']); $row['token'] = $encryptionHelper->decryptData($row['token']); } if (count($rows) > 0) { jsonSuccess($rows); } else { jsonError("No drivers found in the specified area"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Exception $e) { jsonError("Error: " . $e->getMessage()); } ``` ## File: ride/RegisrationCar/update.php ``` encryptData($value); } $columnValues[$column] = $value; } } } // بناء جملة SET للتحديث $setClause = []; foreach ($columnValues as $column => $value) { $setClause[] = "`$column` = :$column"; } $setClause = implode(", ", $setClause); // التحقق من وجود بيانات للتحديث if (empty($setClause)) { jsonError("No data provided to update."); exit(); } // ✅ تأكد من اسم الجدول الصحيح $sql = "UPDATE `CarRegistration` SET $setClause WHERE `driverID` = :driverID AND `id` = :id"; $stmt = $con->prepare($sql); // ربط القيم بالاستعلام foreach ($columnValues as $column => $value) { $stmt->bindValue(":$column", $value); } $stmt->bindValue(':driverID', $driverID); $stmt->bindValue(':id', $id); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Car registration data updated successfully"); } else { jsonError("Failed to update car registration data"); } ?> ``` ## File: ride/RegisrationCar/get.php ``` ``` ## File: ride/RegisrationCar/makeDefaultCar.php ``` prepare($sql1); $stmt1->bindParam(':driverID', $driverID); $stmt1->execute(); // ثانياً: تعيين السيارة المحددة كافتراضية $sql2 = "UPDATE `CarRegistration` SET `isDefault` = 1 WHERE `id` = :id"; $stmt2 = $con->prepare($sql2); $stmt2->bindParam(':id', $id); $stmt2->execute(); if ($stmt2->rowCount() > 0) { jsonSuccess(null, "Default car updated successfully."); } else { jsonError("Failed to update default car."); } } catch (PDOException $e) { error_log("DB Error: " . $e->getMessage()); jsonError("Database error occurred."); } ?> ``` ## File: ride/RegisrationCar/delete.php ``` ``` ## File: ride/videos_driver/get.php ``` prepare($sql); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($data) { jsonSuccess($data); } else { jsonError("No video records found"); } ?> ``` ## File: ride/egyptPhones/add.php ``` prepare($sql); $stmt->bindParam(':phones', $phones); $stmt->bindParam(':name', $name); $stmt->bindParam(':phones2', $phones2); try { $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = "Contact data saved successfully"); } else { // Print a failure message jsonError($message = "Failed to save contact data"); } } catch (PDOException $e) { // Print error message jsonError($message = "Database error: " . $e->getMessage()); } ?> ``` ## File: ride/egyptPhones/syrianAdd.php ``` prepare($sql); $stmt->bindParam(':driverId', $driverId); $stmt->bindParam(':name', $name); $stmt->bindParam(':phone', $phone); try { $stmt->execute(); // rowCount() ستكون 1 عند إضافة سجل جديد، و 0 عند تجاهل سجل مكرر if ($stmt->rowCount() > 0) { jsonSuccess(null, "New contact saved successfully"); } else { jsonSuccess(null, "Contact already exists for this driver."); } } catch (PDOException $e) { // إرجاع رسالة خطأ في حال حدوث مشكلة في قاعدة البيانات jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: ride/egyptPhones/get.php ``` ``` ## File: ride/profile/updateDriverEmail.php ``` encryptData($email); // تنفيذ التحديث $sql = "UPDATE driver SET email = :email WHERE id = :id"; $stmt = $con->prepare($sql); $success = $stmt->execute([ ":email" => $encryptedEmail, ":id" => $id ]); if ($success && $stmt->rowCount() > 0) { jsonSuccess(null, "Email updated successfully"); } else { jsonError("Failed to update email"); } ?> ``` ## File: ride/profile/update.php ``` $id]; $encryptedFields = [ "phone", "sosPhone", "birthdate", "site", "gender", "first_name", "last_name", "education", "employmentType", "maritalStatus" ]; foreach ($encryptedFields as $field) { if (isset($_POST[$field]) && !empty($_POST[$field])) { $value = filterRequest($field); $encryptedValue = $encryptionHelper->encryptData($value); $fields[] = "`$field` = :$field"; $params[":$field"] = $encryptedValue; } } if (!empty($fields)) { $setClause = implode(", ", $fields); $sql = "UPDATE `passengers` SET $setClause WHERE `id` = :id"; $stmt = $con->prepare($sql); $stmt->execute($params); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Passenger data updated successfully"); } else { jsonError("Failed to update passenger data"); } } else { jsonError("No fields to update"); } ?> ``` ## File: ride/profile/get.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_STR); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); if ($result) { unset($result['password']); // إخفاء الباسورد // فك تشفير الحقول الحساسة $fieldsToDecrypt = [ 'phone', 'email', 'gender', 'birthdate', 'site', 'first_name', 'last_name', 'sosPhone', 'education', 'employmentType', 'maritalStatus' ]; foreach ($fieldsToDecrypt as $field) { if (isset($result[$field])) { $result[$field] = $encryptionHelper->decryptData($result[$field]); } } echo json_encode([ "status" => "success", "data" => $result ]); } else { jsonError("Failed to retrieve passenger data"); } ?> ``` ## File: ride/profile/getCaptainProfile.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_STR); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); if (!$result) { jsonError("Failed to retrieve driver data"); exit; } // فك تشفير حقل birthdate أولاً لحساب العمر if (!empty($result['birthdate'])) { $result['birthdate'] = $encryptionHelper->decryptData($result['birthdate']); try { $dob = new DateTime($result['birthdate']); $today = new DateTime(); $age = $today->diff($dob)->y; } catch (Exception $e) { $age = null; } } else { $age = null; } $result['age'] = $age; // فك تشفير بقية الحقول $driverFieldsToDecrypt = [ 'phone', 'email', 'gender', 'site', 'first_name', 'last_name' ]; foreach ($driverFieldsToDecrypt as $field) { if (!empty($result[$field])) { $result[$field] = $encryptionHelper->decryptData($result[$field]); } } // فك تشفير حقول السيارة $vehicleFieldsToDecrypt = ['vin', 'car_plate']; foreach ($vehicleFieldsToDecrypt as $field) { if (!empty($result[$field])) { $result[$field] = $encryptionHelper->decryptData($result[$field]); } } jsonSuccess($result); ?> ``` ## File: ride/driver_order/add.php ``` prepare($checkSql); $checkStmt->execute([$order_id]); if ($checkStmt->rowCount() > 0) { // تحديث السجل إذا كان موجودًا $updateSql = "UPDATE `driver_orders` SET `driver_id` = ?, `status` = ?, `created_at` = NOW() WHERE `order_id` = ?"; $updateStmt = $con->prepare($updateSql); $updateStmt->execute([$driver_id, $status, $order_id]); if ($updateStmt->rowCount() > 0) { jsonSuccess(null, "Driver order data updated successfully"); } else { jsonError("Failed to update driver order data"); } } else { // إدخال سجل جديد إذا لم يكن موجودًا $insertSql = "INSERT INTO `driver_orders` (`driver_id`, `order_id`, `created_at`, `status`) VALUES (?, ?, NOW(), ?)"; $insertStmt = $con->prepare($insertSql); $insertStmt->execute([$driver_id, $order_id, $status]); if ($insertStmt->rowCount() > 0) { jsonSuccess(null, "Driver order data saved successfully"); } else { jsonError("Failed to save driver order data"); } } ?> ``` ## File: ride/driver_order/update.php ``` prepare($sql); $stmt->bindParam(":status", $status); $stmt->bindParam(":order_id", $order_id); $stmt->bindParam(":notes", $notes); $stmt->execute(); // التحقق من النتيجة if ($stmt->rowCount() > 0) { jsonSuccess(null, "Driver order data updated successfully"); } else { jsonError("Failed to update driver order data"); // أو لم يحدث تغيير في البيانات } ?> ``` ## File: ride/driver_order/getOrderCancelStatus.php ``` prepare($sql); $stmt->bindParam(":order_id", $order_id, PDO::PARAM_STR); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row) { echo json_encode([ "status" => "success", "data" => $row ]); } else { echo json_encode([ "status" => "failure", "message" => "No driver order data found for the specified order_id" ]); } ?> ``` ## File: ride/driver_order/get.php ``` prepare($stats_sql); $stats_stmt->execute([':driver_id' => $driver_id]); $stats = $stats_stmt->fetch(PDO::FETCH_ASSOC); // Calculate the average if ($stats && $stats['total_rides'] > 0) { $stats['averageApplied'] = $stats['total_applied'] / $stats['total_rides']; } else { $stats['averageApplied'] = 0; } // 2. Second, get the actual order history $orders_sql = " SELECT * FROM driver_orders WHERE driver_id = :driver_id AND MONTH(created_at) = MONTH(CURRENT_DATE()) AND YEAR(created_at) = YEAR(CURRENT_DATE()) ORDER BY created_at DESC "; $orders_stmt = $con->prepare($orders_sql); $orders_stmt->execute([':driver_id' => $driver_id]); $orders = $orders_stmt->fetchAll(PDO::FETCH_ASSOC); // 3. Combine the results into one response jsonSuccess($orders); } elseif ($order_id != null) { // This part remains the same, but let's ensure it's correct $sql = " SELECT * FROM driver_orders WHERE order_id = :order_id AND MONTH(created_at) = MONTH(CURRENT_DATE()) AND YEAR(created_at) = YEAR(CURRENT_DATE()) "; $stmt = $con->prepare($sql); $stmt->execute([':order_id' => $order_id]); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($stmt->rowCount() > 0) { jsonSuccess($result); } else { jsonError("No driver order data found for this order_id"); } } else { jsonError("No driver_id or order_id provided"); } ?> ``` ## File: ride/driver_order/delete.php ``` ``` ## File: ride/tips/add.php ``` 99999999.99) { jsonError("Invalid tip amount."); exit(); } // إدراج بيانات البقشيش $sql = "INSERT INTO `tips` (`driverID`, `passengerID`, `rideID`, `tipAmount`) VALUES (:driverID, :passengerID, :rideID, :tipAmount)"; $stmt = $con->prepare($sql); $stmt->bindParam(':driverID', $driverID); $stmt->bindParam(':passengerID', $passengerID); $stmt->bindParam(':rideID', $rideID); $stmt->bindParam(':tipAmount', $tipAmount); // تنفيذ العملية if ($stmt->execute() && $stmt->rowCount() > 0) { jsonSuccess(null, "Tip inserted successfully"); } else { jsonError("Failed to save tip information"); } ?> ``` ## File: ride/tips/get.php ``` prepare($sql); $stmt->bindParam(':driverID', $driverID); $stmt->bindParam(':passengerID', $passengerID); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); // فحص النتائج if ($data) { jsonSuccess($data); } else { jsonError("No tips records found"); } ?> ``` ## File: ride/driver_scam/add.php ``` prepare($sql); $stmt->bindParam(":driverID", $driverID); $stmt->bindParam(":passengerID", $passengerID); $stmt->bindParam(":rideID", $rideID); $stmt->bindParam(":isDriverCallPassenger", $isDriverCallPassenger); $stmt->bindParam(":dateCreated", $dateCreated); // تنفيذ الإدخال $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Driver ride scam data saved successfully"); } else { jsonError("Failed to save driver ride scam data"); } ?> ``` ## File: ride/driver_scam/update.php ``` ``` ## File: ride/driver_scam/get.php ``` = CURDATE() AND driver_ride_scam.dateCreated < DATE_ADD(CURDATE(), INTERVAL 1 DAY) GROUP BY DATE(driver_ride_scam.dateCreated) ORDER BY date DESC"; try { $stmt = $con->prepare($sql); $stmt->bindParam(':driverID', $driverID); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); if (!empty($rows)) { // --- FIX IS HERE --- // Your Flutter app looks for d['message']. // We manually create the array with the key "message" to match your app. echo json_encode(array("status" => "success", "message" => $rows)); } else { jsonError("No ride scam record found"); } } catch (PDOException $e) { jsonError("Database Error: " . $e->getMessage()); } ?> ``` ## File: ride/driver_scam/delete.php ``` ``` ## File: ride/passengerWallet/add.php ``` prepare("SELECT * FROM payment_tokens_passenger WHERE token = :token AND isUsed = FALSE"); $stmt->execute([':token' => $token]); $tokenData = $stmt->fetch(); if ($tokenData) { // Insert into passengerWallet securely using prepared statements $sql = "INSERT INTO `passengerWallet` (`passenger_id`, `balance`) VALUES (:passenger_id, :balance)"; $stmt = $con->prepare($sql); $stmt->execute([':passenger_id' => $passenger_id, ':balance' => $balance]); if ($stmt->rowCount() > 0) { // Mark the token as used $updateTokenStmt = $con->prepare("UPDATE payment_tokens_passenger SET isUsed = TRUE WHERE token = :token"); $updateTokenStmt->execute([':token' => $token]); jsonSuccess(null, "Wallet record created successfully"); } else { jsonError("Failed to create wallet record"); } } else { jsonError("Invalid or already used token"); } ?> ``` ## File: ride/passengerWallet/update.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = "Wallet record updated successfully"); } else { // Print a failure message jsonError($message = "Failed to update wallet record"); } ?> ``` ## File: ride/passengerWallet/get.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/passengerWallet/addPaymentTokenPassenger.php ``` prepare("INSERT INTO payment_tokens_passenger (token, passengerId, dateCreated, amount) VALUES (?, ?, NOW(), ?)"); try { $stmt->execute([$token, $passengerId, $amount]); if ($stmt->rowCount() > 0) { jsonSuccess($token); } else { jsonError("Failed to save record"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } // Rest of your code including the generateSecureToken function... // Rest of your code including the generateSecureToken function... function generateSecureToken($passengerId, $amount, $dateCreated) { global $secretKey; // Concatenate the parameters $data = $passengerId . $amount . $dateCreated; // Add the secret key from the environment variable $data .= $secretKey; // Generate a hash $hash = hash('sha256', $data); // Add some randomness $randomBytes = bin2hex(random_bytes(16)); // Combine hash and random bytes $token = $hash . $randomBytes; // Truncate to a reasonable length (e.g., 64 characters) return substr($token, 0, 64); } ``` ## File: ride/passengerWallet/getPassengerWalletArchive.php ``` = DATE_SUB(NOW(), INTERVAL 1 MONTH) ORDER BY `passengerWallet`.`id` DESC"; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/passengerWallet/getWalletByPassenger.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/passengerWallet/getAllPassengerTransaction.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Fetch the record $row = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($row); } else{ // Print a failure message jsonError($message = "No wallet record found"); } ?> ``` ## File: ride/passengerWallet/delete.php ``` prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = "Wallet record deleted successfully"); } else { // Print a failure message jsonError($message = "Failed to delete wallet record"); } ?> ``` ## File: ride/driver_behavior/get_driver_behavior.php ``` prepare($sql_average); $stmt_avg->bindParam(':driver_id', $driver_id); $stmt_avg->execute(); $average = $stmt_avg->fetch(PDO::FETCH_ASSOC); // ✅ ثانياً: جلب آخر 10 رحلات $sql_last10 = "SELECT id, trip_id, max_speed, avg_speed, hard_brakes, total_distance, behavior_score, created_at FROM driver_behavior WHERE driver_id = :driver_id ORDER BY id DESC LIMIT 10"; $stmt_last10 = $con->prepare($sql_last10); $stmt_last10->bindParam(':driver_id', $driver_id); $stmt_last10->execute(); $last10 = $stmt_last10->fetchAll(PDO::FETCH_ASSOC); // ✅ تجهيز الاستجابة النهائية $response = [ 'overall_behavior_score' => $average['overall_behavior_score'], 'last_10_trips' => $last10 ]; jsonSuccess($response); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: ride/invitor/add.php ``` prepare("SELECT COUNT(*) FROM invites WHERE inviteCode = ?"); $stmt->execute([$code]); if ($stmt->fetchColumn() == 0) { return $code; } } } $driverId = filterRequest("driverId"); $inviterDriverPhone = filterRequest("inviterDriverPhone"); // 🔐 تشفير رقم الهاتف $inviterDriverPhoneEncrypted = $encryptionHelper->encryptData($inviterDriverPhone); // تحقق من وجود رقم الهاتف مسبقًا $checkSql = "SELECT `id`, `inviteCode`, `isInstall` FROM `invites` WHERE `inviterDriverPhone` = :inviterDriverPhone"; $checkStmt = $con->prepare($checkSql); $checkStmt->bindParam(':inviterDriverPhone', $inviterDriverPhoneEncrypted, PDO::PARAM_STR); $checkStmt->execute(); if ($checkStmt->rowCount() > 0) { $existingInvite = $checkStmt->fetch(PDO::FETCH_ASSOC); if ($existingInvite['isInstall'] == 1) { jsonError($existingInvite['inviteCode']); } else { // تحديث الدعوة الحالية $updateSql = "UPDATE `invites` SET `driverId` = :driverId, `expirationTime` = :expirationTime, `createdAt` = NOW() WHERE `id` = :id"; $updateStmt = $con->prepare($updateSql); $expirationTime = date('Y-m-d H:i:s', strtotime('+1 hour')); $updateStmt->bindParam(':driverId', $driverId, PDO::PARAM_INT); $updateStmt->bindParam(':expirationTime', $expirationTime); $updateStmt->bindParam(':id', $existingInvite['id'], PDO::PARAM_INT); try { $updateStmt->execute(); printSuccess([ "message" => "Invite updated successfully", "inviteId" => $existingInvite['id'], "inviteCode" => $existingInvite['inviteCode'], "expirationTime" => $expirationTime ]); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } } } else { // إنشاء دعوة جديدة $inviteCode = generateUniqueCode($con); $expirationTime = date('Y-m-d H:i:s', strtotime('+1 hour')); $sql = "INSERT INTO `invites` (`driverId`, `inviterDriverPhone`, `inviteCode`, `expirationTime`, `createdAt`, `isInstall`) VALUES (:driverId, :inviterDriverPhone, :inviteCode, :expirationTime, NOW(), 0)"; $stmt = $con->prepare($sql); $stmt->bindParam(':driverId', $driverId, PDO::PARAM_INT); $stmt->bindParam(':inviterDriverPhone', $inviterDriverPhoneEncrypted, PDO::PARAM_STR); $stmt->bindParam(':inviteCode', $inviteCode); $stmt->bindParam(':expirationTime', $expirationTime); try { $stmt->execute(); if ($stmt->rowCount() > 0) { $insertedID = $con->lastInsertId(); printSuccess([ "message" => "Invite created successfully", "inviteId" => $insertedID, "inviteCode" => $inviteCode, "expirationTime" => $expirationTime ]); } else { jsonError("Failed to save invite data"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } } ?> ``` ## File: ride/invitor/update.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Record updated successfully."); } else { jsonError("No records were updated"); } ?> ``` ## File: ride/invitor/getDriverInvitationToPassengers.php ``` prepare($sql); $stmt->bindParam(':driverId', $driverId, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // 🔓 فك التشفير للحقول المطلوبة foreach ($rows as &$row) { $row['inviterPassengerPhone'] = $encryptionHelper->decryptData($row['inviterPassengerPhone']); $row['passengerName'] = $encryptionHelper->decryptData($row['passengerName']); } jsonSuccess($rows); } else { jsonError("No records found."); } ?> ``` ## File: ride/invitor/get.php ``` prepare($sql); $stmt->bindParam(':driverId', $driverId, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // 🔓 فك التشفير للحقول المطلوبة foreach ($rows as &$row) { $row['inviterDriverPhone'] = $encryptionHelper->decryptData($row['inviterDriverPhone']); $row['invitorPhone'] = $encryptionHelper->decryptData($row['invitorPhone']); $row['invitorName'] = $encryptionHelper->decryptData($row['invitorName']); } jsonSuccess($rows); } else { jsonError("No records found."); } ?> ``` ## File: ride/invitor/updatePassengersInvitation.php ``` encryptData($inviteCode); try { $checkSql = "SELECT `id`, `expirationTime` FROM `invitesToPassengers` WHERE `inviteCode` = :inviteCode AND `isInstall` = 0 AND `isGiftToken` = 0"; $checkStmt = $con->prepare($checkSql); $checkStmt->bindParam(':inviteCode', $inviteCodeEncrypted); $checkStmt->execute(); if ($checkStmt->rowCount() > 0) { $invite = $checkStmt->fetch(PDO::FETCH_ASSOC); $updateSql = "UPDATE `invitesToPassengers` SET `isInstall` = 1, `passengerID` = :passengerID WHERE `id` = :id"; $updateStmt = $con->prepare($updateSql); $updateStmt->bindParam(':id', $invite['id'], PDO::PARAM_INT); $updateStmt->bindParam(':passengerID', $passengerID); $updateStmt->execute(); if ($updateStmt->rowCount() > 0) { jsonSuccess(null, "Invite code successfully used and marked as installed."); } else { jsonError("Invite found but update failed."); } } else { jsonError("Invalid invite code, already used, or marked as gift."); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: ride/invitor/updatePassengerGift.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Record updated successfully."); } else { jsonError("No records were updated"); } ?> ``` ## File: ride/invitor/addInvitationPassenger.php ``` prepare("SELECT COUNT(*) FROM invitesToPassengers WHERE inviteCode = ?"); $stmt->execute([$code]); if ($stmt->fetchColumn() == 0) { return $code; } } } $driverId = filterRequest("driverId"); $inviterPassengerPhone = filterRequest("inviterPassengerPhone"); // 🔐 تشفير رقم الهاتف $inviterPassengerPhoneEncrypted = $encryptionHelper->encryptData($inviterPassengerPhone); // التحقق من وجود الرقم مسبقًا $checkSql = "SELECT `id`, `inviteCode`, `isInstall`, `isGiftToken` FROM `invitesToPassengers` WHERE `inviterPassengerPhone` = :inviterPassengerPhone"; $checkStmt = $con->prepare($checkSql); $checkStmt->bindParam(':inviterPassengerPhone', $inviterPassengerPhoneEncrypted, PDO::PARAM_STR); $checkStmt->execute(); if ($checkStmt->rowCount() > 0) { $existingInvite = $checkStmt->fetch(PDO::FETCH_ASSOC); if ($existingInvite['isInstall'] == 1 || $existingInvite['isGiftToken'] == 1) { printFailure([ "message" => "Invite code already used or gift token already applied", "inviteCode" => $existingInvite['inviteCode'] ]); } else { // تحديث الدعوة $updateSql = "UPDATE `invitesToPassengers` SET `driverId` = :driverId, `expirationTime` = :expirationTime, `createdAt` = NOW() WHERE `id` = :id"; $updateStmt = $con->prepare($updateSql); $expirationTime = date('Y-m-d H:i:s', strtotime('+1 hour')); $updateStmt->bindParam(':driverId', $driverId, PDO::PARAM_INT); $updateStmt->bindParam(':expirationTime', $expirationTime); $updateStmt->bindParam(':id', $existingInvite['id'], PDO::PARAM_INT); try { $updateStmt->execute(); printSuccess([ "message" => "Invite updated successfully", "inviteId" => $existingInvite['id'], "inviteCode" => $existingInvite['inviteCode'], "expirationTime" => $expirationTime ]); } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } } } else { // إنشاء دعوة جديدة $inviteCode = generateUniqueCode($con); $expirationTime = date('Y-m-d H:i:s', strtotime('+4 hour')); $sql = "INSERT INTO `invitesToPassengers` (`driverId`, `inviterPassengerPhone`, `inviteCode`, `expirationTime`, `createdAt`, `isInstall`, `isGiftToken`) VALUES (:driverId, :inviterPassengerPhone, :inviteCode, :expirationTime, NOW(), 0, 0)"; $stmt = $con->prepare($sql); $stmt->bindParam(':driverId', $driverId, PDO::PARAM_INT); $stmt->bindParam(':inviterPassengerPhone', $inviterPassengerPhoneEncrypted, PDO::PARAM_STR); $stmt->bindParam(':inviteCode', $inviteCode); $stmt->bindParam(':expirationTime', $expirationTime); try { $stmt->execute(); if ($stmt->rowCount() > 0) { $insertedID = $con->lastInsertId(); printSuccess([ "message" => "Invite created successfully", "inviteId" => $insertedID, "inviteCode" => $inviteCode, "expirationTime" => $expirationTime ]); } else { jsonError("Failed to save invite data"); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } } ?> ``` ## File: ride/invitor/updateInvitationCodeFromRegister.php ``` NOW()"; $checkStmt = $con->prepare($checkSql); $checkStmt->bindParam(':inviteCode', $inviteCode); $checkStmt->execute(); if ($checkStmt->rowCount() > 0) { $invite = $checkStmt->fetch(PDO::FETCH_ASSOC); $updateSql = "UPDATE `invites` SET `isInstall` = 1 WHERE `id` = :id"; $updateStmt = $con->prepare($updateSql); $updateStmt->bindParam(':id', $invite['id'], PDO::PARAM_INT); $updateStmt->execute(); if ($updateStmt->rowCount() > 0) { printSuccess([ "message" => "Invite code successfully used and marked as installed.", "driverId" => $invite['driverId'], "expirationTime" => $invite['expirationTime'] ]); } else { jsonError("Failed to update the invite record."); } } else { jsonError("Invalid invite code, already installed, or expired."); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: ride/invitor/updateDriverInvitationDirectly.php ``` encryptData($inviterDriverPhone); // ✅ الآن الاستعلام نظيف وطبيعي جداً لأن قاعدة البيانات تم إصلاحها $fetchSql = "SELECT i.`id`, i.`driverId`, i.`inviterDriverPhone`, i.`createdAt`, i.`inviteCode`, i.`isInstall`, i.`isGiftToken`, i.`expirationTime`, dt.token FROM `invites` i LEFT JOIN `driverToken` dt ON dt.captain_id = i.driverId WHERE i.`inviterDriverPhone` = :inviterDriverPhone AND i.`expirationTime` > NOW()"; $fetchStmt = $con->prepare($fetchSql); $fetchStmt->bindParam(':inviterDriverPhone', $inviterDriverPhoneEncrypted); $fetchStmt->execute(); if ($fetchStmt->rowCount() > 0) { $invite = $fetchStmt->fetch(PDO::FETCH_ASSOC); // فك التشفير $invite['inviterDriverPhone'] = $encryptionHelper->decryptData($invite['inviterDriverPhone']); if (!empty($invite['token'])) { $invite['token'] = $encryptionHelper->decryptData($invite['token']); } // التحديث $updateSql = "UPDATE `invites` SET `isInstall` = 1 WHERE `id` = :id"; $updateStmt = $con->prepare($updateSql); $updateStmt->bindParam(':id', $invite['id'], PDO::PARAM_INT); $updateStmt->execute(); printSuccess("Record found and updated successfully.", $invite); } else { jsonError("No records found."); } } catch (PDOException $e) { error_log("DB Error: " . $e->getMessage()); jsonError("Database error: " . $e->getMessage()); } ?> ``` ## File: ride/seferWallet/add.php ``` prepare($sql); $stmt->bindParam(':driver_id', $driver_id, PDO::PARAM_STR); $stmt->bindParam(':passenger_id', $passenger_id, PDO::PARAM_STR); $stmt->bindParam(':amount', $amount, PDO::PARAM_STR); $stmt->bindParam(':payment_method', $payment_method, PDO::PARAM_STR); $stmt->bindParam(':token', $token, PDO::PARAM_STR); if ($stmt->execute()) { // Print a success message jsonSuccess($message = "Wallet data saved successfully"); } else { // Print a failure message jsonError($message = "Failed to save wallet data"); } ?> ``` ## File: ride/seferWallet/get.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($stmt->rowCount() > 0) { // Print the retrieved data // echo json_encode($result); jsonSuccess($data = $result); } else { // Print a failure message jsonError($message = "No driver order data found"); } ?> ``` ## File: ride/notificationCaptain/add.php ``` prepare($sql); $stmt->execute([ ':driverID' => $driverID, ':title' => $title, ':body' => $body, ':isPin' => $isPin ]); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Notification data saved successfully"); } else { jsonError("Failed to save notification data"); } ?> ``` ## File: ride/notificationCaptain/update.php ``` $id]; if (isset($_POST["driverID"])) { $columnValues[] = "`driverID` = :driverID"; $params[':driverID'] = filterRequest("driverID"); } if (isset($_POST["title"])) { $columnValues[] = "`title` = :title"; $params[':title'] = filterRequest("title"); } if (isset($_POST["body"])) { $columnValues[] = "`body` = :body"; $params[':body'] = filterRequest("body"); } if (isset($_POST["isShown"])) { $columnValues[] = "`isShown` = :isShown"; $params[':isShown'] = filterRequest("isShown"); } if (isset($_POST["dateCreated"])) { $columnValues[] = "`dateCreated` = :dateCreated"; $params[':dateCreated'] = filterRequest("dateCreated"); } // Check if there are fields to update if (empty($columnValues)) { jsonError("No fields to update"); exit; } $setClause = implode(", ", $columnValues); $sql = "UPDATE `notificationCaptain` SET $setClause WHERE `id` = :id"; $stmt = $con->prepare($sql); $stmt->execute($params); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Notification data updated successfully"); } else { jsonError("Failed to update notification data"); } ?> ``` ## File: ride/notificationCaptain/get.php ``` DATE_SUB(NOW(), INTERVAL 2 DAY) ORDER BY `dateCreated` DESC LIMIT 10"; $stmt = $con->prepare($sql); $stmt->bindParam(':driverID', $driverID, PDO::PARAM_STR); $stmt->execute(); $notifications = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($notifications) { jsonSuccess($notifications); } else { jsonError("No notification data found"); } ?> ``` ## File: ride/notificationCaptain/addWaitingRide.php ``` prepare($sql); $stmt->execute($params); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Operation completed successfully"); } else { jsonSuccess(null, "No changes made"); } } catch (PDOException $e) { error_log("Database error in addWaitingRide: " . $e->getMessage()); jsonError("Database error: " . $e->getMessage()); } catch (Exception $e) { jsonError("Error: " . $e->getMessage()); } ?> ``` ## File: ride/notificationCaptain/deleteAvailableRide.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); // Check the result and print the appropriate message if ($stmt->rowCount() > 0) { jsonSuccess(null, "Record with ID $id deleted successfully."); } else { jsonError("No record found with ID $id."); } } catch (PDOException $e) { jsonError("Database error: " . $e->getMessage()); } catch (Exception $e) { jsonError("Error: " . $e->getMessage()); } ?> ``` ## File: ride/notificationCaptain/delete.php ``` prepare($sql); $stmt->bindParam(':id', $notificationID, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Notification data deleted successfully"); } else { jsonError("Failed to delete notification data"); } ?> ``` ## File: ride/notificationCaptain/getRideWaiting.php ``` '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"); } ?> ``` ## File: ride/notificationCaptain/updateWaitingTrip.php ``` $id]; $possibleFields = [ 'start_location', 'end_location', 'date', 'time', 'price', 'passenger_id', 'status', 'carType', 'passengerRate', 'price_for_passenger', 'distance', 'duration' ]; foreach ($possibleFields as $field) { if (isset($_POST[$field])) { $value = filterRequest($field); $fields[] = "`$field` = :$field"; $params[":$field"] = $value; } } if (empty($fields)) { jsonError("No fields provided for update"); exit; } $setClause = implode(", ", $fields); $sql = "UPDATE `waitingRides` SET $setClause WHERE `id` = :id"; $stmt = $con->prepare($sql); $stmt->execute($params); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Waiting ride data updated successfully"); } else { jsonError("Failed to update waiting ride data"); } ?> ``` ## File: ride/overLay/add.php ``` prepare($sql); // --- التعديل الرئيسي هنا في bindValue --- $stmt->bindValue(':rideId', $data['rideId']); $stmt->bindValue(':driver_id', $data['driver_id']); $stmt->bindValue(':passengerId', $data['passengerId']); // Bind the locations as simple strings $stmt->bindValue(':passengerLocation', $data['passengerLocation']); $stmt->bindValue(':passengerDestination', $data['passengerDestination']); // باقي الـ bindValue تبقى كما هي $stmt->bindValue(':Duration', intval($data['Duration']), PDO::PARAM_INT); $stmt->bindValue(':DurationToPassenger', intval($data['DurationToPassenger']), PDO::PARAM_INT); $stmt->bindValue(':durationOfRideValue', intval($data['durationOfRideValue']), PDO::PARAM_INT); $stmt->bindValue(':Distance', (float)$data['Distance']); $stmt->bindValue(':totalCost', (float)$data['totalCost']); $stmt->bindValue(':paymentAmount', (float)$data['paymentAmount']); $stmt->bindValue(':paymentMethod', $data['paymentMethod']); $stmt->bindValue(':WalletChecked', $data['WalletChecked'] === 'true' ? 1 : 0, PDO::PARAM_INT); $stmt->bindValue(':isHaveSteps', !empty($data['isHaveSteps']) ? 1 : 0, PDO::PARAM_INT); $stmt->bindValue(':step0', $data['step0']); $stmt->bindValue(':step1', $data['step1']); $stmt->bindValue(':step2', $data['step2']); $stmt->bindValue(':step3', $data['step3']); $stmt->bindValue(':step4', $data['step4']); $stmt->bindValue(':passengerWalletBurc', (float)$data['passengerWalletBurc']); $stmt->bindValue(':tokenPassenger', $data['tokenPassenger']); $stmt->bindValue(':name', $data['name']); $stmt->bindValue(':phone', $data['phone']); $stmt->bindValue(':email', $data['email']); $stmt->bindValue(':startNameLocation', $data['startNameLocation']); $stmt->bindValue(':endNameLocation', $data['endNameLocation']); $stmt->bindValue(':carType', $data['carType']); $stmt->bindValue(':kazan', (float)$data['kazan']); $stmt->bindValue(':direction', $data['direction']); $stmt->bindValue(':timeOfOrder', $data['timeOfOrder']); $stmt->bindValue(':totalPassenger', intval($data['totalPassenger']), PDO::PARAM_INT); log_message("SQL statement prepared successfully. Attempting to execute..."); if ($stmt->execute()) { log_message("SUCCESS: Database insert was successful for rideId: " . $data['rideId']); jsonSuccess(null, "نجحت الإضافة"); } else { $errorInfo = $stmt->errorInfo(); $error_msg = "FAILURE: Database insert failed. PDO Error: " . implode(" | ", $errorInfo); log_message($error_msg); jsonError("failure"); } } catch (Exception $e) { $error_msg = "EXCEPTION: An unexpected error occurred: " . $e->getMessage(); log_message($error_msg); jsonError("failure"); } ?> ``` ## File: ride/overLay/deletArgumets.php ``` prepare($sql); $stmt->bindParam(':driver_id', $driver_id); $stmt->execute(); // Check if any rows were actually deleted $count = $stmt->rowCount(); if ($count > 0) { jsonSuccess(null, "Record deleted successfully"); } else { // Failure occurs if no record exists OR if the record is older than 2 minutes jsonError('No data found to delete (or time limit exceeded)'); } ?> ``` ## File: ride/overLay/get.php ``` = NOW() - INTERVAL 2 MINUTE ORDER BY r.created_at DESC LIMIT 1; "; $stmt = $con->prepare($sql); $stmt->bindParam(':driver_id', $driver_id, PDO::PARAM_INT); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); // 3) إرجاع النتيجة أو رسالة خطأ if ($row) { jsonSuccess($row); } else { jsonError("Ride not found."); } ``` ## File: ride/overLay/_log.txt ``` [2025-06-20 17:42:27] --- New Request Received --- [2025-06-20 17:42:27] Incoming POST data: {"driver_id":"109270481246447459618","status":"Apply","passengerLocation":"32.1117875,36.0669891","passengerDestination":"32.0798703,36.0749472","Duration":"528","totalCost":"6.99","Distance":"5.64","name":"hamza","phone":"+201010101010","email":"hamzaayedflutter@gmail.com","WalletChecked":"true","tokenPassenger":"e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C32.1117875%2C36.0669891&markers=color:red%7Clabel:D%7C32.0798703%2C36.0749472&path=color:0x007bff%7Cweight:5%7C32.1117875%2C36.0669891%7C32.0798703%2C36.0749472&key=AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0","DurationToPassenger":"1","rideId":"1292","passengerId":"113172279072358305645","durationOfRideValue":"528","paymentAmount":"33.78","paymentMethod":"visa","isHaveSteps":"startEnd","step0":"32.09571771505668,36.06855209916831","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"6.99","carType":"Speed","kazan":"8","startNameLocation":"4368+PPP\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","endNameLocation":"33HG+R6R\u060c \u0627\u0644\u0632\u0631\u0642\u0627\u0621\u060c \u0627\u0644\u0623\u0631\u062f\u0646","timeOfOrder":"2025-06-20T17:42:26.285449","totalPassenger":"33.78"} [2025-06-20 17:42:27] Critical error: Missing required fields (rideId, driverId, or locations). [2025-06-20 17:45:59] --- New Request Received --- [2025-06-20 17:45:59] Incoming POST data: {"driver_id":"109270481246447459618","status":"Apply","passengerLocation":"32.1117875,36.0669891","passengerDestination":"32.0798703,36.0749472","Duration":"528","totalCost":"6.99","Distance":"5.64","name":"hamza","phone":"+201010101010","email":"hamzaayedflutter@gmail.com","WalletChecked":"true","tokenPassenger":"e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C32.1117875%2C36.0669891&markers=color:red%7Clabel:D%7C32.0798703%2C36.0749472&path=color:0x007bff%7Cweight:5%7C32.1117875%2C36.0669891%7C32.0798703%2C36.0749472&key=AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0","DurationToPassenger":"3","rideId":"1293","passengerId":"113172279072358305645","durationOfRideValue":"528","paymentAmount":"33.78","paymentMethod":"visa","isHaveSteps":"startEnd","step0":"32.09571771505668,36.06855209916831","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"6.99","carType":"Speed","kazan":"8","startNameLocation":"4368+PPP\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","endNameLocation":"33HG+R6R\u060c \u0627\u0644\u0632\u0631\u0642\u0627\u0621\u060c \u0627\u0644\u0623\u0631\u062f\u0646","timeOfOrder":"2025-06-20T17:45:58.817633","totalPassenger":"33.78"} [2025-06-20 17:45:59] Critical error: Missing required fields (rideId, driverId, or locations). [2025-06-20 17:47:00] --- New Request Received --- [2025-06-20 17:47:00] Incoming POST data: {"driver_id":"109270481246447459618","status":"Apply","passengerLocation":"32.1117875,36.0669891","passengerDestination":"32.1364001,36.0707479","Duration":"434","totalCost":"5.42","Distance":"4.38","name":"hamza","phone":"+201010101010","email":"hamzaayedflutter@gmail.com","WalletChecked":"true","tokenPassenger":"e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C32.1117875%2C36.0669891&markers=color:red%7Clabel:D%7C32.1364001%2C36.0707479&path=color:0x007bff%7Cweight:5%7C32.1117875%2C36.0669891%7C32.1364001%2C36.0707479&key=AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0","DurationToPassenger":"2","rideId":"1294","passengerId":"113172279072358305645","durationOfRideValue":"434","paymentAmount":"27.82","paymentMethod":"visa","isHaveSteps":"startEnd","step0":"32.12404505187645,36.06566168367863","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"5.42","carType":"Speed","kazan":"8","startNameLocation":"4368+PPP\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","endNameLocation":"43PC+C4G\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","timeOfOrder":"2025-06-20T17:46:59.188875","totalPassenger":"27.82"} [2025-06-20 17:47:00] Parsed Locations: passenger_lat=32.1117875, passenger_lng=36.0669891 | destination_lat=32.1364001, destination_lng=36.0707479 [2025-06-20 17:47:00] SQL statement prepared successfully. Attempting to execute... [2025-06-20 17:47:00] SUCCESS: Database insert was successful for rideId: 1294 [2025-06-20 17:49:18] --- New Request Received --- [2025-06-20 17:49:18] Incoming POST data: {"driver_id":"109270481246447459618","status":"Apply","passengerLocation":"32.1117875,36.0669891","passengerDestination":"32.0798703,36.0749472","Duration":"528","totalCost":"6.99","Distance":"5.64","name":"hamza","phone":"+201010101010","email":"hamzaayedflutter@gmail.com","WalletChecked":"true","tokenPassenger":"e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C32.1117875%2C36.0669891&markers=color:red%7Clabel:D%7C32.0798703%2C36.0749472&path=color:0x007bff%7Cweight:5%7C32.1117875%2C36.0669891%7C32.0798703%2C36.0749472&key=AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0","DurationToPassenger":"1","rideId":"1295","passengerId":"113172279072358305645","durationOfRideValue":"528","paymentAmount":"33.78","paymentMethod":"visa","isHaveSteps":"startEnd","step0":"32.09571771505668,36.06855209916831","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"6.99","carType":"Speed","kazan":"8","startNameLocation":"4368+PPP\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","endNameLocation":"33HG+R6R\u060c \u0627\u0644\u0632\u0631\u0642\u0627\u0621\u060c \u0627\u0644\u0623\u0631\u062f\u0646","timeOfOrder":"2025-06-20T17:49:16.916262","totalPassenger":"33.78"} [2025-06-20 17:49:18] Parsed Locations: passenger_lat=32.1117875, passenger_lng=36.0669891 | destination_lat=32.0798703, destination_lng=36.0749472 [2025-06-20 17:49:18] SQL statement prepared successfully. Attempting to execute... [2025-06-20 17:49:18] EXCEPTION: An unexpected error occurred: SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\x84\x0DO\x0E@@...' for column 'passenger_location' at row 1 [2025-06-20 17:52:06] --- New Request Received --- [2025-06-20 17:52:06] Incoming POST data: {"driver_id":"109270481246447459618","status":"Apply","passengerLocation":"32.1117875,36.0669891","passengerDestination":"32.1364001,36.0707479","Duration":"434","totalCost":"5.42","Distance":"4.38","name":"hamza","phone":"+201010101010","email":"hamzaayedflutter@gmail.com","WalletChecked":"true","tokenPassenger":"e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C32.1117875%2C36.0669891&markers=color:red%7Clabel:D%7C32.1364001%2C36.0707479&path=color:0x007bff%7Cweight:5%7C32.1117875%2C36.0669891%7C32.1364001%2C36.0707479&key=AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0","DurationToPassenger":"5","rideId":"1296","passengerId":"113172279072358305645","durationOfRideValue":"434","paymentAmount":"27.82","paymentMethod":"visa","isHaveSteps":"startEnd","step0":"32.12404505187645,36.06566168367863","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"5.42","carType":"Speed","kazan":"8","startNameLocation":"4368+PPP\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","endNameLocation":"43PC+C4G\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","timeOfOrder":"2025-06-20T17:52:05.601313","totalPassenger":"27.82"} [2025-06-20 17:52:06] SQL statement prepared successfully. Attempting to execute... [2025-06-20 17:52:06] EXCEPTION: An unexpected error occurred: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'passenger_location' at row 1 [2025-06-20 17:53:56] --- New Request Received --- [2025-06-20 17:53:56] Incoming POST data: {"driver_id":"109270481246447459618","status":"Apply","passengerLocation":"32.1117875,36.0669891","passengerDestination":"32.0798703,36.0749472","Duration":"528","totalCost":"6.99","Distance":"5.64","name":"hamza","phone":"+201010101010","email":"hamzaayedflutter@gmail.com","WalletChecked":"true","tokenPassenger":"e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C32.1117875%2C36.0669891&markers=color:red%7Clabel:D%7C32.0798703%2C36.0749472&path=color:0x007bff%7Cweight:5%7C32.1117875%2C36.0669891%7C32.0798703%2C36.0749472&key=AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0","DurationToPassenger":"3","rideId":"1297","passengerId":"113172279072358305645","durationOfRideValue":"528","paymentAmount":"33.78","paymentMethod":"visa","isHaveSteps":"startEnd","step0":"32.09571771505668,36.06855209916831","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"6.99","carType":"Speed","kazan":"8","startNameLocation":"4368+PPP\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","endNameLocation":"33HG+R6R\u060c \u0627\u0644\u0632\u0631\u0642\u0627\u0621\u060c \u0627\u0644\u0623\u0631\u062f\u0646","timeOfOrder":"2025-06-20T17:53:56.195146","totalPassenger":"33.78"} [2025-06-20 17:53:56] SQL statement prepared successfully. Attempting to execute... [2025-06-20 17:53:56] SUCCESS: Database insert was successful for rideId: 1297 [2025-06-21 23:49:45] --- New Request Received --- [2025-06-21 23:49:45] Incoming POST data: {"driver_id":"109270481246447459618","status":"Apply","passengerLocation":"32.1117875,36.0669891","passengerDestination":"32.0798703,36.0749472","Duration":"528","totalCost":"6.99","Distance":"5.64","name":"hamza","phone":"+201010101010","email":"hamzaayedflutter@gmail.com","WalletChecked":"true","tokenPassenger":"e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C32.1117875%2C36.0669891&markers=color:red%7Clabel:D%7C32.0798703%2C36.0749472&path=color:0x007bff%7Cweight:5%7C32.1117875%2C36.0669891%7C32.0798703%2C36.0749472&key=AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0","DurationToPassenger":"1","rideId":"1298","passengerId":"113172279072358305645","durationOfRideValue":"528","paymentAmount":"29.81","paymentMethod":"visa","isHaveSteps":"startEnd","step0":"32.09571771505668,36.06855209916831","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"6.99","carType":"Speed","kazan":"8","startNameLocation":"4368+PPP\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","endNameLocation":"33HG+R6R\u060c \u0627\u0644\u0632\u0631\u0642\u0627\u0621\u060c \u0627\u0644\u0623\u0631\u062f\u0646","timeOfOrder":"2025-06-21T23:49:42.340702","totalPassenger":"29.81"} [2025-06-21 23:49:45] SQL statement prepared successfully. Attempting to execute... [2025-06-21 23:49:45] SUCCESS: Database insert was successful for rideId: 1298 [2025-07-08 18:34:43] --- New Request Received --- [2025-07-08 18:34:43] Incoming POST data: {"driver_id":"109270481246447459618","status":"Apply","passengerLocation":"33.4934292,36.3335578","passengerDestination":"33.5165162,36.3174916","Duration":"842","totalCost":"6.32","Distance":"5.11","name":"hamza","phone":"+201010101010","email":"hamzaayedflutter@gmail.com","WalletChecked":"true","tokenPassenger":"e4QWqe7K607luM7qUMOPCL:APA91bFjX4XBM4I5COJl9fyxCTKJ1ZQpT3vzY7iEbOTuT4uo0-OSCAt5zgVhlhw4aC33s-VhyucDnP1tQGFd9svaazQ8A_SKgolPk3owzug8dCsiXoPeJ0k","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C33.4934292%2C36.3335578&markers=color:red%7Clabel:D%7C33.5165162%2C36.3174916&path=color:0x007bff%7Cweight:5%7C33.4934292%2C36.3335578%7C33.5165162%2C36.3174916&key=AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0","DurationToPassenger":"11","rideId":"1315","passengerId":"113172279072358305645","durationOfRideValue":"842","paymentAmount":"34.78","paymentMethod":"visa","isHaveSteps":"startEnd","step0":"33.505157730332385,36.32586847990751","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"6.32","carType":"Speed","kazan":"8","startNameLocation":"F8VM+C95\u060c \u062f\u0645\u0634\u0642\u060c \u0633\u0648\u0631\u064a\u0627","endNameLocation":"G888+MV4\u060c \u062f\u0645\u0634\u0642\u060c \u0633\u0648\u0631\u064a\u0627","timeOfOrder":"2025-07-08T18:34:14.861836","totalPassenger":"34.78"} [2025-07-08 18:34:43] SQL statement prepared successfully. Attempting to execute... [2025-07-08 18:34:43] SUCCESS: Database insert was successful for rideId: 1315 [2025-07-27 16:51:54] --- New Request Received --- [2025-07-27 16:51:54] Incoming POST data: {"driver_id":"34feffd3fa72d6bee56b","status":"Apply","passengerLocation":"32.1117875,36.0669891","passengerDestination":"32.1324686,36.0710479","Duration":"346","totalCost":"2767.81","Distance":"2.64","name":"hamza","phone":"963992952235","email":"963992952235@intaleqapp.com","WalletChecked":"false","tokenPassenger":"eskhRGH3gkzOmUQou8xJjg:APA91bGkbGdXRTuB3QTZ5BjHGiYLZNugjVlW7o89ck9KPDmJrT7v1DBSjdamRSLc4oqT56xNpZ_LgkFKhRWkprlLUvZx5HLCOTXMk0WBiQ0UibiSWqw10oI","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C32.1117875%2C36.0669891&markers=color:red%7Clabel:D%7C32.1324686%2C36.0710479&path=color:0x007bff%7Cweight:5%7C32.1117875%2C36.0669891%7C32.1324686%2C36.0710479&key=QOsqYdTCyHNapgBsg2Kn-nTKbhaWhEAGOjUeU78","DurationToPassenger":"1","rideId":"2","passengerId":"0b24f04061d6853df4b9","durationOfRideValue":"346","paymentAmount":"10532.56","paymentMethod":"cash","isHaveSteps":"startEnd","step0":"32.122128403255125,36.07006452977657","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"2767.81","carType":"Speed","kazan":"15","startNameLocation":"4368+PPP\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","endNameLocation":"43MC+374\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","timeOfOrder":"2025-07-27T16:51:53.436851","totalPassenger":"10532.56"} [2025-07-27 16:51:54] SQL statement prepared successfully. Attempting to execute... [2025-07-27 16:51:54] SUCCESS: Database insert was successful for rideId: 2 [2025-08-05 12:13:28] --- New Request Received --- [2025-08-05 12:13:28] Incoming POST data: {"driver_id":"34feffd3fa72d6bee56b","status":"Apply","passengerLocation":"32.1117131,36.067405","passengerDestination":"32.1278332,36.0702951","Duration":"253","totalCost":"2126.67","Distance":"2.03","name":"hamza","phone":"963992952235","email":"963992952235@intaleqapp.com","WalletChecked":"false","tokenPassenger":"dwDRLsWhZEIqum1oxaaTWY:APA91bHhImBb0-kyeRE8zP8jL-ps_K4Xt09g1YNRWbVx007FO4N9U4b9lPAoNOU029qM5-GU65doySW7dfsdQ_mDogqGtQnGtJz1uVOb_3_v-tuoL9irixo","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C32.1117131%2C36.067405&markers=color:red%7Clabel:D%7C32.1278332%2C36.0702951&path=color:0x007bff%7Cweight:5%7C32.1117131%2C36.067405%7C32.1278332%2C36.0702951&key=AIzaSyCFsWBqvkXzk1Gb-bCGxwqTwJQKIeHjH64","DurationToPassenger":"3","rideId":"23","passengerId":"0b24f04061d6853df4b9","durationOfRideValue":"253","paymentAmount":"5938.31","paymentMethod":"cash","isHaveSteps":"startEnd","step0":"32.119773283888684,36.06956731528044","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"2126.67","carType":"Speed","kazan":"15","startNameLocation":"4368+PPP\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","endNameLocation":"43H9+3V8\u060c \u0627\u0644\u0633\u062e\u0646\u0629\u060c \u0627\u0644\u0623\u0631\u062f\u0646","timeOfOrder":"2025-08-05T12:13:27.287381","totalPassenger":"5938.31"} [2025-08-05 12:13:28] SQL statement prepared successfully. Attempting to execute... [2025-08-05 12:13:28] SUCCESS: Database insert was successful for rideId: 23 [2025-11-03 16:54:25] --- New Request Received --- [2025-11-03 16:54:25] Incoming POST data: {"driver_id":"90393d64b8cd7488c4df","status":"Apply","passengerLocation":"33.4323,36.24325","passengerDestination":"33.4277,36.23907","Duration":"111","totalCost":"0.00","Distance":"0.72","name":"\u062d\u0645\u0632\u0647","phone":"963992952235","email":"963992952235@intaleqapp.com","WalletChecked":"false","tokenPassenger":"eznj5vRWRnqwKNtKJBaYNg:APA91bHhJ2DJ1KQa3KRx6wQtX8BkFHq6I_-dXGxT16p6pnV5AwI0bWOeiTJOI35VfTBaK4YSCKmAB4SsRnpARK0MTJ96xtpPmwAKfkvsZFga8OoGMeb3PmA","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C33.4323%2C36.24325&markers=color:red%7Clabel:D%7C33.4277%2C36.23907&path=color:0x007bff%7Cweight:5%7C33.4323%2C36.24325%7C33.4277%2C36.23907&key=AIzaSyAPFR_XbRN0XZ5Iz3AYDjNYHGJG2s2QWwM","DurationToPassenger":"0","rideId":"5","passengerId":"f1e06c5908dcae1f5bf2","durationOfRideValue":"111","paymentAmount":"17280.00","paymentMethod":"cash","isHaveSteps":"startEnd","step0":"33.430078683118474,36.241159960627556","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"0.00","carType":"Speed","kazan":"8","startNameLocation":"home","endNameLocation":"destination","timeOfOrder":"2025-11-03T16:54:23.416130","totalPassenger":"17280.00"} [2025-11-03 16:54:25] SQL statement prepared successfully. Attempting to execute... [2025-11-03 16:54:25] SUCCESS: Database insert was successful for rideId: 5 [2025-11-18 18:07:16] --- New Request Received --- [2025-11-18 18:07:16] Incoming POST data: {"driver_id":"ca60f0f65d7d6de23e5c","status":"Apply","passengerLocation":"36.16167,37.15408","passengerDestination":"36.2431,37.1496","Duration":"1254","totalCost":"0.00","Distance":"11.53","name":"George","phone":"447441447609","email":"sahrsa6@gmail.com","WalletChecked":"false","tokenPassenger":"eoHpQeewTbKL3ZU5ioLgP5:APA91bG0FhuTixe_kuDw49onLPdOjxdyRvmbT_TG5Va81lI7RqOpoHqaho6NThvybVJZaelkobwTDCZeC9WKLW-RytE1mUl3MfRiYiTPkHGZ2bCe9Raehtc","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C36.16167%2C37.15408&markers=color:red%7Clabel:D%7C36.2431%2C37.1496&path=color:0x007bff%7Cweight:5%7C36.16167%2C37.15408%7C36.2431%2C37.1496&key=AIzaSyAPFR_XbRN0XZ5Iz3AYDjNYHGJG2s2QWwM","DurationToPassenger":"0","rideId":"124","passengerId":"21c382cde919795e93bb","durationOfRideValue":"1254","paymentAmount":"56469.00","paymentMethod":"cash","isHaveSteps":"startEnd","step0":"36.174937765937635,37.15724665671587","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"0.00","carType":"Speed","kazan":"8","startNameLocation":"home","endNameLocation":"destination","timeOfOrder":"2025-11-18T18:07:15.160122","totalPassenger":"56469.00"} [2025-11-18 18:07:16] SQL statement prepared successfully. Attempting to execute... [2025-11-18 18:07:16] SUCCESS: Database insert was successful for rideId: 124 [2025-11-20 10:07:35] --- New Request Received --- [2025-11-20 10:07:35] Incoming POST data: {"driver_id":"34feffd3fa72d6bee56b","status":"Apply","passengerLocation":"33.4323,36.24325","passengerDestination":"33.43575,36.2483","Duration":"203","totalCost":"0.00","Distance":"0.96","name":"\u062d\u0645\u0632\u0647","phone":"963992952235","email":"963992952235@intaleqapp.com","WalletChecked":"false","tokenPassenger":"clZNZD6JTNeytuyvhqAjAs:APA91bEfEgnGduR3yy2ND3V57d1-qT_OS_A-gGimALeYNwSla-IVMBfYgfDYucNN5Whf0wJODjkOYuT03JLr5AJ4eqRXKxUbkbBis-GYFDdly_3o5nDEiWo","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C33.4323%2C36.24325&markers=color:red%7Clabel:D%7C33.43575%2C36.2483&path=color:0x007bff%7Cweight:5%7C33.4323%2C36.24325%7C33.43575%2C36.2483&key=AIzaSyAPFR_XbRN0XZ5Iz3AYDjNYHGJG2s2QWwM","DurationToPassenger":"0","rideId":"143","passengerId":"849a9faf3e68c1aeb708","durationOfRideValue":"203","paymentAmount":"17280.00","paymentMethod":"cash","isHaveSteps":"startEnd","step0":"33.43403283445615,36.24521479010582","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"0.00","carType":"Speed","kazan":"8","startNameLocation":"home","endNameLocation":"destination","timeOfOrder":"2025-11-20T10:07:33.481734","totalPassenger":"17280.00"} [2025-11-20 10:07:35] SQL statement prepared successfully. Attempting to execute... [2025-11-20 10:07:35] SUCCESS: Database insert was successful for rideId: 143 [2025-11-25 20:16:54] --- New Request Received --- [2025-11-25 20:16:54] Incoming POST data: {"driver_id":"7939eb03eb3b912ffb49","status":"Apply","passengerLocation":"35.12533,36.76929","passengerDestination":"35.13223,36.7536","Duration":"292","totalCost":"0.00","Distance":"2.81","name":"\u0639\u0628\u062f\u0627\u0644\u0644\u0647","phone":"963098198141","email":"bdallhlwany@gmail.com","WalletChecked":"false","tokenPassenger":"e-z9_8IRZEEsjwL3qFQAzN:APA91bHZEIWbF418RCnLeo3yVsGHkD7xDqoIHZzbw7tiXoImzSDi5KlOQbhIrEFxrtxNJ1uvStUk9jobI3k1p1LBr-Er7O2fhWG-P-HSHsChgGWoEjEZ15o","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C35.12533%2C36.76929&markers=color:red%7Clabel:D%7C35.13223%2C36.7536&path=color:0x007bff%7Cweight:5%7C35.12533%2C36.76929%7C35.13223%2C36.7536&key=AIzaSyAPFR_XbRN0XZ5Iz3AYDjNYHGJG2s2QWwM","DurationToPassenger":"0","rideId":"229","passengerId":"64070ab2e6cfa4be0c58","durationOfRideValue":"292","paymentAmount":"17280.00","paymentMethod":"cash","isHaveSteps":"startEnd","step0":"35.1270850911746,36.76192492246628","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"0.00","carType":"Speed","kazan":"8","startNameLocation":"\u062f\u0648\u0627\u0631 \u0627\u0644\u0627\u0633\u0643\u0627\u0646","endNameLocation":"\u062d\u0645\u0627\u0629","timeOfOrder":"2025-11-25T20:16:53.203785","totalPassenger":"17280.00"} [2025-11-25 20:16:54] SQL statement prepared successfully. Attempting to execute... [2025-11-25 20:16:54] SUCCESS: Database insert was successful for rideId: 229 [2025-11-29 13:25:59] --- New Request Received --- [2025-11-29 13:25:59] Incoming POST data: {"driver_id":"f48c50ef7bb6f55e710c","status":"Apply","passengerLocation":"33.43231,36.24297","passengerDestination":"33.43562,36.16933","Duration":"1419","totalCost":"0.00","Distance":"12.68","name":"\u062d\u0645\u0632\u0647","phone":"963992952235","email":"963992952235@intaleqapp.com","WalletChecked":"false","tokenPassenger":"eduBTsgC501SmEff3v4MGi:APA91bGf2PpOdgC3dEK7h3E4Kccu30tw7rbZeAJe7Co5JmHrrkwsz0pijAXFcjrbNkWQLI867bTogGGjL847OBNQ8FHSQJN9Gs1RY-GwaXh9ubffApwEdd0","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C33.43231%2C36.24297&markers=color:red%7Clabel:D%7C33.43562%2C36.16933&path=color:0x007bff%7Cweight:5%7C33.43231%2C36.24297%7C33.43562%2C36.16933&key=AIzaSyAPFR_XbRN0XZ5Iz3AYDjNYHGJG2s2QWwM","DurationToPassenger":"0","rideId":"290","passengerId":"849a9faf3e68c1aeb708","durationOfRideValue":"1419","paymentAmount":"60710.00","paymentMethod":"cash","isHaveSteps":"startEnd","step0":"33.449831692690715,36.20406500995159","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"0.00","carType":"Speed","kazan":"8","startNameLocation":"\u0623\u0634\u0631\u0641\u064a\u0629","endNameLocation":"\u062c\u062f\u064a\u062f\u0629 \u0639\u0631\u0637\u0648\u0632","timeOfOrder":"2025-11-29T13:25:58.938290","totalPassenger":"60710.00"} [2025-11-29 13:25:59] SQL statement prepared successfully. Attempting to execute... [2025-11-29 13:25:59] SUCCESS: Database insert was successful for rideId: 290 [2025-12-01 10:28:09] --- New Request Received --- [2025-12-01 10:28:09] Incoming POST data: {"driver_id":"b21737ec0edb0d02eb86","status":"Apply","passengerLocation":"33.4323,36.24329","passengerDestination":"33.41301,36.23664","Duration":"575","totalCost":"0.00","Distance":"3.64","name":"\u062d\u0645\u0632\u0647","phone":"963992952235","email":"963992952235@intaleqapp.com","WalletChecked":"false","tokenPassenger":"eduBTsgC501SmEff3v4MGi:APA91bGf2PpOdgC3dEK7h3E4Kccu30tw7rbZeAJe7Co5JmHrrkwsz0pijAXFcjrbNkWQLI867bTogGGjL847OBNQ8FHSQJN9Gs1RY-GwaXh9ubffApwEdd0","direction":"https:\/\/maps.googleapis.com\/maps\/api\/staticmap?size=600x150&maptype=roadmap&markers=color:green%7Clabel:S%7C33.4323%2C36.24329&markers=color:red%7Clabel:D%7C33.41301%2C36.23664&path=color:0x007bff%7Cweight:5%7C33.4323%2C36.24329%7C33.41301%2C36.23664&key=AIzaSyAPFR_XbRN0XZ5Iz3AYDjNYHGJG2s2QWwM","DurationToPassenger":"0","rideId":"314","passengerId":"849a9faf3e68c1aeb708","durationOfRideValue":"575","paymentAmount":"19754.00","paymentMethod":"cash","isHaveSteps":"startEnd","step0":"33.42334065389521,36.23577006161213","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"0.00","carType":"Speed","kazan":"8","startNameLocation":"\u0623\u0634\u0631\u0641\u064a\u0629","endNameLocation":"\u0627\u0644\u0634\u064a\u062e \u0625\u0628\u0631\u0627\u0647\u064a\u0645","timeOfOrder":"2025-12-01T10:28:11.316238","totalPassenger":"19754.00"} [2025-12-01 10:28:09] SQL statement prepared successfully. Attempting to execute... [2025-12-01 10:28:09] SUCCESS: Database insert was successful for rideId: 314 [2026-01-08 01:45:12] --- New Request Received --- [2026-01-08 01:45:12] Incoming POST data: {"driver_id":"34feffd3fa72d6bee56b","status":"Apply","passengerLocation":"31.990668","passengerDestination":"35.877682","Duration":"35.930359","totalCost":"3.50","Distance":"8.5 km","name":"Hamza Passenger","phone":"0791234567","email":"client@email.com","WalletChecked":"false","tokenPassenger":"PASSENGER_FCM_TOKEN_XYZ","direction":"","DurationToPassenger":"5 min","rideId":"9999","passengerId":"55","durationOfRideValue":"20 min","paymentAmount":"3.50","paymentMethod":"cash","isHaveSteps":"false","step0":"","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"3.50","carType":"speed","kazan":"2.75","startNameLocation":"\u0627\u0644\u062c\u0627\u0645\u0639\u0629 \u0627\u0644\u0623\u0631\u062f\u0646\u064a\u0629 - \u0627\u0644\u0628\u0648\u0627\u0628\u0629 \u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629","endNameLocation":"\u0627\u0644\u0639\u0628\u062f\u0644\u064a \u0645\u0648\u0644 - \u0627\u0644\u0628\u0648\u0644\u064a\u0641\u0627\u0631\u062f","timeOfOrder":"2026-01-08T01:45:11.370578","totalPassenger":"3.50"} [2026-01-08 01:45:12] SQL statement prepared successfully. Attempting to execute... [2026-01-08 01:45:12] EXCEPTION: An unexpected error occurred: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'direction_url' cannot be null [2026-01-08 21:23:04] --- New Request Received --- [2026-01-08 21:23:04] Incoming POST data: {"driver_id":"34feffd3fa72d6bee56b","status":"Apply","passengerLocation":"32.073743222739","passengerDestination":"36.096920477709","Duration":"35.930359","totalCost":"3.50","Distance":"8.9 km","name":"Hamza Passenger","phone":"0791234567","email":"client@email.com","WalletChecked":"false","tokenPassenger":"PASSENGER_FCM_TOKEN_XYZ","direction":"","DurationToPassenger":"5 min","rideId":"9999","passengerId":"55","durationOfRideValue":"18 min","paymentAmount":"53.50","paymentMethod":"cash","isHaveSteps":"false","step0":"","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"3.50","carType":"speed","kazan":"2.75","startNameLocation":"\u0627\u0644\u062c\u0627\u0645\u0639\u0629 \u0627\u0644\u0623\u0631\u062f\u0646\u064a\u0629 - \u0627\u0644\u0628\u0648\u0627\u0628\u0629 \u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629","endNameLocation":"\u0627\u0644\u0639\u0628\u062f\u0644\u064a \u0645\u0648\u0644 - \u0627\u0644\u0628\u0648\u0644\u064a\u0641\u0627\u0631\u062f","timeOfOrder":"2026-01-08T21:23:03.507502","totalPassenger":"53.50"} [2026-01-08 21:23:04] SQL statement prepared successfully. Attempting to execute... [2026-01-08 21:23:04] EXCEPTION: An unexpected error occurred: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'direction_url' cannot be null [2026-01-22 14:29:49] --- New Request Received --- [2026-01-22 14:29:49] Incoming POST data: {"driver_id":"34feffd3fa72d6bee56b","status":"Apply","passengerLocation":"startLocation","passengerDestination":"endLocation","Duration":"durationToPassenger","totalCost":"totalCost","Distance":"distance","name":"passengerName","phone":"passengerPhone","email":"email","WalletChecked":"WalletChecked","tokenPassenger":"passengerToken","direction":"","DurationToPassenger":"DurationToPassenger","rideId":"rideId","passengerId":"passengerId","durationOfRideValue":"durationOfRideValue","paymentAmount":"paymentAmount","paymentMethod":"cash","isHaveSteps":"isHaveSteps","step0":"step0","step1":"step1","step2":"step2","step3":"step3","step4":"step4","passengerWalletBurc":"totalCost","carType":"carType","kazan":"kazan","startNameLocation":"startNameLocation","endNameLocation":"endNameLocation","timeOfOrder":"2026-01-22T14:29:46.887096","totalPassenger":"paymentAmount"} [2026-01-22 14:29:49] SQL statement prepared successfully. Attempting to execute... [2026-01-22 14:29:49] EXCEPTION: An unexpected error occurred: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'direction_url' cannot be null [2026-01-22 14:31:31] --- New Request Received --- [2026-01-22 14:31:31] Incoming POST data: {"driver_id":"34feffd3fa72d6bee56b","status":"Apply","passengerLocation":"startLocation","passengerDestination":"endLocation","Duration":"durationToPassenger","totalCost":"totalCost","Distance":"distance","name":"passengerName","phone":"passengerPhone","email":"email","WalletChecked":"WalletChecked","tokenPassenger":"passengerToken","direction":"","DurationToPassenger":"DurationToPassenger","rideId":"rideId","passengerId":"passengerId","durationOfRideValue":"durationOfRideValue","paymentAmount":"paymentAmount","paymentMethod":"cash","isHaveSteps":"isHaveSteps","step0":"step0","step1":"step1","step2":"step2","step3":"step3","step4":"step4","passengerWalletBurc":"totalCost","carType":"carType","kazan":"kazan","startNameLocation":"startNameLocation","endNameLocation":"endNameLocation","timeOfOrder":"2026-01-22T14:31:29.409730","totalPassenger":"paymentAmount"} [2026-01-22 14:31:31] SQL statement prepared successfully. Attempting to execute... [2026-01-22 14:31:31] EXCEPTION: An unexpected error occurred: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'direction_url' cannot be null [2026-01-22 14:39:59] --- New Request Received --- [2026-01-22 14:39:59] Incoming POST data: {"driver_id":"34feffd3fa72d6bee56b","status":"Apply","passengerLocation":"startLocation","passengerDestination":"endLocation","Duration":"durationToPassenger","totalCost":"totalCost","Distance":"distance","name":"passengerName","phone":"passengerPhone","email":"email","WalletChecked":"WalletChecked","tokenPassenger":"passengerToken","direction":"","DurationToPassenger":"DurationToPassenger","rideId":"rideId","passengerId":"passengerId","durationOfRideValue":"durationOfRideValue","paymentAmount":"paymentAmount","paymentMethod":"cash","isHaveSteps":"isHaveSteps","step0":"step0","step1":"step1","step2":"step2","step3":"step3","step4":"step4","passengerWalletBurc":"totalCost","carType":"carType","kazan":"kazan","startNameLocation":"startNameLocation","endNameLocation":"endNameLocation","timeOfOrder":"2026-01-22T14:39:56.986847","totalPassenger":"paymentAmount"} [2026-01-22 14:39:59] SQL statement prepared successfully. Attempting to execute... [2026-01-22 14:39:59] EXCEPTION: An unexpected error occurred: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'direction_url' cannot be null [2026-02-20 16:39:52] --- New Request Received --- [2026-02-20 16:39:52] Incoming POST data: {"driver_id":"eefed62b0aeb9e304efd","status":"Apply","passengerLocation":"32.11172","passengerDestination":"36.06738","Duration":"36.06738","totalCost":"173.00","Distance":"0.0","name":"\u062d\u0645\u0632\u0647 \u0639\u0627\u064a\u062f","phone":"963992952235","email":"963992952235@intaleqapp.com","WalletChecked":"false","tokenPassenger":"e9X4q6nL3EuRu2OIsWJ-A2:APA91bE223jfIOjWbSrjF41HZjeZVWc-jm2NAg2sXTmoyHUkoC10uycmxl0Ne4WcE8aojjTm7fWTPm5aEFi1xJKN1Wy0vgupUmSD2LcKBcE1Cym_GTvikME","direction":"","DurationToPassenger":"","rideId":"782","passengerId":"849a9faf3e68c1aeb708","durationOfRideValue":"","paymentAmount":"173.00","paymentMethod":"cash","isHaveSteps":"false","step0":"32.11180279564045,36.067136228084564","step1":"","step2":"","step3":"","step4":"","passengerWalletBurc":"173.00","carType":"Fixed Price","kazan":"0.00","startNameLocation":"\u0648\u0627\u062f\u064a \u0623\u0643\u064a\u062f\u0631","endNameLocation":"\u0648\u0627\u062f\u064a \u0623\u0643\u064a\u062f\u0631","timeOfOrder":"2026-02-20T16:40:10.040464","totalPassenger":"173.00"} [2026-02-20 16:39:52] SQL statement prepared successfully. Attempting to execute... [2026-02-20 16:39:52] EXCEPTION: An unexpected error occurred: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'direction_url' cannot be null ``` ## File: ride/overLay/getArgumentAfterAppliedFromBackground.php ``` prepare($sql); $stmt->bindParam(':driver_id', $driver_id); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row) { // convert WKT POINT back to "lat,lng" foreach (['passenger_location', 'passenger_destination'] as $f) { if (!empty($row["{$f}_wkt"])) { // WKT format: POINT(lng lat) preg_match('/POINT\(([^ ]+) ([^ ]+)\)/', $row["{$f}_wkt"], $m); $row[$f] = "{$m[2]},{$m[1]}"; } unset($row["{$f}_wkt"]); } jsonSuccess($row); } else { jsonError('No data found'); } ``` ## File: ride/promo/add.php ``` prepare($sql); $stmt->bindValue(':promoCode', $promoCode); $stmt->bindValue(':amount', $amount); $stmt->bindValue(':description', $description); $stmt->bindValue(':passengerID', $passengerID); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Promo data saved successfully"); } else { jsonError("Failed to save promo data"); } ?> ``` ## File: ride/promo/update.php ``` prepare($sql); $stmt->bindParam(':promoCode', $promoCode); stmt->bindParam(':description', $description); stmt->bindParam(':validityStartDate', $validityStartDate); $stmt->bindParam(':validityEndDate', $validityEndDate); stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Promo data updated successfully"); } else { jsonError("Failed to update promo data"); } ?> ``` ## File: ride/promo/get.php ``` prepare($sql); $stmt->bindParam(':promo_code', $promo_code, PDO::PARAM_STR); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($result) { jsonSuccess($result); } else { jsonError("Failed to retrieve promo records"); } ?> ``` ## File: ride/promo/getPromoFirst.php ``` encryptData(filterRequest("passengerID")); $passengerID = filterRequest("passengerID"); // استخدم هذا إذا ID رقم فقط $sql = "SELECT `id`, `promo_code`, `amount`, `description`, `validity_start_date`, `validity_end_date` FROM `promos` WHERE `passengerID` = ? AND CURDATE() BETWEEN validity_start_date AND validity_end_date"; $stmt = $con->prepare($sql); $stmt->bindParam(1, $passengerID); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($result) { jsonSuccess($result); } else { jsonError("Failed to retrieve promo records"); } ?> ``` ## File: ride/promo/delete.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); // استخدام bindParam لحماية الاستعلام $stmt->execute(); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Promo data deleted successfully"); } else { jsonError("Failed to delete promo data"); } ?> ``` ## File: ride/promo/getPromoBytody.php ``` = CURDATE();"; $stmt = $con->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($result) { // Print all promo records jsonSuccess($result); } else { // Print a failure message jsonError($message = "Failed to retrieve promo records"); } ?> ``` ## File: ride/carDrivers/add.php ``` encryptData(filterRequest("vin")); $car_plate = $encryptionHelper->encryptData(filterRequest("car_plate")); $make = filterRequest("make"); $model = filterRequest("model"); $year = filterRequest("year"); $expiration_date = filterRequest("expiration_date"); $color = filterRequest("color"); $owner = $encryptionHelper->encryptData(filterRequest("owner")); $color_hex = filterRequest("color_hex"); $address = $encryptionHelper->encryptData(filterRequest("address")); $displacement = filterRequest("displacement"); $fuel = filterRequest("fuel"); $registration_date = filterRequest("registration_date"); // SQL statement $sql = "INSERT INTO `captains_car` ( `driverID`, `vin`, `car_plate`, `make`, `model`, `year`, `expiration_date`, `color`, `owner`, `color_hex`, `address`, `displacement`, `fuel`, `registration_date` ) VALUES ( :driverID, :vin, :car_plate, :make, :model, :year, :expiration_date, :color, :owner, :color_hex, :address, :displacement, :fuel, :registration_date )"; $stmt = $con->prepare($sql); // Bind parameters $stmt->bindParam(':driverID', $driverID); $stmt->bindParam(':vin', $vin); $stmt->bindParam(':car_plate', $car_plate); $stmt->bindParam(':make', $make); $stmt->bindParam(':model', $model); $stmt->bindParam(':year', $year, PDO::PARAM_INT); $stmt->bindParam(':expiration_date', $expiration_date); $stmt->bindParam(':color', $color); $stmt->bindParam(':owner', $owner); $stmt->bindParam(':color_hex', $color_hex); $stmt->bindParam(':address', $address); $stmt->bindParam(':displacement', $displacement); $stmt->bindParam(':fuel', $fuel); $stmt->bindParam(':registration_date', $registration_date); $stmt->execute(); $insertedId = $con->lastInsertId(); if ($stmt->rowCount() > 0) { jsonSuccess(["id" => $insertedId]); } else { jsonError("Failed to save car registration information"); } ?> ``` ## File: ride/carDrivers/get.php ``` decryptData($v); } catch (\Throwable $e) { return $v; } }; // أعمدة مشتركة/موحّدة للإخراج return [ 'id' => $get('id'), 'driverID' => $get('driverID'), 'vin' => $dec($get('vin')), // إن كان مُشفراً 'car_plate' => $dec($get('car_plate')), // إن كان مُشفراً 'make' => $get('make'), 'model' => $get('model'), 'year' => $get('year'), 'expiration_date' => $get('expiration_date'), 'color' => $get('color'), 'color_hex' => $get('color_hex'), 'owner' => $dec($get('owner')), // إن كان مُشفراً 'address' => $dec($get('address')), // قد لا يوجد في CarRegistration 'type' => $get('type'), // إن وُجد 'isDefault' => (int)($get('isDefault', 0)), 'status' => $get('status'), 'created_at' => $get('created_at'), 'source' => $source, // لمعرفة مصدر السجل ]; } // 1) جلب من captains_car $sql1 = "SELECT * FROM captains_car WHERE driverID = :driverID"; $st1 = $con->prepare($sql1); $st1->execute([':driverID' => $driverID]); $rows1 = $st1->fetchAll(PDO::FETCH_ASSOC); // 2) جلب من CarRegistration $sql2 = "SELECT * FROM CarRegistration WHERE driverID = :driverID"; $st2 = $con->prepare($sql2); $st2->execute([':driverID' => $driverID]); $rows2 = $st2->fetchAll(PDO::FETCH_ASSOC); // 3) توحيد النتائج مع فك التشفير $result = []; foreach ($rows1 as $r) { $result[] = normalize_car_row($r, 'captains_car', $encryptionHelper); } foreach ($rows2 as $r) { $result[] = normalize_car_row($r, 'CarRegistration', $encryptionHelper); } if (empty($result)) { jsonError("No driver car data found"); exit; } // 4) ترتيب النتيجة: السيارات الافتراضية أولاً ثم الأحدث إنشاءً usort($result, function($a, $b) { // isDefault desc if ((int)$a['isDefault'] !== (int)$b['isDefault']) { return (int)$b['isDefault'] <=> (int)$a['isDefault']; } // created_at desc (لو أحدهم null لن يؤثر) return strcmp((string)$b['created_at'], (string)$a['created_at']); }); jsonSuccess($result); } catch (PDOException $e) { error_log("Database error (get_driver_cars): " . $e->getMessage()); jsonError("Database error occurred"); } catch (Throwable $e) { error_log("App error (get_driver_cars): " . $e->getMessage()); jsonError("Unexpected error occurred"); } ``` ## File: ride/carDrivers/delete.php ``` prepare($sql); $stmt->bindParam(':id', $id, PDO::PARAM_INT); $stmt->execute(); // التحقق من نجاح الحذف if ($stmt->rowCount() > 0) { jsonSuccess(null, "Car registration deleted successfully"); } else { jsonError("Failed to delete car registration"); } ?> ``` ## File: Admin/jwtService.php ``` enforce(RateLimiter::identifier(), 'login'); try { $email = filterRequest('email') ?? ''; $password = filterRequest('password') ?? ''; $audience = filterRequest('aud') ?? ''; $allowed1 = getenv('allowedService1'); $allowed2 = getenv('allowedService2'); $allowedAudiences = array_values(array_filter([$allowed1, $allowed2])); if (empty($email) || empty($password) || empty($audience)) { jsonError('Email and password are required.', 400); } if (!in_array($audience, $allowedAudiences, true)) { jsonError('Invalid audience', 400); } $con = Database::get('main'); // استخدام user table ويفضل استخدام password_hash لاحقا مثل admin_users $stmt = $con->prepare("SELECT `id`, `password`, `email` FROM `users` WHERE email = :email LIMIT 1"); $stmt->execute([':email' => $email]); $user = $stmt->fetch(); $startTime = microtime(true); // دعم password_verify مع البقاء على التوافق مع كلمات السر القديمة (Plain Text) if ($user && (password_verify($password, $user['password']) || $user['password'] === $password)) { $limiter->reset(RateLimiter::identifier(), 'login'); $jwtService = new JwtService($redis); $jwt = $jwtService->generateAccessToken($user['id'], 'service', $audience); $refresh = $jwtService->generateRefreshToken($user['id']); jsonSuccess([ 'jwt' => $jwt, 'refresh_token' => $refresh['token'], 'expires_in' => 900 // أو 6600 كما كان في الكود الأصلي ]); } else { $elapsed = microtime(true) - $startTime; if ($elapsed < 0.1) usleep((int)((0.1 - $elapsed) * 1000000)); securityLog("Service login failed", ['email' => $email]); jsonError('Invalid email or password', 401); } } catch (PDOException $e) { securityLog("Service Login PDO Error", ['msg' => $e->getMessage()]); jsonError('Login failed: Database error', 500); } catch (Exception $e) { securityLog("Service Login Error", ['msg' => $e->getMessage()]); jsonError('Login failed: Server error', 500); } ``` ## File: Admin/send_whatsapp_message.php ``` $receiver, "type" => "text", "message" => $message, "instance_id" => $instanceId, "access_token"=> $accessToken ]; error_log("[send_whatsapp_message.php] Sending payload: " . json_encode($payload)); // إرسال الطلب $response = callAPI("POST", $apiUrl, json_encode($payload)); error_log("[send_whatsapp_message.php] Raw response: " . print_r($response, true)); // فحص الاستجابة if ($response && !isset($response->error) && (isset($response->status) && $response->status == 'success' || isset($response->message))) { jsonSuccess(null, "Message sent successfully."); } else { $errorMessage = isset($response->message) ? $response->message : "Unknown error."; error_log("[send_whatsapp_message.php] Failed to send: $errorMessage"); jsonError("Failed to send message: $errorMessage"); } // دالة cURL function callAPI($method, $url, $data) { $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_POSTFIELDS => $data, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Accept: application/json" ], ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { error_log("[callAPI] cURL Error: $err"); return null; } else { return json_decode($response); } } ?> ``` ## File: Admin/sendEmailToDrivertransaction.php ```
$appName Logo

Payment Sent - $appName

Thank you for being a valued driver on the $appName platform.

We have sent a payment of $totalAmount EGP to your account $accountBank.

Please note that it may take a few days for your bank to process this transaction.

We appreciate your efforts and are proud to have you on board with $appName.

Regards,
tripz Team

tripz, Egypt | $domain

"; // محتوى الإيميل - باللغة العربية $bodyEmailAr = "
$appName

تم إرسال الدفعة - $appName

شكرًا لك لكونك سائقًا مميزًا على منصة $appName.

لقد تم إرسال دفعة قدرها $totalAmount جنيه إلى حسابك $accountBank.

يرجى ملاحظة أن عملية التحويل قد تستغرق بضعة أيام حسب إجراءات البنك.

نقدّر جهودك ونتطلع إلى استمرار الشراكة معك على تطبيق $appName.

مع التحية،
فريق $appName

$appName - مصر | $domain

"; // إعدادات الإيميل $supportEmail = 'support@tripz-egypt.com'; $headers = "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: text/html; charset=UTF-8\r\n"; $headers .= "From: tripz Egypt <$supportEmail>\r\n"; // إرسال الإيميل إن وُجد عنوان صالح if (!empty($driverEmail)) { $subject = "Payment Sent - $appName"; $message = ($language === 'ar') ? $bodyEmailAr : $bodyEmail; if (mail($driverEmail, $subject, $message, $headers)) { jsonSuccess(null, "Email sent successfully to $driverEmail"); } else { jsonError("Failed to send email to $driverEmail"); } } else { jsonError("Invalid or missing driver email address."); } ?> ``` ## File: Admin/getPassengerDetails.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); // ✅ فك التشفير للحقول الحساسة foreach ($result as &$row) { $fieldsToDecrypt = [ "phone", "email", "gender", "birthdate", "site", "first_name", "last_name", "sosPhone", "education", "employmentType", "maritalStatus", "passengerToken" ]; foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && $row[$field] !== null) { $decrypted = $encryptionHelper->decryptData($row[$field]); if ($decrypted !== false) { $row[$field] = $decrypted; } else { // سجل أو تجاهل القيم التي فشل فك تشفيرها $row[$field] = null; // أو احتفظ بالقيمة المشفرة error_log("Failed to decrypt field '$field' for passenger ID: " . $row['id']); } } } } if ($stmt->rowCount() > 0) { jsonSuccess($data = $result); } else { jsonError("No records found"); } ?> ``` ## File: Admin/view_errors.php ``` prepare("SELECT * FROM `error` WHERE `status` = ? ORDER BY `created_at` DESC"); $stmt->execute(array($status)); } else { // إذا لم يتم تحديد status، قم بجلب جميع الأخطاء $stmt = $con->prepare("SELECT * FROM `error` ORDER BY `created_at` DESC"); $stmt->execute(); } // جلب جميع النتائج $errors = $stmt->fetchAll(PDO::FETCH_ASSOC); $count = $stmt->rowCount(); if ($count > 0) { // إرجاع البيانات كـ JSON مع رسالة نجاح echo json_encode(array("status" => "success", "data" => $errors)); } else { // في حال عدم وجود أخطاء، إرجاع رسالة نجاح مع بيانات فارغة echo json_encode(array("status" => "success", "data" => [])); } ?> ``` ## File: Admin/getPassengerbyEmail.php ``` encryptData(filterRequest("passengerEmail")); $passengerId = filterRequest("passengerId"); $passengerphone = $encryptionHelper->encryptData(filterRequest("passengerphone")); $sql = "SELECT `passengers`.`id`, `passengers`.`phone`, `passengers`.`email`, `passengers`.`gender`, `passengers`.`status`, `passengers`.`birthdate`, `passengers`.`site`, `passengers`.`first_name`, `passengers`.`last_name`, `passengers`.`sosPhone`, `passengers`.`education`, `passengers`.`employmentType`, `passengers`.`maritalStatus`, `passengers`.`created_at`, `passengers`.`updated_at`, ( SELECT COUNT(`id`) FROM `passengers` ) AS countPassenger, ( SELECT COUNT(`id`) FROM `feedBack` ) AS countFeedback, ( SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2)) FROM `ratingPassenger` WHERE `passenger_id` = `passengers`.`id` ) AS ratingPassenger, ( SELECT COUNT(`driverID`) FROM `ratingPassenger` WHERE `passenger_id` = `passengers`.`id` ) AS countDriverRate, ( SELECT COUNT(`passengerID`) FROM `canecl` WHERE `passengerID` = `passengers`.`id` ) AS countPassengerCancel, ( SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2)) FROM `ratingDriver` WHERE `passenger_iD` = `passengers`.`id` ) AS passengerAverageRating, ( SELECT COUNT(`driver_id`) FROM `ratingDriver` WHERE `passenger_id` = `passengers`.`id` ) AS countPassengerRate, ( SELECT COUNT(`passenger_id`) FROM `ride` WHERE `passenger_id` = `passengers`.`id` ) AS countPassengerRide, ( SELECT `token` FROM `tokens` WHERE `passengerID` = `passengers`.`id` ) AS passengerToken FROM `passengers` WHERE passengers.email = :email OR passengers.phone = :phone OR passengers.id = :id "; $stmt = $con->prepare($sql); $stmt->bindParam(":email", $passengerEmail); $stmt->bindParam(":phone", $passengerphone); $stmt->bindParam(":id", $passengerId); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير للحقول الحساسة foreach ($result as &$row) { $fieldsToDecrypt = [ "phone", "email", "gender", "birthdate", "site", "first_name", "last_name", "sosPhone", "education", "employmentType", "maritalStatus" ]; foreach ($fieldsToDecrypt as $field) { if (isset($row[$field])) { $row[$field] = $encryptionHelper->decryptData($row[$field]); } } } if ($stmt->rowCount() > 0) { jsonSuccess($data = $result); } else { jsonError("No records found"); } ?> ``` ## File: Admin/errorApp.php ``` prepare($sql); // ربط المتغيرات بالقيم $stmt->bindParam(':error', $error); $stmt->bindParam(':userId', $userId); $stmt->bindParam(':userType', $userType); $stmt->bindParam(':phone', $phone); $stmt->bindParam(':device', $device); $stmt->bindParam(':details', $details); // <-- ربط المتغير الجديد $stmt->execute(); if ($stmt->rowCount() > 0) { // طباعة رسالة نجاح jsonSuccess($message = "Error data saved successfully"); } else { // طباعة رسالة فشل jsonError($message = "Failed to save error data"); } ?> ``` ## File: Admin/getVisaForEachDriver.php ``` 0 AND total_amount > 100 LIMIT 0, 25"; $stmt = $con->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير للحقول المطلوبة foreach ($result as &$row) { $fieldsToDecrypt = ['phone', 'email', 'accountBank', 'bankCode', 'name_arabic']; foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && $row[$field] !== null) { $row[$field] = $encryptionHelper->decryptData($row[$field]); } } } if ($stmt->rowCount() > 0) { jsonSuccess($result); } else { jsonError("No wallet record found"); } ?> ``` ## File: Admin/ggg.php ``` $adminPhoneParam]); jsonError('Access denied for this admin phone.', 403); } if (empty($text) || ($action !== 'encrypt' && $action !== 'decrypt')) { jsonError('Invalid input: need action=encrypt|decrypt and non-empty text.', 400); } // 4) تنفيذ التشفير / الفك (التوافق مع CBC الحالي) try { if ($action === 'encrypt') { $result = $encryptionHelper->encryptData($text); } else { // decrypt $result = $encryptionHelper->decryptData($text); } jsonSuccess([ 'action' => $action, 'result' => (string) $result, ]); } catch (Exception $e) { securityLog("Encryption tool failed", ['error' => $e->getMessage()]); jsonError('Operation failed.', 500); } ``` ## File: Admin/facebook.php ``` $appId, 'app_secret' => $appSecret, 'default_graph_version' => 'v16.0', // Adjust based on your API version ]); try { // Generate the app token $appToken = $appId . '|' . $appSecret; // Debug the token $response = $fb->get('/debug_token?input_token=' . $accessToken, $appToken); $tokenData = $response->getDecodedBody(); // Display the token details echo "Token Data:\n"; print_r($tokenData); if (isset($tokenData['data']['expires_at'])) { echo "Expires At: " . date('Y-m-d H:i:s', $tokenData['data']['expires_at']) . "\n"; } else { echo "The token does not have an expiration time.\n"; } } catch (Facebook\Exceptions\FacebookResponseException $e) { echo 'Graph API Error: ' . $e->getMessage(); } catch (Facebook\Exceptions\FacebookSDKException $e) { echo 'SDK Error: ' . $e->getMessage(); } ``` ## File: Admin/dashbord.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($result) { jsonSuccess($result); } else { jsonError("No dashboard data found"); } ?> ``` ## File: Admin/getPassengerDetailsByPassengerID.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); // ✅ فك تشفير الحقول الحساسة foreach ($result as &$row) { $fieldsToDecrypt = [ "phone", "email", "gender", "birthdate", "site", "first_name", "last_name", "sosPhone", "education", "employmentType", "maritalStatus", "passengerToken" ]; foreach ($fieldsToDecrypt as $field) { if (isset($row[$field]) && $row[$field] !== null) { $row[$field] = $encryptionHelper->decryptData($row[$field]); } } } if ($stmt->rowCount() > 0) { jsonSuccess($result); } else { jsonError("No records found"); } ?> ``` ## File: Admin/rides/get_driver_live_pos.php ``` prepare($sql); $stmt->execute([$driver_id]); $data = $stmt->fetch(PDO::FETCH_ASSOC); if ($data) { jsonSuccess($data); } else { // السائق ليس له موقع مسجل (ربما لم يشغل التطبيق بعد) jsonError("No location found for this driver"); } } catch (PDOException $e) { jsonError("Database Error: " . $e->getMessage()); } ?> ``` ## File: Admin/rides/admin_get_rides_by_phone.php ``` encryptData($raw); try { error_log("[get_last_ride] Searching passenger with phone=$raw"); // 1) ابحث عن الراكب بالهاتف المشفّر $selP = $con->prepare(" SELECT id, first_name, last_name, phone FROM passengers WHERE phone =:enc_raw LIMIT 1 "); $selP->execute(['enc_raw' => $enc_raw]); $passenger = $selP->fetch(PDO::FETCH_ASSOC); if (!$passenger) { error_log("[get_last_ride] Passenger not found (phone=$raw)"); jsonError('Passenger not found for provided phone'); exit; } error_log("[get_last_ride] Passenger found id=" . $passenger['id']); // 2) آخر رحلة لهذا الراكب $rideStmt = $con->prepare(" SELECT r.id, r.start_location, r.end_location, r.date, r.time, r.endtime, r.status, r.paymentMethod, r.carType, r.price, r.price_for_driver, r.price_for_passenger, r.distance, r.driver_id, r.passenger_id, r.created_at, r.updated_at, r.DriverIsGoingToPassenger, r.rideTimeStart, r.rideTimeFinish, d.first_name AS driver_first_name, d.last_name AS driver_last_name FROM ride r LEFT JOIN driver d ON d.id = r.driver_id WHERE r.passenger_id = :pid ORDER BY r.created_at DESC, r.id DESC LIMIT 1 "); $rideStmt->execute(['pid' => $passenger['id']]); $ride = $rideStmt->fetch(PDO::FETCH_ASSOC); if (!$ride) { error_log("[get_last_ride] No rides found for passenger_id=" . $passenger['id']); jsonError('No rides found for this passenger'); exit; } error_log("[get_last_ride] Found ride id=" . $ride['id'] . " for passenger_id=" . $passenger['id']); // فك التشفير $passenger['first_name'] = $encryptionHelper->decryptData($passenger['first_name']); $passenger['last_name'] = $encryptionHelper->decryptData($passenger['last_name']); $passenger['phone'] = $encryptionHelper->decryptData($passenger['phone']); $ride['driver_first_name'] = $encryptionHelper->decryptData($ride['driver_first_name']); $ride['driver_last_name'] = $encryptionHelper->decryptData($ride['driver_last_name']); // 3) اطبع النتيجة $response = [ 'passenger' => [ 'id' => $passenger['id'], 'first_name' => $passenger['first_name'], 'last_name' => $passenger['last_name'], 'phone' => $passenger['phone'], ], 'ride' => $ride ]; error_log("[get_last_ride] Success response for passenger_id=" . $passenger['id']); jsonSuccess($response); } catch (Throwable $e) { error_log("[get_last_ride] Exception: " . $e->getMessage()); jsonError("Error: " . $e->getMessage()); } ``` ## File: Admin/rides/get_rides_by_status.php ``` prepare($sql); $stmt->execute($params); $rides = $stmt->fetchAll(PDO::FETCH_ASSOC); $data = []; foreach ($rides as $row) { // فك التشفير try { $row['d_fname'] = $encryptionHelper->decryptData($row['d_fname']); } catch(Exception $e){} try { $row['d_lname'] = $encryptionHelper->decryptData($row['d_lname']); } catch(Exception $e){} try { $row['d_phone'] = $encryptionHelper->decryptData($row['d_phone']); } catch(Exception $e){} try { $row['p_fname'] = $encryptionHelper->decryptData($row['p_fname']); } catch(Exception $e){} try { $row['p_lname'] = $encryptionHelper->decryptData($row['p_lname']); } catch(Exception $e){} try { $row['p_phone'] = $encryptionHelper->decryptData($row['p_phone']); } catch(Exception $e){} $row['driver_full_name'] = trim($row['d_fname'] . ' ' . $row['d_lname']); $row['passenger_full_name'] = trim($row['p_fname'] . ' ' . $row['p_lname']); if(empty($row['driver_full_name'])) $row['driver_full_name'] = "Unknown Driver"; if(empty($row['passenger_full_name'])) $row['passenger_full_name'] = "Unknown Passenger"; $data[] = $row; } jsonSuccess($data); } catch (PDOException $e) { jsonError("Database Error: " . $e->getMessage()); } ?> ``` ## File: Admin/rides/monitorRide.php ``` encryptData($phone); error_log("[MONITOR_RIDE] 2. Encrypted Phone: " . $encPhone); // Check Driver Table $driverQuery = $con->prepare("SELECT id AS driverID FROM driver WHERE phone = :phone LIMIT 1"); $driverQuery->execute([':phone' => $encPhone]); $driver = $driverQuery->fetch(PDO::FETCH_ASSOC); // Check Passenger Table $customerQuery = $con->prepare("SELECT id AS customerID FROM passengers WHERE phone = :phone LIMIT 1"); $customerQuery->execute([':phone' => $encPhone]); $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) جلب آخر رحلة حالتها "بدأت" بناءً على نوع المستخدم //------------------------------------------------------------------------ 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 = 'Begin' 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 = 'Begin' 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 ride with status 'Begin' found."); jsonError("لا توجد رحلة بدأت لهذا المستخدم."); exit; } else { error_log("[MONITOR_RIDE] 4. SUCCESS: Active Ride Found. Ride ID: " . $ride['id']); } //------------------------------------------------------------------------ // 3) جلب معلومات السائق من الرحلة //------------------------------------------------------------------------ // FIX 1: Safe assignment of driver ID (checking driverID vs driver_id) $rideDriverID = $ride['driverID'] ?? $ride['driver_id']; error_log("[MONITOR_RIDE] 5. Fetching info for Driver ID from Ride: " . $rideDriverID); // FIX 2: Select first_name and last_name instead of fullname $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']); // FIX 4: Decrypt First Name and Last Name $driverInfo['first_name'] = $encryptionHelper->decryptData($driverInfo['first_name']); $driverInfo['last_name'] = $encryptionHelper->decryptData($driverInfo['last_name']); // Construct fullname for the response $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) جلب آخر موقع للسائق من جدول driver_location بشرط الحالة ON //------------------------------------------------------------------------ error_log("[MONITOR_RIDE] 6. Querying Tracking DB for Driver ID: " . $rideDriverID); // FIX 3: Changed ORDER BY id DESC to ORDER BY updated_at DESC $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'] . " Updated=" . $location['updated_at']); } else { error_log("[MONITOR_RIDE] 6. WARNING: No live location found (status=ON) or list empty."); } //------------------------------------------------------------------------ // 5) تجهيز البيانات للرد //------------------------------------------------------------------------ $response = [ "ride_details" => $ride, "driver_details" => $driverInfo, "driver_location" => $location ?: "No live location" ]; error_log("[MONITOR_RIDE] 7. Sending Success Response."); jsonSuccess($response); ?> ``` ## File: Admin/rides/admin_update_ride_status.php ``` beginTransaction(); // إن أردت ختم وقت النهاية تلقائيًا عند الإكمال if ($status === 'Completed') { $sql = "UPDATE ride SET status = :st, rideTimeFinish = IFNULL(rideTimeFinish, NOW()), updated_at = CURRENT_TIMESTAMP WHERE id = :id"; } else { $sql = "UPDATE ride SET status = :st, updated_at = CURRENT_TIMESTAMP WHERE id = :id"; } $stmt = $con->prepare($sql); $ok = $stmt->execute(['st' => $status, 'id' => $rideId]); if (!$ok || $stmt->rowCount() === 0) { $con->rollBack(); jsonError("Ride not found or no change"); exit; } // أعِدّ بيانات الرحلة المحدّثة (للتحديث الفوري في الواجهة) $fetch = $con->prepare(" SELECT r.id, r.start_location, r.end_location, r.date, r.time, r.endtime, r.status, r.paymentMethod, r.carType, r.price, r.price_for_driver, r.price_for_passenger, r.distance, r.driver_id, r.passenger_id, r.created_at, r.updated_at, r.DriverIsGoingToPassenger, r.rideTimeStart, r.rideTimeFinish, d.first_name AS driver_first_name, d.last_name AS driver_last_name FROM ride r LEFT JOIN driver d ON d.id = r.driver_id WHERE r.id = :id LIMIT 1 "); $fetch->execute(['id' => $rideId]); $ride = $fetch->fetch(PDO::FETCH_ASSOC); $con->commit(); jsonSuccess(['ride' => $ride, 'message' => 'Status updated']); } catch (Throwable $e) { if ($con->inTransaction()) $con->rollBack(); jsonError("Error: ".$e->getMessage()); } ``` ## File: Admin/AdminCaptain/add.php ``` ``` ## File: Admin/AdminCaptain/update.php ``` ``` ## File: Admin/AdminCaptain/get.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك تشفير الحقول الحساسة foreach ($result as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); $row['email'] = $encryptionHelper->decryptData($row['email']); $row['gender'] = $encryptionHelper->decryptData($row['gender']); $row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']); $row['site'] = $encryptionHelper->decryptData($row['site']); $row['first_name'] = $encryptionHelper->decryptData($row['first_name']); $row['last_name'] = $encryptionHelper->decryptData($row['last_name']); $row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']); $row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']); } if (count($result) > 0) { jsonSuccess($result); } else { jsonError("No records found"); } ?> ``` ## File: Admin/AdminCaptain/getCaptainDetailsByEmailOrIDOrPhone.php ``` encryptData(filterRequest("driverEmail")); $driverPhone = $encryptionHelper->encryptData(filterRequest("driverPhone")); $sql = "SELECT `driver`.`id`, `driver`.`phone`, `driver`.`email`, `driver`.`gender`, `driver`.`status`, `driver`.`birthdate`, `driver`.`site`, `driver`.`first_name`, `driver`.`last_name`, `driver`.`education`, `driver`.`employmentType`, `driver`.`maritalStatus`, `driver`.`created_at`, `driver`.`updated_at`, ( SELECT COUNT(*) FROM `driver` ) AS countPassenger, ( SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2)) FROM `ratingPassenger` WHERE `ratingPassenger`.`driverID` = `driver`.`id` ) AS ratingPassenger, ( SELECT COUNT(*) FROM `ratingPassenger` WHERE `driverID` = `driver`.`id` ) AS countDriverRate, ( SELECT COUNT(*) FROM `canecl` WHERE `driverID` = `driver`.`id` ) AS countPassengerCancel, ( SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2)) FROM `ratingDriver` WHERE `driver_id` = `driver`.`id` ) AS passengerAverageRating, ( SELECT COUNT(*) FROM `ratingDriver` WHERE `driver_id` = `driver`.`id` ) AS countPassengerRate, ( SELECT COUNT(*) FROM `ride` WHERE `driver_id` = `driver`.`id` ) AS countPassengerRide, ( SELECT `token` FROM `driverToken` WHERE `captain_id` = `driver`.`id` LIMIT 1 ) AS passengerToken FROM `driver` WHERE `driver`.`email` = :email OR `driver`.`phone` = :phone OR `driver`.`id` = :id ORDER BY passengerAverageRating DESC LIMIT 10 "; $stmt = $con->prepare($sql); $stmt->bindParam(":email", $driverEmail); $stmt->bindParam(":phone", $driverPhone); $stmt->bindParam(":id", $driver_id); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك تشفير الحقول الحساسة foreach ($result as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); $row['email'] = $encryptionHelper->decryptData($row['email']); $row['gender'] = $encryptionHelper->decryptData($row['gender']); $row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']); $row['site'] = $encryptionHelper->decryptData($row['site']); $row['first_name'] = $encryptionHelper->decryptData($row['first_name']); $row['last_name'] = $encryptionHelper->decryptData($row['last_name']); $row['education'] = $encryptionHelper->decryptData($row['education']); $row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']); $row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']); } if ($stmt->rowCount() > 0) { jsonSuccess($result); } else { jsonError("No records found"); } ?> ``` ## File: Admin/AdminCaptain/getCaptainDetailsById.php ``` prepare($sql); $stmt->bindParam(':driver_id', $driver_id); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك تشفير الحقول الحساسة بعد الجلب foreach ($result as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); $row['email'] = $encryptionHelper->decryptData($row['email']); $row['gender'] = $encryptionHelper->decryptData($row['gender']); $row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']); $row['site'] = $encryptionHelper->decryptData($row['site']); $row['first_name'] = $encryptionHelper->decryptData($row['first_name']); $row['last_name'] = $encryptionHelper->decryptData($row['last_name']); $row['education'] = $encryptionHelper->decryptData($row['education']); $row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']); $row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']); } if ($stmt->rowCount() > 0) { jsonSuccess($result); } else { jsonError("No records found"); } ?> ``` ## File: Admin/AdminCaptain/delete.php ``` ``` ## File: Admin/AdminCaptain/getDriversPhonesAndTokens.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير للحقول الحساسة foreach ($result as &$row) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); if (!empty($row['token'])) { $row['token'] = $encryptionHelper->decryptData($row['token']); } } if ($stmt->rowCount() > 0) { jsonSuccess($result); } else { jsonError("No records found"); } ?> ``` ## File: Admin/auth/login.php ``` prepare("SELECT * FROM adminUser WHERE device_number = ? AND name = ?"); $stmt->execute([$device, $phone]); if ($stmt->rowCount() > 0) { $admin = $stmt->fetch(PDO::FETCH_ASSOC); // يمكن لاحقًا توليد توكن أو بيانات أخرى printSuccess([ "message" => "تم التحقق بنجاح", "admin" => $admin, ]); } else { jsonError("بيانات الدخول غير صحيحة أو غير مسجلة."); } ``` ## File: Admin/auth/send_otp_admin.php ``` prepare("INSERT INTO token_verification_admin (phone_number, token, expiration_time) VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 5 MINUTE)) ON DUPLICATE KEY UPDATE token = VALUES(token), expiration_time = VALUES(expiration_time)"); $stmt->execute([$receiver, $otp]); // error_log("[send_otp_admin] OTP saved to database successfully for $receiver"); jsonSuccess(null, "OTP sent successfully."); } catch (PDOException $e) { // error_log("[send_otp_admin] Database error: " . $e->getMessage()); jsonError("حدث خطأ في حفظ الرمز."); } } else { // error_log("[send_otp_admin] Failed to send WhatsApp message to $receiver"); jsonError("فشل في إرسال الرمز عبر WhatsApp."); } //error_log("--- [send_otp_admin] Script ended ---"); ?> ``` ## File: Admin/auth/verify_otp_admin.php ``` prepare("SELECT * FROM token_verification_admin WHERE phone_number = ? AND token = ? AND expiration_time >= NOW()"); $stmt->execute([$phone, $otp]); if ($stmt->rowCount() > 0) { // ✅ تحقق ناجح - ننتقل إلى إدخال أو تحديث سجل adminUser // تحقق إن كان المستخدم موجود مسبقًا $checkAdmin = $con->prepare("SELECT * FROM adminUser WHERE name = ?"); $checkAdmin->execute([$phone]); $now = date("Y-m-d H:i:s"); if ($checkAdmin->rowCount() > 0) { // المستخدم موجود ✅ تحديث device_number و updated_at $update = $con->prepare("UPDATE adminUser SET device_number = ?, updated_at = ? WHERE name = ?"); $update->execute([$deviceNumber, $now, $phone]); jsonSuccess(["message" => "verified and updated existing admin"]); } else { // المستخدم غير موجود ✅ إدخال جديد $insert = $con->prepare("INSERT INTO adminUser (device_number, name, created_at, updated_at) VALUES (?, ?, ?, ?)"); $insert->execute([$deviceNumber, $phone, $now, $now]); jsonSuccess(["message" => "verified and new admin created"]); } } else { // ❌ رمز التحقق غير صالح jsonError("رمز التحقق غير صالح أو منتهي."); } ``` ## File: Admin/driver/remove_from_blacklist.php ``` encryptData($phone); $sql = "DELETE FROM blacklist_driver WHERE phone = :phone"; $stmt = $con->prepare($sql); $stmt->execute([':phone' => $encPhone]); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Driver removed from blacklist successfully."); } else { jsonError("No driver found in blacklist with this phone."); } } catch (PDOException $e) { jsonError("Error removing from blacklist: " . $e->getMessage()); } ``` ## File: Admin/driver/find_driver_by_phone.php ``` encryptData($phone); // احضار كل الأعمدة باستثناء كلمة المرور $sql = "SELECT * FROM driver WHERE phone = :phone LIMIT 1"; $stmt = $con->prepare($sql); $stmt->execute([':phone' => $encPhone]); $driver = $stmt->fetch(PDO::FETCH_ASSOC); if ($driver) { // ✅ الحقول المشفرة اللي لازم تنفك: $encryptedFields = [ 'phone', 'email', 'first_name', 'last_name', 'national_number', 'address','gender','site', 'birthdate', 'name_arabic', ]; foreach ($encryptedFields as $field) { if (!empty($driver[$field])) { $driver[$field] = $encryptionHelper->decryptData($driver[$field]); } } // ❌ احذف كلمة المرور من النتيجة unset($driver['password']); jsonSuccess($driver); } else { jsonError("No driver found with this phone."); } } catch (PDOException $e) { jsonError("Error searching driver: " . $e->getMessage()); } ``` ## File: Admin/driver/deleteCaptain.php ``` encryptData($phone); // حذف السائق من جدول driver $sqlDel = "DELETE FROM driver WHERE id = :id"; $stmtDel = $con->prepare($sqlDel); $stmtDel->bindParam(':id', $driver_id, PDO::PARAM_INT); $stmtDel->execute(); if ($stmtDel->rowCount() > 0) { // إضافة بيانات السائق المحذوف إلى البلاك ليست $sqlInsert = "INSERT INTO blacklist_driver (driver_id, phone, reason) VALUES (:driver_id, :phone, :reason)"; $stmtInsert = $con->prepare($sqlInsert); $stmtInsert->execute([ 'driver_id' => $driver_id, 'phone' => $encPhone, 'reason' => !empty($reason) ? $reason : "Deleted & blacklisted by admin" ]); jsonSuccess(null, "Driver deleted and blacklisted successfully."); } else { jsonError("No driver found with the provided ID."); } } catch (PDOException $e) { jsonError("Error: " . $e->getMessage()); } ``` ## File: Admin/driver/updateDriverFromAdmin.php ``` encryptData($phone); $sql = "UPDATE `driver` SET `phone` = :encphone WHERE `id` = :id"; $stmt = $con->prepare($sql); // Bind values $stmt->bindParam(':encphone', $encphone, PDO::PARAM_STR); $stmt->bindParam(':id', $driver_id, PDO::PARAM_STR); try { $stmt->execute(); if ($stmt->rowCount() > 0) { // تم التحديث بنجاح jsonSuccess(null, "Phone updated successfully."); } else { // لم يتم العثور على أي سجل للتحديث jsonError("No records updated. Please check the driver ID."); } } catch (PDOException $e) { jsonError("Error updating record: " . $e->getMessage()); } ?> ``` ## File: Admin/driver/getDriverGiftPayment.php ``` encryptData($phone); $sql = "SELECT * FROM `driver` WHERE phone = :encPhone"; $stmt = $con->prepare($sql); // FIX 1: Bind AFTER preparing the statement // FIX 2: Use the same placeholder name (:encPhone) $stmt->bindParam(':encPhone', $encphone, PDO::PARAM_STR); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // Decrypt sensitive fields foreach ($rows as &$row) { if (!empty($row['phone'])) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); } if (!empty($row['name_arabic'])) { $row['name_arabic'] = $encryptionHelper->decryptData($row['name_arabic']); } } jsonSuccess($rows); } else { jsonError("No recent driver location activity found"); } ?> ``` ## File: Admin/driver/getBestDriver.php ``` TIMESTAMP(DATE_SUB(NOW(), INTERVAL 7 DAY)) GROUP BY driver.id ORDER BY driver_count DESC LIMIT 19; "; $stmt = $con->prepare($sql); $stmt->execute(); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // فك التشفير للحقول الحساسة foreach ($rows as &$row) { if (!empty($row['phone'])) { $row['phone'] = $encryptionHelper->decryptData($row['phone']); } if (!empty($row['name_arabic'])) { $row['name_arabic'] = $encryptionHelper->decryptData($row['name_arabic']); } if (!empty($row['token'])) { $row['token'] = $encryptionHelper->decryptData($row['token']); } } jsonSuccess($rows); } else { jsonError($message = "No recent driver location activity found"); } ?> ``` ## File: Admin/driver/deleteRecord.php ``` prepare($sql); // Bind the driver_id parameter $stmt->bindParam(':driver_id', $driver_id, PDO::PARAM_STR); try { // Execute the query $stmt->execute(); if ($stmt->rowCount() > 0) { // Success response jsonSuccess(null, "Record(s) deleted successfully."); } else { // Failure response: no records found to delete jsonError("No records found for the provided driver ID."); } } catch (PDOException $e) { // Handle any SQL errors jsonError("Error deleting records: " . $e->getMessage()); } ?> ``` ## File: Admin/AdminRide/get.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($stmt->rowCount() > 0) { jsonSuccess($result); } else { jsonError("No records found"); } ?> ``` ## File: Admin/AdminRide/getRidesPerMonth.php ``` prepare($sql); $stmt->execute(); $dailyRides = $stmt->fetchAll(PDO::FETCH_ASSOC); // SQL to get current month's total ride count $sqlMonth = " SELECT COUNT(*) AS current_month_rides_count FROM ride WHERE MONTH(date) = :currentMonth AND YEAR(date) = :currentYear "; $stmtMonth = $con->prepare($sqlMonth); $stmtMonth->bindParam(':currentMonth', $currentMonth); $stmtMonth->bindParam(':currentYear', $currentYear); $stmtMonth->execute(); $monthRides = $stmtMonth->fetch(PDO::FETCH_ASSOC); // Append current month total to each row (if needed) foreach ($dailyRides as &$row) { $row['current_month_rides_count'] = $monthRides['current_month_rides_count']; } // Return result if ($dailyRides) { jsonSuccess($dailyRides); } else { jsonError("No records found"); } ?> ``` ## File: Admin/passenger/admin_update_passenger.php ``` encryptData($new_phone); $first_name = $encryptionHelper->encryptData($first_name); $last_name = $encryptionHelper->encryptData($last_name); $enc_norm = $encryptionHelper->encryptData($norm); if ($first_name !== null) { $sets[] = "first_name = :first_name"; $params['first_name'] = trim($first_name); } if ($last_name !== null) { $sets[] = "last_name = :last_name"; $params['last_name'] = trim($last_name); } if ($new_phone !== null) { $sets[] = "phone = :phone"; $params['phone'] = trim($new_phone); // منع تكرار الهاتف على راكب آخر $q = $con->prepare("SELECT id FROM passengers WHERE phone = :ph LIMIT 1"); $q->execute(['ph' => $params['phone']]); $row = $q->fetch(PDO::FETCH_ASSOC); if ($row) { if (!empty($id) && $row['id'] != $id) { jsonError("Phone already used by another passenger"); exit; } if (empty($id) && $row['id'] != $phoneLookup) { jsonError("Phone already used by another passenger"); exit; } } } $whereSql = ""; $whereParams = []; if (!empty($id)) { $whereSql = "id = :pid"; $whereParams['pid'] = $id; } else { $whereSql = "phone = :plk"; $whereParams['plk'] = $phoneLookup; } $sql = "UPDATE passengers SET ".implode(", ", $sets).", updated_at = CURRENT_TIMESTAMP WHERE $whereSql"; $stmt = $con->prepare($sql); $ok = $stmt->execute(array_merge($params, $whereParams)); if ($ok && $stmt->rowCount() > 0) { jsonSuccess(null, "Passenger updated"); } else { jsonError("No change or passenger not found"); } ``` ## File: Admin/passenger/admin_unblacklist.php ``` prepare("DELETE FROM passenger_blacklist WHERE phone_normalized = :phn"); $stmt->execute(['phn' => $phn]); if ($stmt->rowCount() > 0) { jsonSuccess(null, "Removed from blacklist"); } else { jsonError("Phone was not blacklisted"); } ``` ## File: Admin/passenger/admin_delete_and_blacklist_passenger.php ``` beginTransaction(); // احضر السجل if (!empty($id)) { $sel = $con->prepare("SELECT id, phone FROM passengers WHERE id = :id LIMIT 1"); $sel->execute(['id' => $id]); } else { $sel = $con->prepare("SELECT id, phone FROM passengers WHERE phone = :ph LIMIT 1"); $sel->execute(['ph' => $phone]); } $p = $sel->fetch(PDO::FETCH_ASSOC); if (!$p) { throw new Exception("Passenger not found"); } $phRaw = $p['phone']; $phNorm= normalize_phone($phRaw); // أدخِل/حدّث في البلاك ليست $ins = $con->prepare(" INSERT INTO passenger_blacklist (phone, phone_normalized, reason, expires_at) VALUES (:ph, :phn, :r, :exp) ON DUPLICATE KEY UPDATE reason = VALUES(reason), expires_at = VALUES(expires_at) "); $ins->execute([ 'ph' => $phRaw, 'phn' => $phNorm, 'r' => $reason ?: 'Deleted & blacklisted', 'exp' => $exp ?: null ]); // حذف فعلي $del = $con->prepare("DELETE FROM passengers WHERE id = :id"); $del->execute(['id' => $p['id']]); $con->commit(); jsonSuccess(null, "Passenger deleted and blacklisted"); } catch (Throwable $e) { $con->rollBack(); jsonError("Failed: ".$e->getMessage()); } ``` ## File: Admin/employee/add.php ``` prepare($sql); $stmt->execute([$id, $name, $education, $site, $phone, $created_at, $status]); // Check if the query successfully inserted the record if ($stmt->rowCount() > 0) { // If a row was inserted, print success jsonSuccess($message = "Employee record added successfully"); } else { // If no rows were inserted, print failure jsonError($message = "Failed to add employee record"); } ?> ``` ## File: Admin/employee/get.php ``` prepare($sql); $stmt->execute(); // Fetch all records as an associative array $employee_data = $stmt->fetchAll(PDO::FETCH_ASSOC); // Check if any records were retrieved if ($employee_data) { // If records were found, print the data as JSON jsonSuccess($data = $employee_data); } else { // If no records were found, print a failure message jsonError($message = "No employee records found"); } ?> ``` ## File: Admin/error/error_list_last20.php ``` prepare($sql); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($rows); } catch (Exception $e) { error_log("error_list_last20.php: " . $e->getMessage()); jsonError($message = "Failed to fetch last 20 errors"); } ``` ## File: Admin/error/error_search_by_phone.php ``` encryptData(trim($phone)); // ثم بدّل الحقل في WHERE إلى phone = :ph $sql = "SELECT `id`, `error`, `userId`, `userType`, `phone`, `created_at`, `device`, `details`, `status` FROM `error` WHERE `phone` = :ph OR `phone` LIKE :phLike ORDER BY `created_at` DESC LIMIT 20"; $stmt = $con->prepare($sql); $stmt->execute([ ":ph" => trim($phone), ":phLike" => '%' . trim($phone) . '%', // يسمح بجزء من الرقم إن أردت ]); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($rows); } catch (Exception $e) { error_log("error_search_by_phone.php: " . $e->getMessage()); jsonError($message = "Failed to search errors by phone"); } ``` ## File: Admin/adminUser/add.php ``` prepare($sql); $stmt->bindParam(':deviceNumber', $deviceNumber); $stmt->bindParam(':name', $name); $stmt->execute(); if ($stmt->rowCount() > 0) { // Print a success message jsonSuccess($message = "Admin user data saved successfully"); } else { // Print a failure message jsonError($message = "Failed to save admin user data"); } ?> ``` ## File: Admin/adminUser/update.php ``` ``` ## File: Admin/adminUser/get.php ``` prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); if (count($result) === 1) { // Print the first record as a success message jsonSuccess($result[0]); } else { // Print a failure message jsonError($message = "Failed to retrieve Password or user name incorrect"); } ?> ``` ## File: Admin/adminUser/invoice_total.php ``` prepare("SELECT * FROM invoice_records ORDER BY date DESC"); $stmt->execute(); $invoices = $stmt->fetchAll(PDO::FETCH_ASSOC); // ✅ حساب عدد الفواتير ومجموع المبالغ $count = count($invoices); $totalAmount = array_sum(array_column($invoices, 'amount')); echo json_encode([ "status" => "success", "data" => $invoices, "summary" => [ "count" => $count, "total" => $totalAmount ] ]); } catch (PDOException $e) { echo json_encode([ "status" => "error", "message" => "Database error: " . $e->getMessage() ]); } ?> ``` ## File: Admin/adminUser/add_invoice.php ``` 'error', 'message' => 'Invalid file type.']); exit; } $new_filename = $invoiceNumber . "_" . $driverID . '.' . $image_extension; $target_dir = "invoice_images/"; $target_file = $target_dir . $new_filename; if (!is_dir($target_dir)) { if (!mkdir($target_dir, 0755, true)) { error_log("[add_invoice.php] ❌ Failed to create directory: $target_dir"); } } if (!move_uploaded_file($image_file['tmp_name'], $target_file)) { error_log("[add_invoice.php] ❌ Failed to move uploaded file."); echo json_encode(['status' => 'error', 'message' => 'Failed to upload image.']); exit; } $linkImage = 'https://intaleq.xyz/siro/Admin/adminUser/invoice_images/' . $new_filename; error_log("[add_invoice.php] ✅ Image uploaded successfully: $linkImage"); } try { $stmt = $con->prepare("INSERT INTO invoice_records (driverID, invoice_number,name, amount, date, image_link, created_at) VALUES (?, ?, ?,?, ?, ?, ?)"); $stmt->execute([$driverID, $invoiceNumber,$name, $amount, $date, $linkImage, $uploadDate]); echo json_encode([ 'status' => 'success', 'message' => 'Invoice data saved.', 'image' => $linkImage ]); error_log("[add_invoice.php] ✅ Invoice saved successfully."); } catch (PDOException $e) { $errorMsg = $e->getMessage(); error_log("[add_invoice.php] 🛑 PDO ERROR: $errorMsg"); echo json_encode([ 'status' => 'error', 'message' => "Database error: $errorMsg" ]); } ``` ## File: Admin/adminUser/delete.php ``` ``` ## File: EgyptDocuments/uploadEgyptIdBack.php ``` "Failed to save image")); ; exit; } // Store additional information (modify based on your needs) $image_url = $target_dir . $new_filename; // Update if needed $image_details = [ "name" => $image_name, "size" => $image_size, "extension" => $image_extension, "url" => $image_url, ]; // Use the image details for further processing (e.g., display, store in database) // ... echo json_encode(array('status' => 'Image uploaded successfully!')); ?> ``` ## File: EgyptDocuments/uploadEgyptidFront.php ``` "Failed to save image")); ; exit; } // Store additional information (modify based on your needs) $image_url = $target_dir . $new_filename; // Update if needed $image_details = [ "name" => $image_name, "size" => $image_size, "extension" => $image_extension, "url" => $image_url, ]; // Use the image details for further processing (e.g., display, store in database) // ... echo json_encode(array('status' => 'Image uploaded successfully!')); ?> ``` ## File: driver_assurance/add.php ``` encryptData($assured); // $health_insurance_provider = $encryptionHelper->encryptData($health_insurance_provider); // SQL using bind parameters $sql = "INSERT INTO `driver_health_assurance` ( `driver_id`, `assured`, `health_insurance_provider` ) VALUES ( :driver_id, :assured, :health_insurance_provider )"; $stmt = $con->prepare($sql); $stmt->bindParam(':driver_id', $driver_id); $stmt->bindParam(':assured', $assured); $stmt->bindParam(':health_insurance_provider', $health_insurance_provider); if ($stmt->execute()) { jsonSuccess(null, "Health assurance data saved successfully"); } else { jsonError("Failed to save health assurance data"); } ?> ``` ## File: driver_assurance/update.php ``` ``` ## File: driver_assurance/get.php ``` ``` ## File: migration/get_all_driver_fingerprints.php ``` 'Forbidden'])); } try { $stmt = $con->prepare(' SELECT captain_id, fingerPrint FROM driverToken WHERE fingerPrint IS NOT NULL AND fingerPrint != "" ORDER BY captain_id '); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode([ 'status' => 'success', 'count' => count($rows), 'data' => $rows, ]); } catch (Exception $e) { error_log('❌ [get_all_driver_fingerprints] ' . $e->getMessage()); http_response_code(500); echo json_encode(['error' => 'Server error']); } ``` ## File: migration/get_all_fingerprints.php ``` 'Forbidden']); exit; } try { // جلب كل البصمات من جدول tokens // نجيب passengerID + fingerPrint فقط — لا نعطي بيانات حساسة أخرى $stmt = $con->prepare(' SELECT passengerID, fingerPrint, "passenger" AS userType FROM tokens WHERE fingerPrint IS NOT NULL AND fingerPrint != "" ORDER BY passengerID '); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode([ 'status' => 'success', 'count' => count($rows), 'data' => $rows, ]); http_response_code(200); } catch (Exception $e) { error_log('❌ [get_all_fingerprints] ' . $e->getMessage()); http_response_code(500); echo json_encode(['error' => 'Server error']); } ``` ## File: migration/update_driver_fingerprint_admin.php ``` 'Forbidden'])); } try { $captainId = filterRequest('captain_id') ?? ''; $fingerprint = filterRequest('fingerprint') ?? ''; if (empty($captainId) || empty($fingerprint)) { http_response_code(400); exit(json_encode(['error' => 'Missing parameters'])); } $stmt = $con->prepare(' UPDATE driverToken SET fingerPrint = :fp WHERE captain_id = :cid '); $stmt->execute([':fp' => $fingerprint, ':cid' => $captainId]); echo json_encode(['status' => 'success', 'affected' => $stmt->rowCount()]); } catch (Exception $e) { error_log('❌ [update_driver_fingerprint_admin] ' . $e->getMessage()); http_response_code(500); echo json_encode(['error' => 'Server error']); } ``` ## File: migration/update_fingerprint_admin.php ``` 'Forbidden']); exit; } try { $passengerID = filterRequest('passengerID') ?? ''; $fingerprint = filterRequest('fingerprint') ?? ''; if (empty($passengerID) || empty($fingerprint)) { http_response_code(400); echo json_encode(['error' => 'Missing parameters']); exit; } $stmt = $con->prepare(' UPDATE tokens SET fingerPrint = :fp WHERE passengerID = :pid '); $stmt->execute([ ':fp' => $fingerprint, ':pid' => $passengerID, ]); $affected = $stmt->rowCount(); echo json_encode([ 'status' => 'success', 'affected' => $affected, ]); http_response_code(200); } catch (Exception $e) { error_log('❌ [update_fingerprint_admin] ' . $e->getMessage()); http_response_code(500); echo json_encode(['error' => 'Server error']); } ``` ## File: email/sendTripEmail.php ``` authenticate(); $EMAIL_ADDRESS = 'hamzaayed@intaleqapp.com'; // 2. استقبال البيانات وتطهيرها (Sanitization) $passengerName = htmlspecialchars(filterRequest('name') ?? 'User', ENT_QUOTES, 'UTF-8'); $passengerEmail = filter_var(filterRequest('email'), FILTER_SANITIZE_EMAIL); $passengerPhone = htmlspecialchars(filterRequest('phone') ?? '', ENT_QUOTES, 'UTF-8'); $fee = floatval(filterRequest('fee') ?? 0); $startNameLocation = htmlspecialchars(filterRequest('startNameLocation') ?? '', ENT_QUOTES, 'UTF-8'); $endNameLocation = htmlspecialchars(filterRequest('endNameLocation') ?? '', ENT_QUOTES, 'UTF-8'); $timeOfTrip = htmlspecialchars(filterRequest('timeOfTrip') ?? date('Y-m-d H:i:s'), ENT_QUOTES, 'UTF-8'); if (!$passengerEmail || !filter_var($passengerEmail, FILTER_VALIDATE_EMAIL)) { jsonError("Invalid email address"); } $SIRO_SMTP_PASSWORD = getenv('SIRO_SMTP_PASSWORD'); // بناء محتوى الإيميل بتصميم عصري وبريميوم $bodyEmail = "

SIRO

Your journey, our priority

Hello, $passengerName!

Thank you for choosing SIRO. Your trip has been successfully confirmed. Here is your digital receipt:

From: $startNameLocation
To: $endNameLocation
Date & Time: $timeOfTrip
Phone: $passengerPhone
Total Amount
$$fee

If you have any questions, feel free to contact our support team at any time.

"; $mail = new PHPMailer(true); try { $mail->isSMTP(); $mail->Host = 'smtp.hostinger.com'; $mail->SMTPAuth = true; $mail->Username = $EMAIL_ADDRESS; $mail->Password = $SIRO_SMTP_PASSWORD; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; $mail->setFrom($EMAIL_ADDRESS, 'SIRO'); $mail->addAddress($passengerEmail, $passengerName); $mail->isHTML(true); $mail->Subject = 'Your SIRO Trip Details'; $mail->Body = $bodyEmail; $mail->send(); jsonSuccess(null, "Email sent successfully"); } catch (Exception $e) { jsonError("Failed to send email: " . $mail->ErrorInfo); } ```