commit 67af97474cd85b2a407559361bbf76ca3e5f5a86 Author: Hamza-Ayed Date: Tue Apr 28 13:04:27 2026 +0300 Initial commit with updated Auth and media ignored diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d512a54 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +logs/ +*.log +.gemini/ +portrate_captain_image/ diff --git a/Admin/AdminCaptain/add.php b/Admin/AdminCaptain/add.php new file mode 100644 index 0000000..e69de29 diff --git a/Admin/AdminCaptain/delete.php b/Admin/AdminCaptain/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/Admin/AdminCaptain/error_log b/Admin/AdminCaptain/error_log new file mode 100644 index 0000000..e69de29 diff --git a/Admin/AdminCaptain/get.php b/Admin/AdminCaptain/get.php new file mode 100644 index 0000000..73c9b43 --- /dev/null +++ b/Admin/AdminCaptain/get.php @@ -0,0 +1,75 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/AdminCaptain/getCaptainDetailsByEmailOrIDOrPhone.php b/Admin/AdminCaptain/getCaptainDetailsByEmailOrIDOrPhone.php new file mode 100644 index 0000000..5902c44 --- /dev/null +++ b/Admin/AdminCaptain/getCaptainDetailsByEmailOrIDOrPhone.php @@ -0,0 +1,86 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/AdminCaptain/getCaptainDetailsById.php b/Admin/AdminCaptain/getCaptainDetailsById.php new file mode 100644 index 0000000..a9cb985 --- /dev/null +++ b/Admin/AdminCaptain/getCaptainDetailsById.php @@ -0,0 +1,87 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/AdminCaptain/getDriversPhonesAndTokens.php b/Admin/AdminCaptain/getDriversPhonesAndTokens.php new file mode 100755 index 0000000..4743600 --- /dev/null +++ b/Admin/AdminCaptain/getDriversPhonesAndTokens.php @@ -0,0 +1,33 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/AdminCaptain/update.php b/Admin/AdminCaptain/update.php new file mode 100644 index 0000000..e69de29 diff --git a/Admin/AdminRide/get.php b/Admin/AdminRide/get.php new file mode 100644 index 0000000..84b7b6d --- /dev/null +++ b/Admin/AdminRide/get.php @@ -0,0 +1,79 @@ +prepare($sql); +$stmt->execute(); +$result = $stmt->fetchAll(PDO::FETCH_ASSOC); + +if ($stmt->rowCount() > 0) { + jsonSuccess($result); +} else { + jsonError("No records found"); +} +?> \ No newline at end of file diff --git a/Admin/AdminRide/getRidesPerMonth.php b/Admin/AdminRide/getRidesPerMonth.php new file mode 100644 index 0000000..7b8c523 --- /dev/null +++ b/Admin/AdminRide/getRidesPerMonth.php @@ -0,0 +1,52 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/adminUser/add.php b/Admin/adminUser/add.php new file mode 100644 index 0000000..349a03e --- /dev/null +++ b/Admin/adminUser/add.php @@ -0,0 +1,25 @@ +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"); +} +?> diff --git a/Admin/adminUser/add_invoice.php b/Admin/adminUser/add_invoice.php new file mode 100755 index 0000000..d6728a2 --- /dev/null +++ b/Admin/adminUser/add_invoice.php @@ -0,0 +1,75 @@ + '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/intaleq/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" + ]); +} \ No newline at end of file diff --git a/Admin/adminUser/delete.php b/Admin/adminUser/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/Admin/adminUser/error_log b/Admin/adminUser/error_log new file mode 100644 index 0000000..e69de29 diff --git a/Admin/adminUser/get.php b/Admin/adminUser/get.php new file mode 100644 index 0000000..82ff4cb --- /dev/null +++ b/Admin/adminUser/get.php @@ -0,0 +1,24 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/adminUser/invoice_images/INV-20250729-224_123.jpg b/Admin/adminUser/invoice_images/INV-20250729-224_123.jpg new file mode 100644 index 0000000..b4da1a8 Binary files /dev/null and b/Admin/adminUser/invoice_images/INV-20250729-224_123.jpg differ diff --git a/Admin/adminUser/invoice_images/INV-20250729-592_123.jpg b/Admin/adminUser/invoice_images/INV-20250729-592_123.jpg new file mode 100644 index 0000000..b4da1a8 Binary files /dev/null and b/Admin/adminUser/invoice_images/INV-20250729-592_123.jpg differ diff --git a/Admin/adminUser/invoice_images/INV-20250810-859_123.jpg b/Admin/adminUser/invoice_images/INV-20250810-859_123.jpg new file mode 100644 index 0000000..65b3696 Binary files /dev/null and b/Admin/adminUser/invoice_images/INV-20250810-859_123.jpg differ diff --git a/Admin/adminUser/invoice_images/INV-20250812-737_123.jpg b/Admin/adminUser/invoice_images/INV-20250812-737_123.jpg new file mode 100644 index 0000000..ebde934 Binary files /dev/null and b/Admin/adminUser/invoice_images/INV-20250812-737_123.jpg differ diff --git a/Admin/adminUser/invoice_total.php b/Admin/adminUser/invoice_total.php new file mode 100755 index 0000000..b3d464f --- /dev/null +++ b/Admin/adminUser/invoice_total.php @@ -0,0 +1,28 @@ +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() + ]); +} +?> \ No newline at end of file diff --git a/Admin/adminUser/update.php b/Admin/adminUser/update.php new file mode 100644 index 0000000..e69de29 diff --git a/Admin/auth/login.php b/Admin/auth/login.php new file mode 100755 index 0000000..3831646 --- /dev/null +++ b/Admin/auth/login.php @@ -0,0 +1,26 @@ +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("بيانات الدخول غير صحيحة أو غير مسجلة."); +} \ No newline at end of file diff --git a/Admin/auth/send_otp_admin.php b/Admin/auth/send_otp_admin.php new file mode 100755 index 0000000..0bcd15f --- /dev/null +++ b/Admin/auth/send_otp_admin.php @@ -0,0 +1,56 @@ +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 ---"); +?> \ No newline at end of file diff --git a/Admin/auth/verify_otp_admin.php b/Admin/auth/verify_otp_admin.php new file mode 100755 index 0000000..55cee72 --- /dev/null +++ b/Admin/auth/verify_otp_admin.php @@ -0,0 +1,46 @@ +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("رمز التحقق غير صالح أو منتهي."); +} \ No newline at end of file diff --git a/Admin/dashbord.php b/Admin/dashbord.php new file mode 100644 index 0000000..c6a2b27 --- /dev/null +++ b/Admin/dashbord.php @@ -0,0 +1,69 @@ +prepare($sql); +$stmt->execute(); +$result = $stmt->fetchAll(PDO::FETCH_ASSOC); + +if ($result) { + jsonSuccess($result); +} else { + jsonError("No dashboard data found"); +} +?> \ No newline at end of file diff --git a/Admin/driver/deleteCaptain.php b/Admin/driver/deleteCaptain.php new file mode 100755 index 0000000..04ee748 --- /dev/null +++ b/Admin/driver/deleteCaptain.php @@ -0,0 +1,41 @@ +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()); +} \ No newline at end of file diff --git a/Admin/driver/deleteRecord.php b/Admin/driver/deleteRecord.php new file mode 100755 index 0000000..f470ce1 --- /dev/null +++ b/Admin/driver/deleteRecord.php @@ -0,0 +1,30 @@ +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()); +} + +?> \ No newline at end of file diff --git a/Admin/driver/find_driver_by_phone.php b/Admin/driver/find_driver_by_phone.php new file mode 100755 index 0000000..285eb37 --- /dev/null +++ b/Admin/driver/find_driver_by_phone.php @@ -0,0 +1,55 @@ +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()); +} \ No newline at end of file diff --git a/Admin/driver/getBestDriver.php b/Admin/driver/getBestDriver.php new file mode 100755 index 0000000..3aac1ff --- /dev/null +++ b/Admin/driver/getBestDriver.php @@ -0,0 +1,48 @@ + 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"); +} + +?> \ No newline at end of file diff --git a/Admin/driver/getDriverGiftPayment.php b/Admin/driver/getDriverGiftPayment.php new file mode 100755 index 0000000..d33d042 --- /dev/null +++ b/Admin/driver/getDriverGiftPayment.php @@ -0,0 +1,45 @@ +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"); +} + +?> diff --git a/Admin/driver/remove_from_blacklist.php b/Admin/driver/remove_from_blacklist.php new file mode 100755 index 0000000..a4f4a3b --- /dev/null +++ b/Admin/driver/remove_from_blacklist.php @@ -0,0 +1,27 @@ +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()); +} \ No newline at end of file diff --git a/Admin/driver/updateDriverFromAdmin.php b/Admin/driver/updateDriverFromAdmin.php new file mode 100755 index 0000000..d12bf2c --- /dev/null +++ b/Admin/driver/updateDriverFromAdmin.php @@ -0,0 +1,30 @@ +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()); +} +?> \ No newline at end of file diff --git a/Admin/employee/add.php b/Admin/employee/add.php new file mode 100755 index 0000000..81b3ebe --- /dev/null +++ b/Admin/employee/add.php @@ -0,0 +1,31 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/employee/get.php b/Admin/employee/get.php new file mode 100755 index 0000000..0dd72e9 --- /dev/null +++ b/Admin/employee/get.php @@ -0,0 +1,29 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/error/error_list_last20.php b/Admin/error/error_list_last20.php new file mode 100755 index 0000000..2bea5d0 --- /dev/null +++ b/Admin/error/error_list_last20.php @@ -0,0 +1,18 @@ +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"); +} \ No newline at end of file diff --git a/Admin/error/error_search_by_phone.php b/Admin/error/error_search_by_phone.php new file mode 100755 index 0000000..2be4f5e --- /dev/null +++ b/Admin/error/error_search_by_phone.php @@ -0,0 +1,32 @@ +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"); +} \ No newline at end of file diff --git a/Admin/errorApp.php b/Admin/errorApp.php new file mode 100755 index 0000000..04bbf05 --- /dev/null +++ b/Admin/errorApp.php @@ -0,0 +1,40 @@ +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($error); +} else { + // طباعة رسالة فشل + jsonError("Failed to save error data"); +} +?> diff --git a/Admin/error_log b/Admin/error_log new file mode 100644 index 0000000..e69de29 diff --git a/Admin/facebook.php b/Admin/facebook.php new file mode 100755 index 0000000..e1cf1e8 --- /dev/null +++ b/Admin/facebook.php @@ -0,0 +1,37 @@ + $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(); +} \ No newline at end of file diff --git a/Admin/getPassengerDetails.php b/Admin/getPassengerDetails.php new file mode 100644 index 0000000..1cfa740 --- /dev/null +++ b/Admin/getPassengerDetails.php @@ -0,0 +1,100 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/getPassengerDetailsByPassengerID.php b/Admin/getPassengerDetailsByPassengerID.php new file mode 100644 index 0000000..9fe8a38 --- /dev/null +++ b/Admin/getPassengerDetailsByPassengerID.php @@ -0,0 +1,96 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/getPassengerbyEmail.php b/Admin/getPassengerbyEmail.php new file mode 100644 index 0000000..0b31982 --- /dev/null +++ b/Admin/getPassengerbyEmail.php @@ -0,0 +1,91 @@ +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"); +} +?> \ No newline at end of file diff --git a/Admin/getVisaForEachDriver.php b/Admin/getVisaForEachDriver.php new file mode 100644 index 0000000..8325021 --- /dev/null +++ b/Admin/getVisaForEachDriver.php @@ -0,0 +1,48 @@ + 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"); +} +?> \ No newline at end of file diff --git a/Admin/ggg.php b/Admin/ggg.php new file mode 100644 index 0000000..ac80fd1 --- /dev/null +++ b/Admin/ggg.php @@ -0,0 +1,53 @@ + $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); +} \ No newline at end of file diff --git a/Admin/jwtService.php b/Admin/jwtService.php new file mode 100755 index 0000000..16f46d9 --- /dev/null +++ b/Admin/jwtService.php @@ -0,0 +1,77 @@ +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); +} \ No newline at end of file diff --git a/Admin/passenger/admin_delete_and_blacklist_passenger.php b/Admin/passenger/admin_delete_and_blacklist_passenger.php new file mode 100755 index 0000000..c895384 --- /dev/null +++ b/Admin/passenger/admin_delete_and_blacklist_passenger.php @@ -0,0 +1,52 @@ +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()); +} \ No newline at end of file diff --git a/Admin/passenger/admin_unblacklist.php b/Admin/passenger/admin_unblacklist.php new file mode 100755 index 0000000..0710216 --- /dev/null +++ b/Admin/passenger/admin_unblacklist.php @@ -0,0 +1,14 @@ +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"); } \ No newline at end of file diff --git a/Admin/passenger/admin_update_passenger.php b/Admin/passenger/admin_update_passenger.php new file mode 100755 index 0000000..837d56d --- /dev/null +++ b/Admin/passenger/admin_update_passenger.php @@ -0,0 +1,50 @@ +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"); } \ No newline at end of file diff --git a/Admin/rides/admin_get_rides_by_phone.php b/Admin/rides/admin_get_rides_by_phone.php new file mode 100755 index 0000000..af1bee8 --- /dev/null +++ b/Admin/rides/admin_get_rides_by_phone.php @@ -0,0 +1,103 @@ +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()); +} \ No newline at end of file diff --git a/Admin/rides/admin_update_ride_status.php b/Admin/rides/admin_update_ride_status.php new file mode 100755 index 0000000..b49b98c --- /dev/null +++ b/Admin/rides/admin_update_ride_status.php @@ -0,0 +1,87 @@ +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()); +} \ No newline at end of file diff --git a/Admin/rides/get_driver_live_pos.php b/Admin/rides/get_driver_live_pos.php new file mode 100755 index 0000000..dd3ee6a --- /dev/null +++ b/Admin/rides/get_driver_live_pos.php @@ -0,0 +1,50 @@ +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()); +} +?> \ No newline at end of file diff --git a/Admin/rides/get_rides_by_status.php b/Admin/rides/get_rides_by_status.php new file mode 100755 index 0000000..bd6ba25 --- /dev/null +++ b/Admin/rides/get_rides_by_status.php @@ -0,0 +1,108 @@ +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()); +} +?> \ No newline at end of file diff --git a/Admin/rides/monitorRide.php b/Admin/rides/monitorRide.php new file mode 100755 index 0000000..b6900a9 --- /dev/null +++ b/Admin/rides/monitorRide.php @@ -0,0 +1,150 @@ +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); + +?> \ No newline at end of file diff --git a/Admin/sendEmailToDrivertransaction.php b/Admin/sendEmailToDrivertransaction.php new file mode 100644 index 0000000..9d09fbb --- /dev/null +++ b/Admin/sendEmailToDrivertransaction.php @@ -0,0 +1,87 @@ + + + + + +
+ $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."); +} +?> \ No newline at end of file diff --git a/Admin/send_whatsapp_message.php b/Admin/send_whatsapp_message.php new file mode 100755 index 0000000..f2bf31f --- /dev/null +++ b/Admin/send_whatsapp_message.php @@ -0,0 +1,79 @@ + $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); + } +} +?> \ No newline at end of file diff --git a/Admin/view_errors.php b/Admin/view_errors.php new file mode 100755 index 0000000..21bde82 --- /dev/null +++ b/Admin/view_errors.php @@ -0,0 +1,31 @@ +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" => [])); +} + +?> diff --git a/EgyptDocuments/error_log b/EgyptDocuments/error_log new file mode 100644 index 0000000..e69de29 diff --git a/EgyptDocuments/uploadEgyptIdBack.php b/EgyptDocuments/uploadEgyptIdBack.php new file mode 100644 index 0000000..00e5769 --- /dev/null +++ b/EgyptDocuments/uploadEgyptIdBack.php @@ -0,0 +1,60 @@ + "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!')); + +?> diff --git a/EgyptDocuments/uploadEgyptidFront.php b/EgyptDocuments/uploadEgyptidFront.php new file mode 100644 index 0000000..c5f0ecd --- /dev/null +++ b/EgyptDocuments/uploadEgyptidFront.php @@ -0,0 +1,60 @@ + "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!')); + +?> diff --git a/aggregate_files.py b/aggregate_files.py new file mode 100644 index 0000000..a0b6fe7 --- /dev/null +++ b/aggregate_files.py @@ -0,0 +1,40 @@ +import os + +# Configuration +PROJECT_DIR = '.' +OUTPUT_FILE = 'intaleq_v1_secure_latest.md' +EXCLUDED_DIRS = {'.git', 'vendor', 'node_modules', '.gemini'} +EXCLUDED_FILES = {OUTPUT_FILE, 'aggregate_files.py'} + +def aggregate_files(): + with open(OUTPUT_FILE, 'w', encoding='utf-8') as outfile: + outfile.write(f'# Intaleq V1 - Secure Latest Version\n\n') + + for root, dirs, files in os.walk(PROJECT_DIR): + # Prune excluded directories + dirs[:] = [d for d in dirs if d not in EXCLUDED_DIRS] + + for file in files: + if file in EXCLUDED_FILES: + continue + + filepath = os.path.join(root, file) + rel_path = os.path.relpath(filepath, PROJECT_DIR) + + # We mainly want to include code files + if any(file.endswith(ext) for ext in ['.php', '.sql', '.ini', '.json', '.md', '.txt', '.py', '.sh']): + try: + with open(filepath, 'r', encoding='utf-8', errors='ignore') as infile: + content = infile.read() + + outfile.write(f'## File: {rel_path}\n') + outfile.write(f'```\n') + outfile.write(content) + outfile.write(f'\n```\n\n') + print(f"Added: {rel_path}") + except Exception as e: + print(f"Could not read {rel_path}: {e}") + +if __name__ == "__main__": + aggregate_files() + print(f"\nDone! File created: {OUTPUT_FILE}") diff --git a/auth/Tester/error_log b/auth/Tester/error_log new file mode 100644 index 0000000..e69de29 diff --git a/auth/Tester/getTesterApp.php b/auth/Tester/getTesterApp.php new file mode 100644 index 0000000..625f035 --- /dev/null +++ b/auth/Tester/getTesterApp.php @@ -0,0 +1,29 @@ +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"); +} + +?> \ No newline at end of file diff --git a/auth/Tester/updateTesterApp.php b/auth/Tester/updateTesterApp.php new file mode 100644 index 0000000..b7b98c2 --- /dev/null +++ b/auth/Tester/updateTesterApp.php @@ -0,0 +1,23 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/captin/addCriminalDocuments.php b/auth/captin/addCriminalDocuments.php new file mode 100644 index 0000000..819e9eb --- /dev/null +++ b/auth/captin/addCriminalDocuments.php @@ -0,0 +1,35 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/captin/deletecaptainAccounr.php b/auth/captin/deletecaptainAccounr.php new file mode 100644 index 0000000..9ee0d05 --- /dev/null +++ b/auth/captin/deletecaptainAccounr.php @@ -0,0 +1,60 @@ +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()); +} +?> \ No newline at end of file diff --git a/auth/captin/error_log b/auth/captin/error_log new file mode 100644 index 0000000..7e42402 --- /dev/null +++ b/auth/captin/error_log @@ -0,0 +1,15 @@ +[21-May-2025 12:28:44 Europe/Berlin] PHP Fatal error: Uncaught PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'driver.education' in 'field list' in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php:43 +Stack trace: +#0 /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php(43): PDO->prepare('SELECT\n driv...') +#1 {main} + thrown in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php on line 43 +[21-May-2025 21:09:18 Europe/Berlin] PHP Fatal error: Uncaught PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'driver.education' in 'field list' in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php:43 +Stack trace: +#0 /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php(43): PDO->prepare('SELECT\n driv...') +#1 {main} + thrown in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php on line 43 +[22-May-2025 03:30:03 Europe/Berlin] PHP Fatal error: Uncaught PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'driver.education' in 'field list' in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php:43 +Stack trace: +#0 /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php(43): PDO->prepare('SELECT\n driv...') +#1 {main} + thrown in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php on line 43 diff --git a/auth/captin/forgetPassword.php b/auth/captin/forgetPassword.php new file mode 100644 index 0000000..e69de29 diff --git a/auth/captin/getAccount.php b/auth/captin/getAccount.php new file mode 100644 index 0000000..436241c --- /dev/null +++ b/auth/captin/getAccount.php @@ -0,0 +1,24 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/captin/getAllDriverSecure.php b/auth/captin/getAllDriverSecure.php new file mode 100644 index 0000000..f566663 --- /dev/null +++ b/auth/captin/getAllDriverSecure.php @@ -0,0 +1,39 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/captin/getPromptDriverDocumentsEgypt.php b/auth/captin/getPromptDriverDocumentsEgypt.php new file mode 100644 index 0000000..7ea4054 --- /dev/null +++ b/auth/captin/getPromptDriverDocumentsEgypt.php @@ -0,0 +1,23 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/captin/login.php b/auth/captin/login.php new file mode 100644 index 0000000..eb27381 --- /dev/null +++ b/auth/captin/login.php @@ -0,0 +1,66 @@ +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."); +} +?> \ No newline at end of file diff --git a/auth/captin/loginFromGoogle.php b/auth/captin/loginFromGoogle.php new file mode 100755 index 0000000..de3d1b8 --- /dev/null +++ b/auth/captin/loginFromGoogle.php @@ -0,0 +1,111 @@ +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; +} +?> \ No newline at end of file diff --git a/auth/captin/loginUsingCredentialsWithoutGoogle.php b/auth/captin/loginUsingCredentialsWithoutGoogle.php new file mode 100755 index 0000000..68e22f6 --- /dev/null +++ b/auth/captin/loginUsingCredentialsWithoutGoogle.php @@ -0,0 +1,77 @@ +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(); +?> \ No newline at end of file diff --git a/auth/captin/register.php b/auth/captin/register.php new file mode 100755 index 0000000..bf67bcc --- /dev/null +++ b/auth/captin/register.php @@ -0,0 +1,132 @@ +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."); +} +?> \ No newline at end of file diff --git a/auth/captin/removeAccount.php b/auth/captin/removeAccount.php new file mode 100644 index 0000000..e23b2ca --- /dev/null +++ b/auth/captin/removeAccount.php @@ -0,0 +1,16 @@ +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."); +} +?> \ No newline at end of file diff --git a/auth/captin/sendOtpMessageDriver.php b/auth/captin/sendOtpMessageDriver.php new file mode 100755 index 0000000..f73dabf --- /dev/null +++ b/auth/captin/sendOtpMessageDriver.php @@ -0,0 +1,130 @@ +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; +} +?> \ No newline at end of file diff --git a/auth/captin/updateAccountBank.php b/auth/captin/updateAccountBank.php new file mode 100644 index 0000000..139ced3 --- /dev/null +++ b/auth/captin/updateAccountBank.php @@ -0,0 +1,44 @@ + $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"); +} +?> \ No newline at end of file diff --git a/auth/captin/updateDriverClaim.php b/auth/captin/updateDriverClaim.php new file mode 100755 index 0000000..b1c1a89 --- /dev/null +++ b/auth/captin/updateDriverClaim.php @@ -0,0 +1,38 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/captin/updateDriverSecure.php b/auth/captin/updateDriverSecure.php new file mode 100644 index 0000000..0597d86 --- /dev/null +++ b/auth/captin/updateDriverSecure.php @@ -0,0 +1,56 @@ +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()); +} +?> \ No newline at end of file diff --git a/auth/captin/updateShamCashDriver.php b/auth/captin/updateShamCashDriver.php new file mode 100755 index 0000000..b8af407 --- /dev/null +++ b/auth/captin/updateShamCashDriver.php @@ -0,0 +1,39 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/captin/verifyEmail.php b/auth/captin/verifyEmail.php new file mode 100644 index 0000000..e69de29 diff --git a/auth/captin/verifyOtpDriver.php b/auth/captin/verifyOtpDriver.php new file mode 100755 index 0000000..0d6ba7b --- /dev/null +++ b/auth/captin/verifyOtpDriver.php @@ -0,0 +1,39 @@ +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."); +} +?> \ No newline at end of file diff --git a/auth/checkPhoneNumberISVerfiedDriver.php b/auth/checkPhoneNumberISVerfiedDriver.php new file mode 100644 index 0000000..cb098c9 --- /dev/null +++ b/auth/checkPhoneNumberISVerfiedDriver.php @@ -0,0 +1,21 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/checkPhoneNumberISVerfiedPassenger.php b/auth/checkPhoneNumberISVerfiedPassenger.php new file mode 100755 index 0000000..8e6ba47 --- /dev/null +++ b/auth/checkPhoneNumberISVerfiedPassenger.php @@ -0,0 +1,39 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/cnMap.php b/auth/cnMap.php new file mode 100644 index 0000000..68f4df5 --- /dev/null +++ b/auth/cnMap.php @@ -0,0 +1,23 @@ + "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; +?> diff --git a/auth/cn_map.json b/auth/cn_map.json new file mode 100644 index 0000000..c398c06 --- /dev/null +++ b/auth/cn_map.json @@ -0,0 +1 @@ +["3","7","1","9","0","5","2","6","4","8"] \ No newline at end of file diff --git a/auth/document_syria/ai_document.php b/auth/document_syria/ai_document.php new file mode 100755 index 0000000..2917c03 --- /dev/null +++ b/auth/document_syria/ai_document.php @@ -0,0 +1,245 @@ + '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 +]); \ No newline at end of file diff --git a/auth/document_syria/uploadDocSyria.php b/auth/document_syria/uploadDocSyria.php new file mode 100755 index 0000000..6acb2d4 --- /dev/null +++ b/auth/document_syria/uploadDocSyria.php @@ -0,0 +1,97 @@ +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 = "/intaleq/auth/uploads/documents/" . $uniqueName; +$imageUrl = rtrim(BASE_URL, '/') . $publicPath; + +// ✅ نتيجة نهائية: فقط رابط الصورة وبعض البيانات المفيدة +printSuccess([ + $imageUrl, + +]); \ No newline at end of file diff --git a/auth/error_log b/auth/error_log new file mode 100644 index 0000000..e69de29 diff --git a/auth/google_auth/callback.php b/auth/google_auth/callback.php new file mode 100755 index 0000000..70e7e53 --- /dev/null +++ b/auth/google_auth/callback.php @@ -0,0 +1,64 @@ + $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(); +?> \ No newline at end of file diff --git a/auth/google_auth/check_status.php b/auth/google_auth/check_status.php new file mode 100755 index 0000000..26d2649 --- /dev/null +++ b/auth/google_auth/check_status.php @@ -0,0 +1,38 @@ + '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(); +?> diff --git a/auth/google_auth/google_auth.php b/auth/google_auth/google_auth.php new file mode 100755 index 0000000..4e9362b --- /dev/null +++ b/auth/google_auth/google_auth.php @@ -0,0 +1,55 @@ + 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); \ No newline at end of file diff --git a/auth/google_auth/login.php b/auth/google_auth/login.php new file mode 100755 index 0000000..4842a1f --- /dev/null +++ b/auth/google_auth/login.php @@ -0,0 +1,41 @@ + '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(); +?> \ No newline at end of file diff --git a/auth/login.php b/auth/login.php new file mode 100644 index 0000000..0313d08 --- /dev/null +++ b/auth/login.php @@ -0,0 +1,67 @@ +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(); + +?> diff --git a/auth/loginFromGooglePassenger.php b/auth/loginFromGooglePassenger.php new file mode 100755 index 0000000..9126df8 --- /dev/null +++ b/auth/loginFromGooglePassenger.php @@ -0,0 +1,104 @@ +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, + t.token AS fcm_token, + t.fingerPrint AS fcm_fingerprint +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 +LEFT JOIN tokens t + ON t.passengerID = p.id +WHERE p.email = :email AND p.id = :id AND phone_verification_passenger.verified = '1' +LIMIT 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']); + + // فك تشفير توكن FCM إذا وجد + if (!empty($row['fcm_token'])) { + $row['fcm_token'] = $encryptionHelper->decryptData($row['fcm_token']); + } + } + + 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(); \ No newline at end of file diff --git a/auth/otpmessage.php b/auth/otpmessage.php new file mode 100755 index 0000000..9cef175 --- /dev/null +++ b/auth/otpmessage.php @@ -0,0 +1,88 @@ + $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; +} +?> \ No newline at end of file diff --git a/auth/packageInfo.php b/auth/packageInfo.php new file mode 100644 index 0000000..18e7cce --- /dev/null +++ b/auth/packageInfo.php @@ -0,0 +1,30 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/passengerOTP/error_log b/auth/passengerOTP/error_log new file mode 100644 index 0000000..e69de29 diff --git a/auth/passengerOTP/sendOtpPassenger.php b/auth/passengerOTP/sendOtpPassenger.php new file mode 100644 index 0000000..fe74e40 --- /dev/null +++ b/auth/passengerOTP/sendOtpPassenger.php @@ -0,0 +1,42 @@ +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"); + } +} +?> \ No newline at end of file diff --git a/auth/passengerOTP/verifyOtpPassenger.php b/auth/passengerOTP/verifyOtpPassenger.php new file mode 100644 index 0000000..12d953b --- /dev/null +++ b/auth/passengerOTP/verifyOtpPassenger.php @@ -0,0 +1,28 @@ +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."); +} +?> \ No newline at end of file diff --git a/auth/passengerRemovedAccountEmail.php b/auth/passengerRemovedAccountEmail.php new file mode 100644 index 0000000..e3e5b14 --- /dev/null +++ b/auth/passengerRemovedAccountEmail.php @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/auth/resetPassword.php b/auth/resetPassword.php new file mode 100644 index 0000000..e69de29 diff --git a/auth/sendEmail.php b/auth/sendEmail.php new file mode 100755 index 0000000..e18e13f --- /dev/null +++ b/auth/sendEmail.php @@ -0,0 +1,34 @@ + + +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); \ No newline at end of file diff --git a/auth/sendVerifyEmail.php b/auth/sendVerifyEmail.php new file mode 100644 index 0000000..d37aae3 --- /dev/null +++ b/auth/sendVerifyEmail.php @@ -0,0 +1,72 @@ +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"); + } +} +?> + diff --git a/auth/signup.php b/auth/signup.php new file mode 100644 index 0000000..f4bffdc --- /dev/null +++ b/auth/signup.php @@ -0,0 +1,70 @@ +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."); +} +?> \ No newline at end of file diff --git a/auth/sms/error_log b/auth/sms/error_log new file mode 100644 index 0000000..e69de29 diff --git a/auth/sms/getSender.php b/auth/sms/getSender.php new file mode 100644 index 0000000..70b0817 --- /dev/null +++ b/auth/sms/getSender.php @@ -0,0 +1,28 @@ +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"); +} + +?> \ No newline at end of file diff --git a/auth/sms/sms_to_user_change_fingerprint.php b/auth/sms/sms_to_user_change_fingerprint.php new file mode 100644 index 0000000..b6b9504 --- /dev/null +++ b/auth/sms/sms_to_user_change_fingerprint.php @@ -0,0 +1,68 @@ +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"]); +?> \ No newline at end of file diff --git a/auth/sms/updatePhoneInvalidSMS.php b/auth/sms/updatePhoneInvalidSMS.php new file mode 100644 index 0000000..f4c3272 --- /dev/null +++ b/auth/sms/updatePhoneInvalidSMS.php @@ -0,0 +1,27 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/sms/updatePhoneInvalidSMSPassenger.php b/auth/sms/updatePhoneInvalidSMSPassenger.php new file mode 100644 index 0000000..a0c9aba --- /dev/null +++ b/auth/sms/updatePhoneInvalidSMSPassenger.php @@ -0,0 +1,23 @@ +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"); +} +?> \ No newline at end of file diff --git a/auth/sms_new_backend/error_log b/auth/sms_new_backend/error_log new file mode 100644 index 0000000..e69de29 diff --git a/auth/sms_new_backend/rasel_whatsapp.php b/auth/sms_new_backend/rasel_whatsapp.php new file mode 100755 index 0000000..fff7c2e --- /dev/null +++ b/auth/sms_new_backend/rasel_whatsapp.php @@ -0,0 +1,134 @@ + $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) + + +?> diff --git a/auth/sms_new_backend/sendOtpPassenger.php b/auth/sms_new_backend/sendOtpPassenger.php new file mode 100644 index 0000000..0322efa --- /dev/null +++ b/auth/sms_new_backend/sendOtpPassenger.php @@ -0,0 +1,97 @@ +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); +} + +?> \ No newline at end of file diff --git a/auth/syria/auth_proxy.php b/auth/syria/auth_proxy.php new file mode 100755 index 0000000..beb4ac0 --- /dev/null +++ b/auth/syria/auth_proxy.php @@ -0,0 +1,75 @@ +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(); +} +?> diff --git a/auth/syria/delete_old_images.php b/auth/syria/delete_old_images.php new file mode 100755 index 0000000..ebca543 --- /dev/null +++ b/auth/syria/delete_old_images.php @@ -0,0 +1,85 @@ +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); \ No newline at end of file diff --git a/auth/syria/driver/driver_details.php b/auth/syria/driver/driver_details.php new file mode 100755 index 0000000..d68f49b --- /dev/null +++ b/auth/syria/driver/driver_details.php @@ -0,0 +1,49 @@ +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()); +} \ No newline at end of file diff --git a/auth/syria/driver/drivers_pending_list.php b/auth/syria/driver/drivers_pending_list.php new file mode 100755 index 0000000..4fa81ea --- /dev/null +++ b/auth/syria/driver/drivers_pending_list.php @@ -0,0 +1,20 @@ + '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()); +} \ No newline at end of file diff --git a/auth/syria/driver/isPhoneVerified.php b/auth/syria/driver/isPhoneVerified.php new file mode 100755 index 0000000..5f94a3d --- /dev/null +++ b/auth/syria/driver/isPhoneVerified.php @@ -0,0 +1,26 @@ +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()); +} \ No newline at end of file diff --git a/auth/syria/driver/register_driver_and_car.php b/auth/syria/driver/register_driver_and_car.php new file mode 100755 index 0000000..ccdc85d --- /dev/null +++ b/auth/syria/driver/register_driver_and_car.php @@ -0,0 +1,391 @@ + 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/intaleq/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."); +} +?> \ No newline at end of file diff --git a/auth/syria/driver/register_driver_and_car_signed.php b/auth/syria/driver/register_driver_and_car_signed.php new file mode 100755 index 0000000..e715879 --- /dev/null +++ b/auth/syria/driver/register_driver_and_car_signed.php @@ -0,0 +1,303 @@ +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."); +} \ No newline at end of file diff --git a/auth/syria/driver/sendWhatsAppDriver.php b/auth/syria/driver/sendWhatsAppDriver.php new file mode 100755 index 0000000..e26145b --- /dev/null +++ b/auth/syria/driver/sendWhatsAppDriver.php @@ -0,0 +1,69 @@ +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 Intaleq 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'); +} +?> diff --git a/auth/syria/driver/verifyOtp.php b/auth/syria/driver/verifyOtp.php new file mode 100755 index 0000000..acb2834 --- /dev/null +++ b/auth/syria/driver/verifyOtp.php @@ -0,0 +1,69 @@ +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()); +} +?> diff --git a/auth/syria/register_passenger.php b/auth/syria/register_passenger.php new file mode 100755 index 0000000..addd06f --- /dev/null +++ b/auth/syria/register_passenger.php @@ -0,0 +1,155 @@ +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."); +} +?> \ No newline at end of file diff --git a/auth/syria/secure_image.php b/auth/syria/secure_image.php new file mode 100755 index 0000000..9683ff7 --- /dev/null +++ b/auth/syria/secure_image.php @@ -0,0 +1,72 @@ +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); \ No newline at end of file diff --git a/auth/syria/sendWhatsOpt.php b/auth/syria/sendWhatsOpt.php new file mode 100755 index 0000000..1e2ff28 --- /dev/null +++ b/auth/syria/sendWhatsOpt.php @@ -0,0 +1,197 @@ +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 Intaleq 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 Intaleq 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); +} +*/ diff --git a/auth/syria/send_survey.php b/auth/syria/send_survey.php new file mode 100755 index 0000000..6d088da --- /dev/null +++ b/auth/syria/send_survey.php @@ -0,0 +1,52 @@ + "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("فشل في إرسال استطلاع الرأي"); +} +?> \ No newline at end of file diff --git a/auth/syria/uploadSyrianDocs.php b/auth/syria/uploadSyrianDocs.php new file mode 100755 index 0000000..d5e69ff --- /dev/null +++ b/auth/syria/uploadSyrianDocs.php @@ -0,0 +1,129 @@ + 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) +]); \ No newline at end of file diff --git a/auth/syria/verifyOtp.php b/auth/syria/verifyOtp.php new file mode 100755 index 0000000..0e71039 --- /dev/null +++ b/auth/syria/verifyOtp.php @@ -0,0 +1,93 @@ +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."); + +?> \ No newline at end of file diff --git a/auth/token_passenger/driver/send_otp_driver.php b/auth/token_passenger/driver/send_otp_driver.php new file mode 100755 index 0000000..6eb0c1f --- /dev/null +++ b/auth/token_passenger/driver/send_otp_driver.php @@ -0,0 +1,67 @@ + 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) { /* … */ } +?> \ No newline at end of file diff --git a/auth/token_passenger/driver/verify_otp_driver.php b/auth/token_passenger/driver/verify_otp_driver.php new file mode 100755 index 0000000..ce04e98 --- /dev/null +++ b/auth/token_passenger/driver/verify_otp_driver.php @@ -0,0 +1,81 @@ +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."); +} \ No newline at end of file diff --git a/auth/token_passenger/send_otp.php b/auth/token_passenger/send_otp.php new file mode 100755 index 0000000..3d596e9 --- /dev/null +++ b/auth/token_passenger/send_otp.php @@ -0,0 +1,65 @@ + 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) { /* … (أبقِها أو احذفها) */ } +?> \ No newline at end of file diff --git a/auth/token_passenger/verify_otp.php b/auth/token_passenger/verify_otp.php new file mode 100755 index 0000000..cdc13db --- /dev/null +++ b/auth/token_passenger/verify_otp.php @@ -0,0 +1,80 @@ +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()); +} +?> \ No newline at end of file diff --git a/auth/uploads/documents/driver_driving_license_sy_back_34feffd3fa72d6bee56b.jpg b/auth/uploads/documents/driver_driving_license_sy_back_34feffd3fa72d6bee56b.jpg new file mode 100644 index 0000000..8f2d858 Binary files /dev/null and b/auth/uploads/documents/driver_driving_license_sy_back_34feffd3fa72d6bee56b.jpg differ diff --git a/auth/uploads/documents/driver_driving_license_sy_back_eddfdfdgfd.jpg b/auth/uploads/documents/driver_driving_license_sy_back_eddfdfdgfd.jpg new file mode 100644 index 0000000..612d377 Binary files /dev/null and b/auth/uploads/documents/driver_driving_license_sy_back_eddfdfdgfd.jpg differ diff --git a/auth/uploads/documents/driver_driving_license_sy_front_34feffd3fa72d6bee56b.jpg b/auth/uploads/documents/driver_driving_license_sy_front_34feffd3fa72d6bee56b.jpg new file mode 100644 index 0000000..9ceab20 Binary files /dev/null and b/auth/uploads/documents/driver_driving_license_sy_front_34feffd3fa72d6bee56b.jpg differ diff --git a/auth/uploads/documents/driver_driving_license_sy_front_eddfdfdgfd.jpg b/auth/uploads/documents/driver_driving_license_sy_front_eddfdfdgfd.jpg new file mode 100644 index 0000000..f5f1309 Binary files /dev/null and b/auth/uploads/documents/driver_driving_license_sy_front_eddfdfdgfd.jpg differ diff --git a/auth/uploads/documents/driver_generic_unknown.jpg b/auth/uploads/documents/driver_generic_unknown.jpg new file mode 100644 index 0000000..d291986 Binary files /dev/null and b/auth/uploads/documents/driver_generic_unknown.jpg differ diff --git a/auth/uploads/documents/driver_id_back_sy_34feffd3fa72d6bee56b.jpg b/auth/uploads/documents/driver_id_back_sy_34feffd3fa72d6bee56b.jpg new file mode 100644 index 0000000..39c2dc1 Binary files /dev/null and b/auth/uploads/documents/driver_id_back_sy_34feffd3fa72d6bee56b.jpg differ diff --git a/auth/uploads/documents/driver_id_back_sy_eddfdfdgfd.jpg b/auth/uploads/documents/driver_id_back_sy_eddfdfdgfd.jpg new file mode 100644 index 0000000..bbf2889 Binary files /dev/null and b/auth/uploads/documents/driver_id_back_sy_eddfdfdgfd.jpg differ diff --git a/auth/uploads/documents/driver_id_front_sy_34feffd3fa72d6bee56b.jpg b/auth/uploads/documents/driver_id_front_sy_34feffd3fa72d6bee56b.jpg new file mode 100644 index 0000000..7ad8146 Binary files /dev/null and b/auth/uploads/documents/driver_id_front_sy_34feffd3fa72d6bee56b.jpg differ diff --git a/auth/uploads/documents/driver_id_front_sy_eddfdfdgfd.jpg b/auth/uploads/documents/driver_id_front_sy_eddfdfdgfd.jpg new file mode 100644 index 0000000..4139987 Binary files /dev/null and b/auth/uploads/documents/driver_id_front_sy_eddfdfdgfd.jpg differ diff --git a/auth/uploads/documents/driver_vehicle_license_sy_back_34feffd3fa72d6bee56b.jpg b/auth/uploads/documents/driver_vehicle_license_sy_back_34feffd3fa72d6bee56b.jpg new file mode 100644 index 0000000..02749ec Binary files /dev/null and b/auth/uploads/documents/driver_vehicle_license_sy_back_34feffd3fa72d6bee56b.jpg differ diff --git a/auth/uploads/documents/driver_vehicle_license_sy_back_eddfdfdgfd.jpg b/auth/uploads/documents/driver_vehicle_license_sy_back_eddfdfdgfd.jpg new file mode 100644 index 0000000..02749ec Binary files /dev/null and b/auth/uploads/documents/driver_vehicle_license_sy_back_eddfdfdgfd.jpg differ diff --git a/auth/uploads/documents/driver_vehicle_license_sy_front_34feffd3fa72d6bee56b.jpg b/auth/uploads/documents/driver_vehicle_license_sy_front_34feffd3fa72d6bee56b.jpg new file mode 100644 index 0000000..cacd260 Binary files /dev/null and b/auth/uploads/documents/driver_vehicle_license_sy_front_34feffd3fa72d6bee56b.jpg differ diff --git a/auth/uploads/documents/driver_vehicle_license_sy_front_eddfdfdgfd.jpg b/auth/uploads/documents/driver_vehicle_license_sy_front_eddfdfdgfd.jpg new file mode 100644 index 0000000..06f9fe0 Binary files /dev/null and b/auth/uploads/documents/driver_vehicle_license_sy_front_eddfdfdgfd.jpg differ diff --git a/auth/verifyEmail.php b/auth/verifyEmail.php new file mode 100644 index 0000000..0248688 --- /dev/null +++ b/auth/verifyEmail.php @@ -0,0 +1,39 @@ +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."); +} +?> \ No newline at end of file diff --git a/auth/verifyOtpMessage.php b/auth/verifyOtpMessage.php new file mode 100755 index 0000000..267de68 --- /dev/null +++ b/auth/verifyOtpMessage.php @@ -0,0 +1,60 @@ +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."); +} +?> \ No newline at end of file diff --git a/card_image/criminalRecord-1b73bad5ed4f147d688e.jpg b/card_image/criminalRecord-1b73bad5ed4f147d688e.jpg new file mode 100644 index 0000000..ffaa58c Binary files /dev/null and b/card_image/criminalRecord-1b73bad5ed4f147d688e.jpg differ diff --git a/card_image/idFrontEmployee-795C0P4Z.jpg b/card_image/idFrontEmployee-795C0P4Z.jpg new file mode 100644 index 0000000..f571f5d Binary files /dev/null and b/card_image/idFrontEmployee-795C0P4Z.jpg differ diff --git a/card_image/idFrontEmployee-AYZHXEIE.jpg b/card_image/idFrontEmployee-AYZHXEIE.jpg new file mode 100644 index 0000000..156b1af Binary files /dev/null and b/card_image/idFrontEmployee-AYZHXEIE.jpg differ diff --git a/card_image/idbackEmployee-795C0P4Z.jpg b/card_image/idbackEmployee-795C0P4Z.jpg new file mode 100644 index 0000000..1f660b7 Binary files /dev/null and b/card_image/idbackEmployee-795C0P4Z.jpg differ diff --git a/card_image/idbackEmployee-AYZHXEIE.jpg b/card_image/idbackEmployee-AYZHXEIE.jpg new file mode 100644 index 0000000..9000963 Binary files /dev/null and b/card_image/idbackEmployee-AYZHXEIE.jpg differ diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..d7c6bb7 --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "vlucas/phpdotenv": "^5.6" + } +} diff --git a/composer.lock b/composer.lock new file mode 100755 index 0000000..0b8b027 --- /dev/null +++ b/composer.lock @@ -0,0 +1,479 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "108be68e4e2b97fed51d36a10eed0849", + "packages": [ + { + "name": "graham-campbell/result-type", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:16:48+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.2", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2023-11-12T21:59:55+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.2", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:43:29+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/connect.php b/connect.php new file mode 100755 index 0000000..ad702f6 --- /dev/null +++ b/connect.php @@ -0,0 +1,28 @@ +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'])); +} \ No newline at end of file diff --git a/core/Auth/JwtService.php b/core/Auth/JwtService.php new file mode 100644 index 0000000..e346e74 --- /dev/null +++ b/core/Auth/JwtService.php @@ -0,0 +1,239 @@ +secretKey = trim(file_get_contents('/home/intaleq-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)); + + $ttl = 3600; + if ($role === 'driver') { + $ttl = 14400; + } elseif ($role === 'passenger') { + $ttl = 3600; + } + + $payload = [ + 'iss' => $this->issuer, + 'aud' => $audience, + 'user_id' => $userId, + 'role' => $role, + 'token_type' => 'access', + 'jti' => $jti, + 'iat' => time(), + 'exp' => time() + $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) { + // محاولة فك التشفير بمفتاح المحفظة (Wallet secret fallback) + $payKeyPath = '/home/intaleq-api/.secret_key_pay'; + $payKey = file_exists($payKeyPath) ? trim(file_get_contents($payKeyPath)) : ''; + + if ($payKey) { + try { + $decoded = JWT::decode($token, new Key($payKey, self::ALGO)); + } catch (Exception $e2) { + self::abort(401, 'Invalid token signature'); + } + } else { + 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/intaleq-api/.internal_socket_key'; + $sent = $_SERVER['HTTP_X_INTERNAL_KEY'] ?? ''; + $expected = (file_exists($keyPath) ? trim(file_get_contents($keyPath)) : '') ?: 'Intaleq_Secure_Bridge_Key_2026_@!socket'; + + 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; + } +} diff --git a/core/Auth/RateLimiter.php b/core/Auth/RateLimiter.php new file mode 100644 index 0000000..2f85022 --- /dev/null +++ b/core/Auth/RateLimiter.php @@ -0,0 +1,82 @@ + ['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}"); + } + } +} diff --git a/core/Database/Database.php b/core/Database/Database.php new file mode 100644 index 0000000..b40b25e --- /dev/null +++ b/core/Database/Database.php @@ -0,0 +1,79 @@ + [ + 'name' => 'DB_PRIMARY_NAME_V2', + 'host' => 'DB_PRIMARY_HOST_V2', + 'user' => 'DB_PRIMARY_USER_V2', + 'pass' => 'DB_PRIMARY_PASS_V2', + ], + 'tracking' => [ + 'name' => 'dbname_track', + 'host' => 'DB_TRACKING_HOST', + 'user' => 'DB_TRACKING_USER', + 'pass' => 'DB_TRACKING_PASS', + ], + 'ride' => [ + 'name' => 'dbname_ride', + 'host' => 'DB_RIDE_HOST', + 'user' => 'DB_RIDE_USER', + 'pass' => 'DB_RIDE_PASS', + ], + ]; + + 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"); + } + + $cfg = self::$map[$name]; + + $dbname = getenv($cfg['name']); + $host = getenv($cfg['host']) ?: 'localhost'; + $user = getenv($cfg['user']); + $pass = getenv($cfg['pass']); + + if (!$dbname || !$user) { + error_log("[FATAL] Database config missing for: $name (Check ENV keys: {$cfg['name']}, {$cfg['user']})"); + throw new RuntimeException("Database configuration error."); + } + + $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, + 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) at $host: " . $e->getMessage()); + throw $e; + } + } + + private function __construct() {} + private function __clone() {} +} diff --git a/core/Security/EncryptionHelper.php b/core/Security/EncryptionHelper.php new file mode 100644 index 0000000..a9c406a --- /dev/null +++ b/core/Security/EncryptionHelper.php @@ -0,0 +1,88 @@ +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); + } +} diff --git a/core/Services/FcmService.php b/core/Services/FcmService.php new file mode 100644 index 0000000..5e799c8 --- /dev/null +++ b/core/Services/FcmService.php @@ -0,0 +1,156 @@ +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; + } +} diff --git a/core/Services/OtpService.php b/core/Services/OtpService.php new file mode 100644 index 0000000..0a8104b --- /dev/null +++ b/core/Services/OtpService.php @@ -0,0 +1,77 @@ +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}"); + } +} diff --git a/core/bootstrap.php b/core/bootstrap.php new file mode 100644 index 0000000..d3aaec9 --- /dev/null +++ b/core/bootstrap.php @@ -0,0 +1,90 @@ +connect($redisHost, $redisPort, 1.5)) { + if ($redisPass) $redis->auth($redisPass); + $redis->setOption(Redis::OPT_PREFIX, 'intaleq:'); + } 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 العام (للتوافقية) +// يتم استخدام .enckey (32 بايت) لتشفير البيانات +$encKey = trim(@file_get_contents('/home/intaleq-api/.enckey') ?: ''); +if (!$encKey) { + $encKey = getenv('ENC_KEY') ?: ''; +} + +if (!$encKey || strlen($encKey) !== 32) { + error_log("[FATAL] Encryption key (.enckey) is missing or invalid length (must be 32 bytes)."); + http_response_code(500); + exit(json_encode(['error' => 'Server configuration error: Encryption key issue'])); +} + +$encryptionHelper = new EncryptionHelper($encKey); diff --git a/core/helpers.php b/core/helpers.php new file mode 100644 index 0000000..25ffa1c --- /dev/null +++ b/core/helpers.php @@ -0,0 +1,178 @@ + 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); + // توحيد الأسلوب ليكون متوافقاً مع الكود القديم (وضع البيانات في message) + $payload = ($data !== null && (!empty($data) || is_array($data))) ? $data : $message; + echo json_encode(['status' => 'success', 'message' => $payload], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + exit; +} + +function jsonError(string $message, int $code = 400, mixed $extra = null): never +{ + http_response_code($code); + $response = ['status' => 'failure', 'message' => $message]; + if ($extra !== null) $response['details'] = $extra; + echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + exit; +} + +// (للتوافق مع الكود القديم) +function printSuccess(mixed $message = 'success'): void +{ + echo json_encode(['status' => 'success', 'message' => $message], JSON_UNESCAPED_UNICODE); +} +function printFailure(mixed $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 +{ + $logDir = __DIR__ . '/../logs'; + if (!is_dir($logDir)) { + @mkdir($logDir, 0777, true); + } + $entry = date('Y-m-d H:i:s') . ' [SECURITY] ' . $message; + if ($context) $entry .= ' | ' . json_encode($context, JSON_UNESCAPED_UNICODE); + @error_log($entry . PHP_EOL, 3, $logDir . '/security.log'); +} + +function appLog(string $message, string $level = 'INFO'): void +{ + $logDir = __DIR__ . '/../logs'; + if (!is_dir($logDir)) { + @mkdir($logDir, 0777, true); + } + $entry = date('Y-m-d H:i:s') . " [$level] " . $message; + @error_log($entry . PHP_EOL, 3, $logDir . '/app.log'); +} + +function debugLog(string $message): void +{ + appLog($message, 'DEBUG'); +} diff --git a/driver_assurance/add.php b/driver_assurance/add.php new file mode 100755 index 0000000..9ea8363 --- /dev/null +++ b/driver_assurance/add.php @@ -0,0 +1,35 @@ +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"); +} +?> \ No newline at end of file diff --git a/driver_assurance/get.php b/driver_assurance/get.php new file mode 100755 index 0000000..e69de29 diff --git a/driver_assurance/update.php b/driver_assurance/update.php new file mode 100755 index 0000000..e69de29 diff --git a/email/sendTripEmail.php b/email/sendTripEmail.php new file mode 100755 index 0000000..eb9adc7 --- /dev/null +++ b/email/sendTripEmail.php @@ -0,0 +1,119 @@ +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"); +} + +$INTALEQ_SMTP_PASSWORD = getenv('INTALEQ_SMTP_PASSWORD'); + +// بناء محتوى الإيميل بتصميم عصري وبريميوم +$bodyEmail = " + + + + + + + +
+
+

INTALEQ

+

Your journey, our priority

+
+
+
Hello, $passengerName!
+

Thank you for choosing INTALEQ. 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 = $INTALEQ_SMTP_PASSWORD; + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + $mail->Port = 587; + + $mail->setFrom($EMAIL_ADDRESS, 'INTALEQ'); + $mail->addAddress($passengerEmail, $passengerName); + $mail->isHTML(true); + $mail->Subject = 'Your INTALEQ Trip Details'; + $mail->Body = $bodyEmail; + + $mail->send(); + jsonSuccess(null, "Email sent successfully"); +} catch (Exception $e) { + jsonError("Failed to send email: " . $mail->ErrorInfo); +} \ No newline at end of file diff --git a/encrypt_decrypt.php b/encrypt_decrypt.php new file mode 100755 index 0000000..80187fd --- /dev/null +++ b/encrypt_decrypt.php @@ -0,0 +1,108 @@ +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; +} + +?> \ No newline at end of file diff --git a/functions.php b/functions.php new file mode 100755 index 0000000..55a6a91 --- /dev/null +++ b/functions.php @@ -0,0 +1,462 @@ + $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/intaleq-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/intaleq-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/intaleq-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/intaleq-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/intaleq-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']; +} + + + + +function authenticateJWT(): object +{ + global $redis; + if (!class_exists('JwtService')) { + require_once __DIR__ . '/core/Auth/JwtService.php'; + } + $jwtService = new JwtService($redis ?? null); + return $jwtService->authenticate(); +} +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); +} + + + + + + +function sendFCM_Internal( + $target, + $title, + $body, + $customData = [], + $category = 'Order', + $isTopic = false, + $tone = 'order' +) { + global $redis; + if (!class_exists('FcmService')) { + require_once __DIR__ . '/core/Services/FcmService.php'; + } + $fcm = new FcmService($redis ?? null); + + return $fcm->send($target, $title, $body, is_array($customData) ? $customData : [], $category, $tone); +} + + + + diff --git a/get_connect.php b/get_connect.php new file mode 100644 index 0000000..43b5f2b --- /dev/null +++ b/get_connect.php @@ -0,0 +1,22 @@ +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'])); +} diff --git a/imageForUsingApp/order_page.jpg b/imageForUsingApp/order_page.jpg new file mode 100644 index 0000000..c8c6a3d Binary files /dev/null and b/imageForUsingApp/order_page.jpg differ diff --git a/instructions_web/animation.mp4 b/instructions_web/animation.mp4 new file mode 100644 index 0000000..3db5d2a Binary files /dev/null and b/instructions_web/animation.mp4 differ diff --git a/instructions_web/delete_account.html b/instructions_web/delete_account.html new file mode 100644 index 0000000..e999ef6 --- /dev/null +++ b/instructions_web/delete_account.html @@ -0,0 +1,67 @@ + + + + + Delete Account + + + + + + App logo + +

Delete Account

+ + + +

To delete your account, please open the app and go to the Profile page. Then, tap on + the "Delete My Account" button and follow the instructions.

+ + +

+ © + All rights reserved by SEFER +

+ + + + + \ No newline at end of file diff --git a/instructions_web/logo.gif b/instructions_web/logo.gif new file mode 100644 index 0000000..4dd5d9c Binary files /dev/null and b/instructions_web/logo.gif differ diff --git a/instructions_web/logo.png b/instructions_web/logo.png new file mode 100644 index 0000000..3e0026b Binary files /dev/null and b/instructions_web/logo.png differ diff --git a/intaleq_v1.code-workspace b/intaleq_v1.code-workspace new file mode 100644 index 0000000..1a1c607 --- /dev/null +++ b/intaleq_v1.code-workspace @@ -0,0 +1,14 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "../../../development/App/Intaleq" + }, + { + "path": "../../../development/App/intaleq_driver" + } + ], + "settings": {} +} \ No newline at end of file diff --git a/intaleq_v1_secure_latest.md b/intaleq_v1_secure_latest.md new file mode 100644 index 0000000..908030c --- /dev/null +++ b/intaleq_v1_secure_latest.md @@ -0,0 +1,33608 @@ +# Intaleq 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/intaleq-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/intaleq-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/intaleq-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/intaleq-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/intaleq-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 مبنية على هيكل الملفات الفعلي: +// intaleq_v1/ ← الجذر +// intaleq_v1/auth/ ← مشترك راكب/سائق +// intaleq_v1/auth/syria/ ← تسجيل سوريا +// intaleq_v1/auth/captin/ ← تسجيل السائق +// ═══════════════════════════════════════════════════════════════ + +function authenticateJWT(): object +{ + $secretKey = trim(file_get_contents('/home/intaleq-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=`intaleqUserDB1`@`%`*/ /*!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=`intaleqUserDB1`@`%`*/ /*!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 +``` + + + + + +سياسة الخصوصية وشروط الخدمة – Intaleq Driver + + + + + +
+

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

+

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

+

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

+

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

+
+ +
+

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

+

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

+
    +
  • في الواجهة (Foreground): عرض موقع السائق على الخريطة وإتاحة الطلبات المناسبة.
  • +
  • في الخلفية/عند الإغلاق: استقبال طلبات جديدة قريبة، وتمكين تتبع الراكب للمسار، وحساب المسافة/الوقت/الأجرة.
  • +
+

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

+
+ +
+

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

+
+
+

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

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

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

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

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

+
    +
  • تشغيل الخدمة الأساسية وإسناد الرحلات والملاحة وتتبع الرحلة واحتساب الأجرة.
  • +
  • السلامة ومنع الاحتيال والتحقق من الأهلية القانونية للسائق.
  • +
  • الدعم الفني وتحسين الجودة والتحليلات المجمّعة.
  • +
  • الالتزام بواجبات محاسبية/ضريبية وقانونية.
  • +
+

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

+
+ +
+

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

+
    +
  • مزودو الخرائط/الملاحة (مثل Google Maps Platform) لمعالجة الخرائط والتوجيه.
  • +
  • خدمات الإشعارات والأداء/الأعطال (مثل Firebase Cloud Messaging وCrashlytics/Analytics).
  • +
  • مزودو الدفع والتحقق والامتثال حسب السوق (مثل MTN، Syriatel، eCash/الهرم) عند الحاجة.
  • +
  • جهات رسمية/رقابية عند وجود التزام قانوني.
  • +
+

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

+
+ +
+

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

+
    +
  • بيانات الحساب والهوية: طالما الحساب فعّال، ثم لمدة معقولة بعد الإنهاء للامتثال/حل النزاعات.
  • +
  • بيانات الرحلات والفوترة: وفق المتطلبات القانونية المحلية (عادة بين 3–5 سنوات).
  • +
  • سجلات الأداء والأعطال: لفترات أقصر (عادة حتى 12 شهرًا).
  • +
+
+ +
+

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

+
    +
  • تشفير أثناء النقل (TLS) وتدابير وصول مقيّدة وسجلات تدقيق.
  • +
  • مراجعات دورية وإصلاح الثغرات عند اكتشافها.
  • +
+

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

+
+ +
+

6) القاصرون

+

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

+
+ +
+

7) حقوقك

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

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

+
+ +
+

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

+

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

+
+ +
+

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

+

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

+
+ +
+

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

+
    +
  • الإشعارات (Push): لإعلام السائق بالطلبات والرسائل.
  • +
  • الكاميرا/الصور: لالتقاط/رفع صور الوثائق أو المركبة (إن طُلبت).
  • +
  • التخزين: لحفظ/قراءة صور الوثائق (إن لزم).
  • +
+
+ +
+

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

+

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

+
+ +
+

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

+

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

+
+ +
+

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

+

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

+
+ +
+ + +
+

Privacy Policy (English)

+

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

+ +
+

Prominent Disclosure – Location

+

The Intaleq 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.

+
    +
  • Foreground: show driver location and enable dispatch.
  • +
  • Background/closed: receive new requests, rider trip-tracking, and route/fare computation.
  • +
+

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

+
+ +

Data We Collect

+
    +
  • Driver-provided: name, phone, profile photo; vehicle details; legal documents; account settings.
  • +
  • Automatically collected: precise/approximate location (foreground & background), trip history, start/finish points, durations/distances, ratings; device info and identifiers (e.g., FCM token), IP, performance/crash logs; payout/billing data where applicable.
  • +
+ +

Purposes & Legal Bases

+
    +
  • Core service operation (dispatch, navigation, tracking, fare computation); safety & fraud prevention; support; analytics; legal compliance.
  • +
  • Legal bases: contract performance; legitimate interests (safety, fraud prevention, improvement); consent for sensitive permissions such as background location.
  • +
+ +

Sharing

+
    +
  • Map/navigation providers (e.g., Google Maps Platform), notifications/performance/crash services (e.g., Firebase), payment/verification partners (e.g., MTN, Syriatel, eCash/Al-Haram as applicable), and authorities when legally required. No sale of personal data.
  • +
+ +

Retention

+
    +
  • Account/identity: while the account is active and for a reasonable period thereafter.
  • +
  • Trips/billing: per legal requirements (typically 3–5 years).
  • +
  • Performance/crash logs: typically up to 12 months.
  • +
+ +

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

+
    +
  • Access, rectification, deletion (subject to legal retention), restriction/objection, data portability where applicable, and consent withdrawal for sensitive permissions.
  • +
+ +

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.

+
+ +
+ +
+

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

+
    +
  • باستخدام التطبيق، تُقرّ بالتزامك بالقوانين المحلية وبسياسة الخصوصية.
  • +
  • تقديم معلومات دقيقة والمحافظة على سلوك مهني وسلامة المركبة.
  • +
+
+ +
+

© 2025 انطلق لنقل الركاب – جميع الحقوق محفوظة.

+
+ + + +``` + +## 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/intaleq-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/intaleq-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/intaleq-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/intaleq-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 +``` + + + + + + Intaleq - 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 Intaleq application ("the App"), you agree to be bound by these Terms and Conditions. Intaleq reserves the right to modify these terms at any time. Continued use constitutes acceptance of the terms.

+

Definitions

+
    +
  • "Intaleq" 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 Intaleq.
  • +
  • "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 Intaleq 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". Intaleq 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=`intaleqLocation`@`%`*/ /*!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=`intaleqLocation`@`%`*/ /*!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, 'intaleq:'); + } 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/intaleq-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/intaleq-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/intaleq-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/intaleq-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/intaleq-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 Intaleq 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 Intaleq 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/intaleq/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 Intaleq 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 = "/intaleq/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/intaleq-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 = "Intaleq_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']; +}); + +?> + + + + + + تقرير السائقين - Intaleq + + + + + +
+ + +
+ +
+
+
+

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

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

Intaleq

+
:آخر تحديث بيانات
+
+
+ +
+
+ إجمالي السائقين + +
+
+ النخبة (+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\": \"بخصوص شكوتك في رحلة Intaleq\", \"body\": \"رسالة واضحة للراكب بنتيجة الشكوى\" }, + \"driverReport\": { \"title\": \"بخصوص بلاغ رحلتك الأخيرة في Intaleq\", \"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/intaleq/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"); +} + +$INTALEQ_SMTP_PASSWORD = getenv('INTALEQ_SMTP_PASSWORD'); + +// بناء محتوى الإيميل بتصميم عصري وبريميوم +$bodyEmail = " + + + + + + + +
+
+

INTALEQ

+

Your journey, our priority

+
+
+
Hello, $passengerName!
+

Thank you for choosing INTALEQ. 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 = $INTALEQ_SMTP_PASSWORD; + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + $mail->Port = 587; + + $mail->setFrom($EMAIL_ADDRESS, 'INTALEQ'); + $mail->addAddress($passengerEmail, $passengerName); + $mail->isHTML(true); + $mail->Subject = 'Your INTALEQ Trip Details'; + $mail->Body = $bodyEmail; + + $mail->send(); + jsonSuccess(null, "Email sent successfully"); +} catch (Exception $e) { + jsonError("Failed to send email: " . $mail->ErrorInfo); +} +``` + diff --git a/load_env.php b/load_env.php new file mode 100755 index 0000000..38c666a --- /dev/null +++ b/load_env.php @@ -0,0 +1,23 @@ +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' => 3600 + ]); + +} 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); +} \ No newline at end of file diff --git a/loginAdmin.php b/loginAdmin.php new file mode 100755 index 0000000..9e77cf9 --- /dev/null +++ b/loginAdmin.php @@ -0,0 +1,81 @@ +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); +} \ No newline at end of file diff --git a/loginFirstTime.php b/loginFirstTime.php new file mode 100755 index 0000000..73fd4a4 --- /dev/null +++ b/loginFirstTime.php @@ -0,0 +1,81 @@ +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/intaleq-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); +} \ No newline at end of file diff --git a/loginFirstTimeDriver.php b/loginFirstTimeDriver.php new file mode 100755 index 0000000..ae3d0f0 --- /dev/null +++ b/loginFirstTimeDriver.php @@ -0,0 +1,76 @@ +enforce(RateLimiter::identifier(), 'login'); + + $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' => getenv('APP_ISSUER') ?: 'Tripz', + 'aud' => $audience, + 'jti' => bin2hex(random_bytes(16)), + ]; + + if ($fpHash !== null) { + $payload['fingerPrint'] = $fpHash; + } + + $secretKey = trim(file_get_contents('/home/intaleq-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); +} \ No newline at end of file diff --git a/loginJwtDriver.php b/loginJwtDriver.php new file mode 100755 index 0000000..c8a1f6f --- /dev/null +++ b/loginJwtDriver.php @@ -0,0 +1,95 @@ +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' => 14400 + ]); + +} 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); +} \ No newline at end of file diff --git a/loginJwtWalletDriver.php b/loginJwtWalletDriver.php new file mode 100755 index 0000000..0789b04 --- /dev/null +++ b/loginJwtWalletDriver.php @@ -0,0 +1,111 @@ +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/intaleq-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); +} \ No newline at end of file diff --git a/loginWallet.php b/loginWallet.php new file mode 100755 index 0000000..beec19f --- /dev/null +++ b/loginWallet.php @@ -0,0 +1,97 @@ +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/intaleq-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); +} \ No newline at end of file diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..fcd73f6 --- /dev/null +++ b/logout.php @@ -0,0 +1,23 @@ +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); +} diff --git a/migrate_driver_passwords.php b/migrate_driver_passwords.php new file mode 100755 index 0000000..cc6b7df --- /dev/null +++ b/migrate_driver_passwords.php @@ -0,0 +1,128 @@ + 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); +} \ No newline at end of file diff --git a/migration/get_all_driver_fingerprints.php b/migration/get_all_driver_fingerprints.php new file mode 100755 index 0000000..dc85754 --- /dev/null +++ b/migration/get_all_driver_fingerprints.php @@ -0,0 +1,48 @@ + + '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']); +} diff --git a/migration/get_all_fingerprints.php b/migration/get_all_fingerprints.php new file mode 100755 index 0000000..b2338d5 --- /dev/null +++ b/migration/get_all_fingerprints.php @@ -0,0 +1,57 @@ + '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']); +} \ No newline at end of file diff --git a/migration/update_driver_fingerprint_admin.php b/migration/update_driver_fingerprint_admin.php new file mode 100755 index 0000000..7f717c5 --- /dev/null +++ b/migration/update_driver_fingerprint_admin.php @@ -0,0 +1,49 @@ + + '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']); +} \ No newline at end of file diff --git a/migration/update_fingerprint_admin.php b/migration/update_fingerprint_admin.php new file mode 100755 index 0000000..a394bc0 --- /dev/null +++ b/migration/update_fingerprint_admin.php @@ -0,0 +1,63 @@ + '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']); +} \ No newline at end of file diff --git a/new_driver_car/100221243420413735049.jpg b/new_driver_car/100221243420413735049.jpg new file mode 100644 index 0000000..e2309c0 Binary files /dev/null and b/new_driver_car/100221243420413735049.jpg differ diff --git a/new_driver_car/100276066669243532075.jpg b/new_driver_car/100276066669243532075.jpg new file mode 100644 index 0000000..4b65d07 Binary files /dev/null and b/new_driver_car/100276066669243532075.jpg differ diff --git a/new_driver_car/105897591838899631737.jpg b/new_driver_car/105897591838899631737.jpg new file mode 100644 index 0000000..62a5369 Binary files /dev/null and b/new_driver_car/105897591838899631737.jpg differ diff --git a/new_driver_car/114243034311436865474.jpg b/new_driver_car/114243034311436865474.jpg new file mode 100644 index 0000000..c9ff312 Binary files /dev/null and b/new_driver_car/114243034311436865474.jpg differ diff --git a/new_driver_car/mahmoudcici40FGH4MCQC3fd.jpg b/new_driver_car/mahmoudcici40FGH4MCQC3fd.jpg new file mode 100644 index 0000000..638d8fc Binary files /dev/null and b/new_driver_car/mahmoudcici40FGH4MCQC3fd.jpg differ diff --git a/privacy_policy.php b/privacy_policy.php new file mode 100755 index 0000000..82e2020 --- /dev/null +++ b/privacy_policy.php @@ -0,0 +1,294 @@ + + + + + + Intaleq - 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 Intaleq application ("the App"), you agree to be bound by these Terms and Conditions. Intaleq reserves the right to modify these terms at any time. Continued use constitutes acceptance of the terms.

+

Definitions

+
    +
  • "Intaleq" 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 Intaleq.
  • +
  • "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 Intaleq 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". Intaleq 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

+
+
+ +
+ + + \ No newline at end of file diff --git a/privacy_policy1.php b/privacy_policy1.php new file mode 100755 index 0000000..04886a1 --- /dev/null +++ b/privacy_policy1.php @@ -0,0 +1,240 @@ + + + + + +سياسة الخصوصية وشروط الخدمة – Intaleq Driver + + + + + +
+

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

+

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

+

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

+

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

+
+ +
+

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

+

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

+
    +
  • في الواجهة (Foreground): عرض موقع السائق على الخريطة وإتاحة الطلبات المناسبة.
  • +
  • في الخلفية/عند الإغلاق: استقبال طلبات جديدة قريبة، وتمكين تتبع الراكب للمسار، وحساب المسافة/الوقت/الأجرة.
  • +
+

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

+
+ +
+

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

+
+
+

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

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

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

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

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

+
    +
  • تشغيل الخدمة الأساسية وإسناد الرحلات والملاحة وتتبع الرحلة واحتساب الأجرة.
  • +
  • السلامة ومنع الاحتيال والتحقق من الأهلية القانونية للسائق.
  • +
  • الدعم الفني وتحسين الجودة والتحليلات المجمّعة.
  • +
  • الالتزام بواجبات محاسبية/ضريبية وقانونية.
  • +
+

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

+
+ +
+

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

+
    +
  • مزودو الخرائط/الملاحة (مثل Google Maps Platform) لمعالجة الخرائط والتوجيه.
  • +
  • خدمات الإشعارات والأداء/الأعطال (مثل Firebase Cloud Messaging وCrashlytics/Analytics).
  • +
  • مزودو الدفع والتحقق والامتثال حسب السوق (مثل MTN، Syriatel، eCash/الهرم) عند الحاجة.
  • +
  • جهات رسمية/رقابية عند وجود التزام قانوني.
  • +
+

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

+
+ +
+

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

+
    +
  • بيانات الحساب والهوية: طالما الحساب فعّال، ثم لمدة معقولة بعد الإنهاء للامتثال/حل النزاعات.
  • +
  • بيانات الرحلات والفوترة: وفق المتطلبات القانونية المحلية (عادة بين 3–5 سنوات).
  • +
  • سجلات الأداء والأعطال: لفترات أقصر (عادة حتى 12 شهرًا).
  • +
+
+ +
+

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

+
    +
  • تشفير أثناء النقل (TLS) وتدابير وصول مقيّدة وسجلات تدقيق.
  • +
  • مراجعات دورية وإصلاح الثغرات عند اكتشافها.
  • +
+

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

+
+ +
+

6) القاصرون

+

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

+
+ +
+

7) حقوقك

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

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

+
+ +
+

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

+

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

+
+ +
+

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

+

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

+
+ +
+

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

+
    +
  • الإشعارات (Push): لإعلام السائق بالطلبات والرسائل.
  • +
  • الكاميرا/الصور: لالتقاط/رفع صور الوثائق أو المركبة (إن طُلبت).
  • +
  • التخزين: لحفظ/قراءة صور الوثائق (إن لزم).
  • +
+
+ +
+

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

+

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

+
+ +
+

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

+

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

+
+ +
+

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

+

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

+
+ +
+ + +
+

Privacy Policy (English)

+

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

+ +
+

Prominent Disclosure – Location

+

The Intaleq 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.

+
    +
  • Foreground: show driver location and enable dispatch.
  • +
  • Background/closed: receive new requests, rider trip-tracking, and route/fare computation.
  • +
+

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

+
+ +

Data We Collect

+
    +
  • Driver-provided: name, phone, profile photo; vehicle details; legal documents; account settings.
  • +
  • Automatically collected: precise/approximate location (foreground & background), trip history, start/finish points, durations/distances, ratings; device info and identifiers (e.g., FCM token), IP, performance/crash logs; payout/billing data where applicable.
  • +
+ +

Purposes & Legal Bases

+
    +
  • Core service operation (dispatch, navigation, tracking, fare computation); safety & fraud prevention; support; analytics; legal compliance.
  • +
  • Legal bases: contract performance; legitimate interests (safety, fraud prevention, improvement); consent for sensitive permissions such as background location.
  • +
+ +

Sharing

+
    +
  • Map/navigation providers (e.g., Google Maps Platform), notifications/performance/crash services (e.g., Firebase), payment/verification partners (e.g., MTN, Syriatel, eCash/Al-Haram as applicable), and authorities when legally required. No sale of personal data.
  • +
+ +

Retention

+
    +
  • Account/identity: while the account is active and for a reasonable period thereafter.
  • +
  • Trips/billing: per legal requirements (typically 3–5 years).
  • +
  • Performance/crash logs: typically up to 12 months.
  • +
+ +

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

+
    +
  • Access, rectification, deletion (subject to legal retention), restriction/objection, data portability where applicable, and consent withdrawal for sensitive permissions.
  • +
+ +

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.

+
+ +
+ +
+

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

+
    +
  • باستخدام التطبيق، تُقرّ بالتزامك بالقوانين المحلية وبسياسة الخصوصية.
  • +
  • تقديم معلومات دقيقة والمحافظة على سلوك مهني وسلامة المركبة.
  • +
+
+ +
+

© 2025 انطلق لنقل الركاب – جميع الحقوق محفوظة.

+
+ + + \ No newline at end of file diff --git a/ride/RegisrationCar/add.php b/ride/RegisrationCar/add.php new file mode 100755 index 0000000..94b39d1 --- /dev/null +++ b/ride/RegisrationCar/add.php @@ -0,0 +1,80 @@ + $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."); +} \ No newline at end of file diff --git a/ride/RegisrationCar/delete.php b/ride/RegisrationCar/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/RegisrationCar/get.php b/ride/RegisrationCar/get.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/RegisrationCar/makeDefaultCar.php b/ride/RegisrationCar/makeDefaultCar.php new file mode 100755 index 0000000..dbd8f3b --- /dev/null +++ b/ride/RegisrationCar/makeDefaultCar.php @@ -0,0 +1,29 @@ +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."); +} +?> \ No newline at end of file diff --git a/ride/RegisrationCar/selectDriverAndCarForMishwariTrip.php b/ride/RegisrationCar/selectDriverAndCarForMishwariTrip.php new file mode 100755 index 0000000..b5c9d5e --- /dev/null +++ b/ride/RegisrationCar/selectDriverAndCarForMishwariTrip.php @@ -0,0 +1,125 @@ += 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()); +} \ No newline at end of file diff --git a/ride/RegisrationCar/update.php b/ride/RegisrationCar/update.php new file mode 100755 index 0000000..a85896c --- /dev/null +++ b/ride/RegisrationCar/update.php @@ -0,0 +1,61 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/apiKey/add.php b/ride/apiKey/add.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/apiKey/delete.php b/ride/apiKey/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/apiKey/error_log b/ride/apiKey/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/apiKey/get.php b/ride/apiKey/get.php new file mode 100644 index 0000000..2fd0b09 --- /dev/null +++ b/ride/apiKey/get.php @@ -0,0 +1,48 @@ +prepare($sql); + $stmt->execute(); + $result = $stmt->fetchAll(PDO::FETCH_ASSOC); + + return $result; +} + + +?> \ No newline at end of file diff --git a/ride/apiKey/update.php b/ride/apiKey/update.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/cancelRide/add.php b/ride/cancelRide/add.php new file mode 100644 index 0000000..57e3e12 --- /dev/null +++ b/ride/cancelRide/add.php @@ -0,0 +1,25 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/cancelRide/addCancelTripFromDriverAfterApplied.php b/ride/cancelRide/addCancelTripFromDriverAfterApplied.php new file mode 100644 index 0000000..3a9d7e0 --- /dev/null +++ b/ride/cancelRide/addCancelTripFromDriverAfterApplied.php @@ -0,0 +1,150 @@ + $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()); +} +?> +?> \ No newline at end of file diff --git a/ride/cancelRide/delete.php b/ride/cancelRide/delete.php new file mode 100644 index 0000000..b35a79d --- /dev/null +++ b/ride/cancelRide/delete.php @@ -0,0 +1,16 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/cancelRide/error_log b/ride/cancelRide/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/cancelRide/get.php b/ride/cancelRide/get.php new file mode 100644 index 0000000..3646555 --- /dev/null +++ b/ride/cancelRide/get.php @@ -0,0 +1,15 @@ +prepare($sql); +$stmt->execute(); + +$result = $stmt->fetchAll(PDO::FETCH_ASSOC); + +if ($stmt->rowCount() > 0) { + jsonSuccess($result); +} else { + jsonError("No records found"); +} +?> \ No newline at end of file diff --git a/ride/cancelRide/update.php b/ride/cancelRide/update.php new file mode 100644 index 0000000..c44bdd0 --- /dev/null +++ b/ride/cancelRide/update.php @@ -0,0 +1,52 @@ +prepare($sql); +$stmt->execute($params); + +// التحقق من النتيجة +if ($stmt->rowCount() > 0) { + jsonSuccess(null, "Data updated successfully"); +} else { + jsonError("Failed to update data or no changes made"); +} +?> \ No newline at end of file diff --git a/ride/carDrivers/add.php b/ride/carDrivers/add.php new file mode 100755 index 0000000..a0717ed --- /dev/null +++ b/ride/carDrivers/add.php @@ -0,0 +1,55 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/carDrivers/delete.php b/ride/carDrivers/delete.php new file mode 100755 index 0000000..c9307e8 --- /dev/null +++ b/ride/carDrivers/delete.php @@ -0,0 +1,19 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/carDrivers/error_log b/ride/carDrivers/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/carDrivers/get.php b/ride/carDrivers/get.php new file mode 100755 index 0000000..c3237b3 --- /dev/null +++ b/ride/carDrivers/get.php @@ -0,0 +1,89 @@ +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"); +} \ No newline at end of file diff --git a/ride/card-image-driver/add.php b/ride/card-image-driver/add.php new file mode 100644 index 0000000..9266a9d --- /dev/null +++ b/ride/card-image-driver/add.php @@ -0,0 +1,120 @@ + + +// 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')); + } +} + +?> \ No newline at end of file diff --git a/ride/card-image-driver/delete.php b/ride/card-image-driver/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/card-image-driver/get.php b/ride/card-image-driver/get.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/card-image-driver/update.php b/ride/card-image-driver/update.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/driverPayment/add.php b/ride/driverPayment/add.php new file mode 100644 index 0000000..9b7f3dd --- /dev/null +++ b/ride/driverPayment/add.php @@ -0,0 +1,25 @@ +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); +} +?> \ No newline at end of file diff --git a/ride/driverPayment/delete.php b/ride/driverPayment/delete.php new file mode 100644 index 0000000..f9b66c5 --- /dev/null +++ b/ride/driverPayment/delete.php @@ -0,0 +1,18 @@ +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"; +} +?> \ No newline at end of file diff --git a/ride/driverPayment/error_log b/ride/driverPayment/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/driverPayment/get.php b/ride/driverPayment/get.php new file mode 100644 index 0000000..cdc59ea --- /dev/null +++ b/ride/driverPayment/get.php @@ -0,0 +1,20 @@ +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."; +} +?> \ No newline at end of file diff --git a/ride/driverPayment/update.php b/ride/driverPayment/update.php new file mode 100644 index 0000000..478bfc5 --- /dev/null +++ b/ride/driverPayment/update.php @@ -0,0 +1,22 @@ +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"; +} +?> \ No newline at end of file diff --git a/ride/driverWallet/add.php b/ride/driverWallet/add.php new file mode 100644 index 0000000..294989b --- /dev/null +++ b/ride/driverWallet/add.php @@ -0,0 +1,58 @@ +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"); +} diff --git a/ride/driverWallet/addPaymentToken.php b/ride/driverWallet/addPaymentToken.php new file mode 100644 index 0000000..f9b6ac5 --- /dev/null +++ b/ride/driverWallet/addPaymentToken.php @@ -0,0 +1,49 @@ +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); +} \ No newline at end of file diff --git a/ride/driverWallet/delete.php b/ride/driverWallet/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/driverWallet/driverStatistic.php b/ride/driverWallet/driverStatistic.php new file mode 100644 index 0000000..737b580 --- /dev/null +++ b/ride/driverWallet/driverStatistic.php @@ -0,0 +1,46 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/driverWallet/error_log b/ride/driverWallet/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/driverWallet/get.php b/ride/driverWallet/get.php new file mode 100644 index 0000000..45d736c --- /dev/null +++ b/ride/driverWallet/get.php @@ -0,0 +1,42 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/driverWallet/getDriverDetails.php b/ride/driverWallet/getDriverDetails.php new file mode 100644 index 0000000..2aef406 --- /dev/null +++ b/ride/driverWallet/getDriverDetails.php @@ -0,0 +1,34 @@ +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"); +} + +?> \ No newline at end of file diff --git a/ride/driverWallet/getDriverWeekPaymentMove.php b/ride/driverWallet/getDriverWeekPaymentMove.php new file mode 100644 index 0000000..281f34f --- /dev/null +++ b/ride/driverWallet/getDriverWeekPaymentMove.php @@ -0,0 +1,37 @@ += 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"); +} +?> \ No newline at end of file diff --git a/ride/driverWallet/getWalletByDriver.php b/ride/driverWallet/getWalletByDriver.php new file mode 100644 index 0000000..6fad20b --- /dev/null +++ b/ride/driverWallet/getWalletByDriver.php @@ -0,0 +1,30 @@ += 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"); +} +?> \ No newline at end of file diff --git a/ride/driverWallet/sendEmailTransfer.php b/ride/driverWallet/sendEmailTransfer.php new file mode 100644 index 0000000..ba28c22 --- /dev/null +++ b/ride/driverWallet/sendEmailTransfer.php @@ -0,0 +1,122 @@ + + + + + +
+

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

+

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

+

نريد إعلامك أن مبلغ $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"; +} diff --git a/ride/driverWallet/update.php b/ride/driverWallet/update.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/driver_behavior/get_driver_behavior.php b/ride/driver_behavior/get_driver_behavior.php new file mode 100644 index 0000000..3834ef9 --- /dev/null +++ b/ride/driver_behavior/get_driver_behavior.php @@ -0,0 +1,40 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/driver_order/add.php b/ride/driver_order/add.php new file mode 100755 index 0000000..b897e37 --- /dev/null +++ b/ride/driver_order/add.php @@ -0,0 +1,38 @@ +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"); + } +} +?> \ No newline at end of file diff --git a/ride/driver_order/delete.php b/ride/driver_order/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/driver_order/error_log b/ride/driver_order/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/driver_order/get.php b/ride/driver_order/get.php new file mode 100755 index 0000000..9ad4f87 --- /dev/null +++ b/ride/driver_order/get.php @@ -0,0 +1,75 @@ +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"); +} + +?> \ No newline at end of file diff --git a/ride/driver_order/getOrderCancelStatus.php b/ride/driver_order/getOrderCancelStatus.php new file mode 100644 index 0000000..168c6b7 --- /dev/null +++ b/ride/driver_order/getOrderCancelStatus.php @@ -0,0 +1,25 @@ +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" + ]); +} +?> \ No newline at end of file diff --git a/ride/driver_order/update.php b/ride/driver_order/update.php new file mode 100644 index 0000000..8fa4db4 --- /dev/null +++ b/ride/driver_order/update.php @@ -0,0 +1,32 @@ +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"); // أو لم يحدث تغيير في البيانات +} +?> \ No newline at end of file diff --git a/ride/driver_scam/add.php b/ride/driver_scam/add.php new file mode 100644 index 0000000..4080508 --- /dev/null +++ b/ride/driver_scam/add.php @@ -0,0 +1,49 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/driver_scam/delete.php b/ride/driver_scam/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/driver_scam/error_log b/ride/driver_scam/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/driver_scam/get.php b/ride/driver_scam/get.php new file mode 100755 index 0000000..84ef318 --- /dev/null +++ b/ride/driver_scam/get.php @@ -0,0 +1,48 @@ += 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()); +} +?> \ No newline at end of file diff --git a/ride/driver_scam/update.php b/ride/driver_scam/update.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/egyptPhones/add.php b/ride/egyptPhones/add.php new file mode 100644 index 0000000..8503ea0 --- /dev/null +++ b/ride/egyptPhones/add.php @@ -0,0 +1,40 @@ +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()); +} +?> diff --git a/ride/egyptPhones/error_log b/ride/egyptPhones/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/egyptPhones/get.php b/ride/egyptPhones/get.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/egyptPhones/syrianAdd.php b/ride/egyptPhones/syrianAdd.php new file mode 100755 index 0000000..3bce9a6 --- /dev/null +++ b/ride/egyptPhones/syrianAdd.php @@ -0,0 +1,37 @@ +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()); +} +?> diff --git a/ride/feedBack/add.php b/ride/feedBack/add.php new file mode 100755 index 0000000..799d080 --- /dev/null +++ b/ride/feedBack/add.php @@ -0,0 +1,35 @@ +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" + ]); +} +?> diff --git a/ride/feedBack/add_solve_all.php b/ride/feedBack/add_solve_all.php new file mode 100755 index 0000000..1ac5009 --- /dev/null +++ b/ride/feedBack/add_solve_all.php @@ -0,0 +1,286 @@ +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\": \"بخصوص شكوتك في رحلة Intaleq\", \"body\": \"رسالة واضحة للراكب بنتيجة الشكوى\" }, + \"driverReport\": { \"title\": \"بخصوص بلاغ رحلتك الأخيرة في Intaleq\", \"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'] +]); + +?> \ No newline at end of file diff --git a/ride/feedBack/delete.php b/ride/feedBack/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/feedBack/error_log b/ride/feedBack/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/feedBack/get.php b/ride/feedBack/get.php new file mode 100755 index 0000000..eb45009 --- /dev/null +++ b/ride/feedBack/get.php @@ -0,0 +1,65 @@ +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 an empty list + jsonSuccess([]); +} +?> \ No newline at end of file diff --git a/ride/feedBack/update.php b/ride/feedBack/update.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/firebase/add.php b/ride/firebase/add.php new file mode 100644 index 0000000..9791239 --- /dev/null +++ b/ride/firebase/add.php @@ -0,0 +1,47 @@ +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"); + } +} +?> \ No newline at end of file diff --git a/ride/firebase/addDriver.php b/ride/firebase/addDriver.php new file mode 100644 index 0000000..b1e820c --- /dev/null +++ b/ride/firebase/addDriver.php @@ -0,0 +1,46 @@ +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"); + } +} +?> \ No newline at end of file diff --git a/ride/firebase/addToken.php b/ride/firebase/addToken.php new file mode 100755 index 0000000..9791239 --- /dev/null +++ b/ride/firebase/addToken.php @@ -0,0 +1,47 @@ +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"); + } +} +?> \ No newline at end of file diff --git a/ride/firebase/delete.php b/ride/firebase/delete.php new file mode 100644 index 0000000..047640a --- /dev/null +++ b/ride/firebase/delete.php @@ -0,0 +1,17 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/firebase/fcm_fun.php b/ride/firebase/fcm_fun.php new file mode 100755 index 0000000..1ef9b52 --- /dev/null +++ b/ride/firebase/fcm_fun.php @@ -0,0 +1,277 @@ + '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 + ] + ]); +} +?> diff --git a/ride/firebase/get.php b/ride/firebase/get.php new file mode 100644 index 0000000..7a28d91 --- /dev/null +++ b/ride/firebase/get.php @@ -0,0 +1,22 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/firebase/getALlTokenDrivers.php b/ride/firebase/getALlTokenDrivers.php new file mode 100755 index 0000000..f0a35ce --- /dev/null +++ b/ride/firebase/getALlTokenDrivers.php @@ -0,0 +1,23 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/firebase/getAllTokenPassengers.php b/ride/firebase/getAllTokenPassengers.php new file mode 100755 index 0000000..0e0bd51 --- /dev/null +++ b/ride/firebase/getAllTokenPassengers.php @@ -0,0 +1,23 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/firebase/getDriverToken.php b/ride/firebase/getDriverToken.php new file mode 100644 index 0000000..1bae751 --- /dev/null +++ b/ride/firebase/getDriverToken.php @@ -0,0 +1,26 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/firebase/getTokenParent.php b/ride/firebase/getTokenParent.php new file mode 100644 index 0000000..03d7a86 --- /dev/null +++ b/ride/firebase/getTokenParent.php @@ -0,0 +1,45 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/firebase/getTokensPassenger.php b/ride/firebase/getTokensPassenger.php new file mode 100755 index 0000000..7a28d91 --- /dev/null +++ b/ride/firebase/getTokensPassenger.php @@ -0,0 +1,22 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/firebase/notify_driver_arrival.php b/ride/firebase/notify_driver_arrival.php new file mode 100755 index 0000000..a6434f2 --- /dev/null +++ b/ride/firebase/notify_driver_arrival.php @@ -0,0 +1,41 @@ + 'test'], // بيانات إضافية بسيطة + "General" // التصنيف +); + +// 3. طباعة النتيجة +//echo "النتيجة:\n"; +print_r($result); + +?> \ No newline at end of file diff --git a/ride/firebase/send_fcm.php b/ride/firebase/send_fcm.php new file mode 100755 index 0000000..b366905 --- /dev/null +++ b/ride/firebase/send_fcm.php @@ -0,0 +1,171 @@ + '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); +} +?> diff --git a/ride/helpCenter/add.php b/ride/helpCenter/add.php new file mode 100644 index 0000000..9d7cf00 --- /dev/null +++ b/ride/helpCenter/add.php @@ -0,0 +1,19 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/helpCenter/delete.php b/ride/helpCenter/delete.php new file mode 100644 index 0000000..eebae18 --- /dev/null +++ b/ride/helpCenter/delete.php @@ -0,0 +1,17 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/helpCenter/error_log b/ride/helpCenter/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/helpCenter/get.php b/ride/helpCenter/get.php new file mode 100644 index 0000000..04bedbe --- /dev/null +++ b/ride/helpCenter/get.php @@ -0,0 +1,28 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/helpCenter/getById.php b/ride/helpCenter/getById.php new file mode 100644 index 0000000..69ac1d5 --- /dev/null +++ b/ride/helpCenter/getById.php @@ -0,0 +1,18 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/helpCenter/update.php b/ride/helpCenter/update.php new file mode 100644 index 0000000..88bfc74 --- /dev/null +++ b/ride/helpCenter/update.php @@ -0,0 +1,19 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/invitor/add.php b/ride/invitor/add.php new file mode 100755 index 0000000..9e5e777 --- /dev/null +++ b/ride/invitor/add.php @@ -0,0 +1,89 @@ +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()); + } +} +?> \ No newline at end of file diff --git a/ride/invitor/addInvitationPassenger.php b/ride/invitor/addInvitationPassenger.php new file mode 100755 index 0000000..c9b590b --- /dev/null +++ b/ride/invitor/addInvitationPassenger.php @@ -0,0 +1,97 @@ +prepare("SELECT COUNT(*) FROM invitesToPassengers WHERE inviteCode = ?"); + $stmt->execute([$code]); + + if ($stmt->fetchColumn() == 0) { + return $code; + } + } +} + +$driverId = filterRequest("driverId"); +$inviterPassengerPhone = filterRequest("inviterPassengerPhone"); + +if (!$driverId || !$inviterPassengerPhone) { + jsonError("Missing required parameters: driverId or 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()); + } +} +?> \ No newline at end of file diff --git a/ride/invitor/error_log b/ride/invitor/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/invitor/get.php b/ride/invitor/get.php new file mode 100644 index 0000000..02e2070 --- /dev/null +++ b/ride/invitor/get.php @@ -0,0 +1,52 @@ +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."); +} +?> \ No newline at end of file diff --git a/ride/invitor/getDriverInvitationToPassengers.php b/ride/invitor/getDriverInvitationToPassengers.php new file mode 100755 index 0000000..0f86e95 --- /dev/null +++ b/ride/invitor/getDriverInvitationToPassengers.php @@ -0,0 +1,48 @@ +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."); +} +?> \ No newline at end of file diff --git a/ride/invitor/update.php b/ride/invitor/update.php new file mode 100644 index 0000000..1b1a1ae --- /dev/null +++ b/ride/invitor/update.php @@ -0,0 +1,16 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/invitor/updateDriverInvitationDirectly.php b/ride/invitor/updateDriverInvitationDirectly.php new file mode 100755 index 0000000..ee651cc --- /dev/null +++ b/ride/invitor/updateDriverInvitationDirectly.php @@ -0,0 +1,59 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/invitor/updateInvitationCodeFromRegister.php b/ride/invitor/updateInvitationCodeFromRegister.php new file mode 100755 index 0000000..a4eb728 --- /dev/null +++ b/ride/invitor/updateInvitationCodeFromRegister.php @@ -0,0 +1,44 @@ + 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()); +} +?> \ No newline at end of file diff --git a/ride/invitor/updatePassengerGift.php b/ride/invitor/updatePassengerGift.php new file mode 100755 index 0000000..dba1492 --- /dev/null +++ b/ride/invitor/updatePassengerGift.php @@ -0,0 +1,16 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/invitor/updatePassengersInvitation.php b/ride/invitor/updatePassengersInvitation.php new file mode 100755 index 0000000..a4e795d --- /dev/null +++ b/ride/invitor/updatePassengersInvitation.php @@ -0,0 +1,48 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/kazan/add.php b/ride/kazan/add.php new file mode 100755 index 0000000..da205b5 --- /dev/null +++ b/ride/kazan/add.php @@ -0,0 +1,45 @@ +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(); +?> diff --git a/ride/kazan/delete.php b/ride/kazan/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/kazan/error_log b/ride/kazan/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/kazan/get.php b/ride/kazan/get.php new file mode 100644 index 0000000..b411b8b --- /dev/null +++ b/ride/kazan/get.php @@ -0,0 +1,18 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/kazan/update.php b/ride/kazan/update.php new file mode 100644 index 0000000..a496b71 --- /dev/null +++ b/ride/kazan/update.php @@ -0,0 +1,38 @@ +prepare($sql); +$stmt->execute($params); + +if ($stmt->rowCount() > 0) { + jsonSuccess(null, "Kazan data updated successfully"); +} else { + jsonError("Failed to update kazan data"); +} +?> \ No newline at end of file diff --git a/ride/license/add.php b/ride/license/add.php new file mode 100644 index 0000000..4255546 --- /dev/null +++ b/ride/license/add.php @@ -0,0 +1,52 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/license/delete.php b/ride/license/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/license/error_log b/ride/license/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/license/get.php b/ride/license/get.php new file mode 100644 index 0000000..28a0bf0 --- /dev/null +++ b/ride/license/get.php @@ -0,0 +1,22 @@ +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"); + +} +?> \ No newline at end of file diff --git a/ride/license/update.php b/ride/license/update.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/location/add.php b/ride/location/add.php new file mode 100755 index 0000000..f965387 --- /dev/null +++ b/ride/location/add.php @@ -0,0 +1,73 @@ + 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"); +} \ No newline at end of file diff --git a/ride/location/addpassengerLocation.php b/ride/location/addpassengerLocation.php new file mode 100755 index 0000000..e2c403d --- /dev/null +++ b/ride/location/addpassengerLocation.php @@ -0,0 +1,34 @@ +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"); +} +?> diff --git a/ride/location/delete.php b/ride/location/delete.php new file mode 100644 index 0000000..47b3fd7 --- /dev/null +++ b/ride/location/delete.php @@ -0,0 +1,20 @@ +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"); +} + +?> \ No newline at end of file diff --git a/ride/location/driversTime.html b/ride/location/driversTime.html new file mode 100755 index 0000000..5b399b1 --- /dev/null +++ b/ride/location/driversTime.html @@ -0,0 +1,341 @@ + + + + + + متابعة السائقين - انطلق + + + + + + + + + +
+
+
+

+ + لوحة متابعة السائقين +

+

+ + توقيت آخر تحديث للبيانات: + جاري التحميل... +

+
+ +
+ +
+
+
+ +
+
+

جاري جلب ملف البيانات (active_drivers_cache.json)...

+
+ + + + + + + + \ No newline at end of file diff --git a/ride/location/get.php b/ride/location/get.php new file mode 100755 index 0000000..14bc8f7 --- /dev/null +++ b/ride/location/get.php @@ -0,0 +1,188 @@ + $lat, + 'lng' => $lng, + 'radius' => 5, // 5 كم كافية للعرض + 'limit' => 50 + ])); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 3); + curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-internal-key: $INTERNAL_KEY"]); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + $redisDrivers = []; + if ($httpCode == 200 && $response) { + $json = json_decode($response, true); + if (isset($json['status']) && $json['status'] === true) { + $redisDrivers = $json['data']; + } + } + + if (empty($redisDrivers)) { + jsonSuccess([]); + exit; + } + + // تجهيز خريطة لدمج البيانات لاحقاً (ID => RedisData) + $driversMap = []; + $driverIds = []; + foreach ($redisDrivers as $d) { + $driverIds[] = $d['id']; + $driversMap[$d['id']] = $d; + } + + // ========================================== + // 3. جلب التفاصيل الكاملة من MySQL (مثل الملف القديم تماماً) + // ========================================== + + // تجهيز الـ Placeholders + $placeholders = implode(',', array_fill(0, count($driverIds), '?')); + + // الاستعلام الشامل (نفس الحقول القديمة) + $sql_drivers_info = " + SELECT + d.id AS driver_id, + d.phone, d.email, d.birthdate, d.first_name, d.last_name, d.gender, d.maritalStatus, + COALESCE(cr.make, d.make, '') AS make, + cr.car_plate, + COALESCE(cr.model, d.model, '') AS model, + cr.color, cr.vin, cr.color_hex, + COALESCE(cr.year, d.year, 0) AS year, + cr.vehicle_category_id, + dt.token, + COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver + FROM driver d + LEFT JOIN CarRegistration cr ON cr.driverID = d.id + LEFT JOIN driverToken dt ON dt.captain_id = d.id + LEFT JOIN ( + SELECT driver_id, AVG(rating) AS ratingDriver + FROM ratingDriver + GROUP BY driver_id + ) rdAvg ON rdAvg.driver_id = d.id + WHERE d.id IN ($placeholders) + AND COALESCE(cr.year, d.year, 0) > 2000 + AND (COALESCE(cr.make, d.make, '') NOT LIKE '%دراج%' AND COALESCE(cr.model, d.model, '') NOT LIKE '%دراج%') + "; + + $stmt = $con->prepare($sql_drivers_info); + $stmt->execute($driverIds); + $drivers_db = $stmt->fetchAll(PDO::FETCH_ASSOC); + + if (empty($drivers_db)) { + jsonSuccess([], "No matching drivers in DB"); + exit; + } + + // ========================================== + // 4. معالجة البيانات، الدمج، وفك التشفير + // ========================================== + + $final_result = []; + $serverNow = date('Y-m-d H:i:s'); + $fieldsToDecrypt = ['phone','email','gender','birthdate','first_name','last_name','token','car_plate','vin']; + + // الهاش الخاص بالإناث (لتحديد النوع لاحقاً إذا لزم الأمر) + // $femaleHash = 'bQ6yWJ2EVXKZooHdGclvmFiDlZCM8UYeO+ILFjDUvpQ='; + + foreach ($drivers_db as $row) { + $did = $row['driver_id']; + + // دمج بيانات الموقع الحية من الريدز (أهم خطوة) + if (isset($driversMap[$did])) { + $redisInfo = $driversMap[$did]; + $row['latitude'] = $redisInfo['lat']; + $row['longitude'] = $redisInfo['lng']; + $row['heading'] = $redisInfo['heading']; + $row['speed'] = $redisInfo['speed']; + // $row['distance'] = $redisInfo['distance']; // إذا أردت إضافتها + } else { + // حالة نادرة: السائق موجود في الاستعلام ولكن ليس في مصفوفة الريدز (لا يجب أن تحدث) + continue; + } + + $row['serverNow'] = $serverNow; + + // فك التشفير (Decrypt) + foreach ($fieldsToDecrypt as $field) { + if (isset($row[$field]) && $row[$field] !== null && $row[$field] !== '') { + try { + $row[$field] = $encryptionHelper->decryptData($row[$field]); + } catch (Exception $e) { + $row[$field] = null; + } + } + } + + // حساب العمر + if (!empty($row['birthdate'])) { + try { + $birthdate = new DateTime($row['birthdate']); + $today = new DateTime(); + $row['age'] = $today->diff($birthdate)->y; + } catch (Exception $e) { $row['age'] = null; } + } else { + $row['age'] = null; + } + + // إضافة نوع السيارة البسيط (اختياري، إذا كان التطبيق يعتمد عليه) + /* + $type = 'car'; + if ($row['vehicle_category_id'] == 2) $type = 'bike'; + elseif ($row['gender'] == 'female') $type = 'lady'; // بعد فك التشفير تكون female + $row['type'] = $type; + */ + + $final_result[] = $row; + } + + // إرجاع النتيجة بنفس الهيكل القديم + jsonSuccess($final_result); + +} catch (PDOException $e) { + jsonError("Database error: " . $e->getMessage()); +} catch (Throwable $e) { + jsonError("Internal error: " . $e->getMessage()); +} +?> \ No newline at end of file diff --git a/ride/location/getBalash.php b/ride/location/getBalash.php new file mode 100755 index 0000000..972031a --- /dev/null +++ b/ride/location/getBalash.php @@ -0,0 +1,166 @@ += 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()); +} diff --git a/ride/location/getCarsLocationByPassengerVan.php b/ride/location/getCarsLocationByPassengerVan.php new file mode 100755 index 0000000..479c4af --- /dev/null +++ b/ride/location/getCarsLocationByPassengerVan.php @@ -0,0 +1,160 @@ += 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()); +} diff --git a/ride/location/getComfort.php b/ride/location/getComfort.php new file mode 100755 index 0000000..7a77cf6 --- /dev/null +++ b/ride/location/getComfort.php @@ -0,0 +1,170 @@ += 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()); +} diff --git a/ride/location/getDelivery.php b/ride/location/getDelivery.php new file mode 100755 index 0000000..aa82ac3 --- /dev/null +++ b/ride/location/getDelivery.php @@ -0,0 +1,159 @@ += 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()); +} diff --git a/ride/location/getDriverCarsLocationToPassengerAfterApplied.php b/ride/location/getDriverCarsLocationToPassengerAfterApplied.php new file mode 100644 index 0000000..05e6b68 --- /dev/null +++ b/ride/location/getDriverCarsLocationToPassengerAfterApplied.php @@ -0,0 +1,91 @@ + يتصل بقاعدة البيانات الأساسية (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()); +} +?> \ No newline at end of file diff --git a/ride/location/getDriverTimeOnline.php b/ride/location/getDriverTimeOnline.php new file mode 100755 index 0000000..169641a --- /dev/null +++ b/ride/location/getDriverTimeOnline.php @@ -0,0 +1,130 @@ += 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); +} +?> \ No newline at end of file diff --git a/ride/location/getElectric.php b/ride/location/getElectric.php new file mode 100755 index 0000000..eb4bd31 --- /dev/null +++ b/ride/location/getElectric.php @@ -0,0 +1,161 @@ += 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()); +} diff --git a/ride/location/getFemalDriver.php b/ride/location/getFemalDriver.php new file mode 100755 index 0000000..c7756ea --- /dev/null +++ b/ride/location/getFemalDriver.php @@ -0,0 +1,160 @@ += 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()); +} diff --git a/ride/location/getLatestLocationPassenger.php b/ride/location/getLatestLocationPassenger.php new file mode 100644 index 0000000..3a225a5 --- /dev/null +++ b/ride/location/getLatestLocationPassenger.php @@ -0,0 +1,29 @@ +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"); +} + +?> \ No newline at end of file diff --git a/ride/location/getLocationParents.php b/ride/location/getLocationParents.php new file mode 100644 index 0000000..46ad58a --- /dev/null +++ b/ride/location/getLocationParents.php @@ -0,0 +1,88 @@ + يتصل بقاعدة البيانات الأساسية (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()); +} +?> \ No newline at end of file diff --git a/ride/location/getPinkBike.php b/ride/location/getPinkBike.php new file mode 100755 index 0000000..2897451 --- /dev/null +++ b/ride/location/getPinkBike.php @@ -0,0 +1,112 @@ += 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()); +} \ No newline at end of file diff --git a/ride/location/getRidesDriverByDay.php b/ride/location/getRidesDriverByDay.php new file mode 100755 index 0000000..81d3f32 --- /dev/null +++ b/ride/location/getRidesDriverByDay.php @@ -0,0 +1,66 @@ += :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"); +} +?> \ No newline at end of file diff --git a/ride/location/getSpeed.php b/ride/location/getSpeed.php new file mode 100755 index 0000000..720b139 --- /dev/null +++ b/ride/location/getSpeed.php @@ -0,0 +1,157 @@ += 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()); +} diff --git a/ride/location/getTotalDriverDuration.php b/ride/location/getTotalDriverDuration.php new file mode 100755 index 0000000..f47863c --- /dev/null +++ b/ride/location/getTotalDriverDuration.php @@ -0,0 +1,44 @@ += :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"); +} + +?> \ No newline at end of file diff --git a/ride/location/getTotalDriverDurationToday.php b/ride/location/getTotalDriverDurationToday.php new file mode 100644 index 0000000..1f83fdc --- /dev/null +++ b/ride/location/getTotalDriverDurationToday.php @@ -0,0 +1,31 @@ += '$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"); +} + +?> diff --git a/ride/location/getUpdatedLocationForAdmin.php b/ride/location/getUpdatedLocationForAdmin.php new file mode 100755 index 0000000..0ce948f --- /dev/null +++ b/ride/location/getUpdatedLocationForAdmin.php @@ -0,0 +1,126 @@ += 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()]); +} +?> \ No newline at end of file diff --git a/ride/location/get_location_area_links.php b/ride/location/get_location_area_links.php new file mode 100644 index 0000000..8850d6d --- /dev/null +++ b/ride/location/get_location_area_links.php @@ -0,0 +1,24 @@ +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()); +} \ No newline at end of file diff --git a/ride/location/getfemalbehavior.php b/ride/location/getfemalbehavior.php new file mode 100644 index 0000000..274f507 --- /dev/null +++ b/ride/location/getfemalbehavior.php @@ -0,0 +1,86 @@ += :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()); +} +?> \ No newline at end of file diff --git a/ride/location/print.php b/ride/location/print.php new file mode 100755 index 0000000..fa9973f --- /dev/null +++ b/ride/location/print.php @@ -0,0 +1,254 @@ + +

⚠️ 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']; +}); + +?> + + + + + + تقرير السائقين - Intaleq + + + + + +
+ + +
+ +
+
+
+

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

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

Intaleq

+
:آخر تحديث بيانات
+
+
+ +
+
+ إجمالي السائقين + +
+
+ النخبة (+50 ساعة) + +
+
+ مستقرون (+20 ساعة) + +
+
+ يحتاجون متابعة + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
#اسم السائقرقم الهاتفساعات النشاطالحالةتاريخ الانضمامملاحظات إدارية
+ + + + + + + + + +
+
+ + + \ No newline at end of file diff --git a/ride/location/save_behavior.php b/ride/location/save_behavior.php new file mode 100644 index 0000000..763bbeb --- /dev/null +++ b/ride/location/save_behavior.php @@ -0,0 +1,58 @@ + يتصل بقاعدة البيانات الأساسية +// $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 +?> \ No newline at end of file diff --git a/ride/location/update.php b/ride/location/update.php new file mode 100644 index 0000000..d7aa3c6 --- /dev/null +++ b/ride/location/update.php @@ -0,0 +1,69 @@ +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'); +} +?> diff --git a/ride/mishwari/add.php b/ride/mishwari/add.php new file mode 100755 index 0000000..ad6f572 --- /dev/null +++ b/ride/mishwari/add.php @@ -0,0 +1,187 @@ +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"); + } +} +?> \ No newline at end of file diff --git a/ride/mishwari/cancel.php b/ride/mishwari/cancel.php new file mode 100755 index 0000000..f5a537d --- /dev/null +++ b/ride/mishwari/cancel.php @@ -0,0 +1,41 @@ +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."); +} +?> \ No newline at end of file diff --git a/ride/mishwari/error_log b/ride/mishwari/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/mishwari/get.php b/ride/mishwari/get.php new file mode 100755 index 0000000..027cdd7 --- /dev/null +++ b/ride/mishwari/get.php @@ -0,0 +1,70 @@ += 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"); +} +?> \ No newline at end of file diff --git a/ride/mishwari/getDriver.php b/ride/mishwari/getDriver.php new file mode 100755 index 0000000..d99f668 --- /dev/null +++ b/ride/mishwari/getDriver.php @@ -0,0 +1,70 @@ += 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"); +} +?> \ No newline at end of file diff --git a/ride/mishwari/test.php b/ride/mishwari/test.php new file mode 100644 index 0000000..871acb4 --- /dev/null +++ b/ride/mishwari/test.php @@ -0,0 +1,30 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/notificationCaptain/add.php b/ride/notificationCaptain/add.php new file mode 100644 index 0000000..7c2a786 --- /dev/null +++ b/ride/notificationCaptain/add.php @@ -0,0 +1,36 @@ +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"); +} + +?> \ No newline at end of file diff --git a/ride/notificationCaptain/addWaitingRide.php b/ride/notificationCaptain/addWaitingRide.php new file mode 100755 index 0000000..157353d --- /dev/null +++ b/ride/notificationCaptain/addWaitingRide.php @@ -0,0 +1,72 @@ +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()); +} +?> diff --git a/ride/notificationCaptain/delete.php b/ride/notificationCaptain/delete.php new file mode 100644 index 0000000..338b2de --- /dev/null +++ b/ride/notificationCaptain/delete.php @@ -0,0 +1,18 @@ +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"); +} + +?> \ No newline at end of file diff --git a/ride/notificationCaptain/deleteAvailableRide.php b/ride/notificationCaptain/deleteAvailableRide.php new file mode 100755 index 0000000..8ec624e --- /dev/null +++ b/ride/notificationCaptain/deleteAvailableRide.php @@ -0,0 +1,30 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/notificationCaptain/error_log b/ride/notificationCaptain/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/notificationCaptain/get.php b/ride/notificationCaptain/get.php new file mode 100755 index 0000000..8f5bf1d --- /dev/null +++ b/ride/notificationCaptain/get.php @@ -0,0 +1,23 @@ + 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"); +} +?> \ No newline at end of file diff --git a/ride/notificationCaptain/getRideWaiting.php b/ride/notificationCaptain/getRideWaiting.php new file mode 100755 index 0000000..23ed3f2 --- /dev/null +++ b/ride/notificationCaptain/getRideWaiting.php @@ -0,0 +1,159 @@ + '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"); +} +?> \ No newline at end of file diff --git a/ride/notificationCaptain/update.php b/ride/notificationCaptain/update.php new file mode 100644 index 0000000..68a740d --- /dev/null +++ b/ride/notificationCaptain/update.php @@ -0,0 +1,52 @@ + $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"); +} +?> \ No newline at end of file diff --git a/ride/notificationCaptain/updateWaitingTrip.php b/ride/notificationCaptain/updateWaitingTrip.php new file mode 100644 index 0000000..00b58a8 --- /dev/null +++ b/ride/notificationCaptain/updateWaitingTrip.php @@ -0,0 +1,39 @@ + $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"); +} +?> \ No newline at end of file diff --git a/ride/notificationPassenger/add.php b/ride/notificationPassenger/add.php new file mode 100755 index 0000000..672b8eb --- /dev/null +++ b/ride/notificationPassenger/add.php @@ -0,0 +1,33 @@ +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"); +} + +?> \ No newline at end of file diff --git a/ride/notificationPassenger/delete.php b/ride/notificationPassenger/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/notificationPassenger/error_log b/ride/notificationPassenger/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/notificationPassenger/get.php b/ride/notificationPassenger/get.php new file mode 100755 index 0000000..9587e60 --- /dev/null +++ b/ride/notificationPassenger/get.php @@ -0,0 +1,33 @@ += 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 { + jsonSuccess([], "No notification data found"); +} + +?> \ No newline at end of file diff --git a/ride/notificationPassenger/update.php b/ride/notificationPassenger/update.php new file mode 100644 index 0000000..20e062e --- /dev/null +++ b/ride/notificationPassenger/update.php @@ -0,0 +1,42 @@ + $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"); +} +?> \ No newline at end of file diff --git a/ride/overLay/_log.txt b/ride/overLay/_log.txt new file mode 100644 index 0000000..0334b73 --- /dev/null +++ b/ride/overLay/_log.txt @@ -0,0 +1,88 @@ +[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 diff --git a/ride/overLay/add.php b/ride/overLay/add.php new file mode 100755 index 0000000..3989e6b --- /dev/null +++ b/ride/overLay/add.php @@ -0,0 +1,122 @@ +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"); +} + +?> \ No newline at end of file diff --git a/ride/overLay/deletArgumets.php b/ride/overLay/deletArgumets.php new file mode 100755 index 0000000..ba779f5 --- /dev/null +++ b/ride/overLay/deletArgumets.php @@ -0,0 +1,32 @@ +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)'); +} +?> \ No newline at end of file diff --git a/ride/overLay/get.php b/ride/overLay/get.php new file mode 100755 index 0000000..434813e --- /dev/null +++ b/ride/overLay/get.php @@ -0,0 +1,40 @@ += 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."); +} \ No newline at end of file diff --git a/ride/overLay/getArgumentAfterAppliedFromBackground.php b/ride/overLay/getArgumentAfterAppliedFromBackground.php new file mode 100755 index 0000000..dc22662 --- /dev/null +++ b/ride/overLay/getArgumentAfterAppliedFromBackground.php @@ -0,0 +1,38 @@ +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'); +} \ No newline at end of file diff --git a/ride/passengerWallet/add.php b/ride/passengerWallet/add.php new file mode 100644 index 0000000..a2b1b47 --- /dev/null +++ b/ride/passengerWallet/add.php @@ -0,0 +1,32 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/passengerWallet/addPaymentTokenPassenger.php b/ride/passengerWallet/addPaymentTokenPassenger.php new file mode 100644 index 0000000..671fe3b --- /dev/null +++ b/ride/passengerWallet/addPaymentTokenPassenger.php @@ -0,0 +1,53 @@ +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); +} \ No newline at end of file diff --git a/ride/passengerWallet/delete.php b/ride/passengerWallet/delete.php new file mode 100644 index 0000000..e74cc79 --- /dev/null +++ b/ride/passengerWallet/delete.php @@ -0,0 +1,17 @@ +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"); +} +?> diff --git a/ride/passengerWallet/error_log b/ride/passengerWallet/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/passengerWallet/get.php b/ride/passengerWallet/get.php new file mode 100644 index 0000000..590e180 --- /dev/null +++ b/ride/passengerWallet/get.php @@ -0,0 +1,32 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/passengerWallet/getAllPassengerTransaction.php b/ride/passengerWallet/getAllPassengerTransaction.php new file mode 100644 index 0000000..536e672 --- /dev/null +++ b/ride/passengerWallet/getAllPassengerTransaction.php @@ -0,0 +1,40 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/passengerWallet/getPassengerWalletArchive.php b/ride/passengerWallet/getPassengerWalletArchive.php new file mode 100644 index 0000000..d0b3bfc --- /dev/null +++ b/ride/passengerWallet/getPassengerWalletArchive.php @@ -0,0 +1,30 @@ += 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"); +} +?> \ No newline at end of file diff --git a/ride/passengerWallet/getWalletByPassenger.php b/ride/passengerWallet/getWalletByPassenger.php new file mode 100755 index 0000000..81432af --- /dev/null +++ b/ride/passengerWallet/getWalletByPassenger.php @@ -0,0 +1,34 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/passengerWallet/update.php b/ride/passengerWallet/update.php new file mode 100644 index 0000000..adf5ab4 --- /dev/null +++ b/ride/passengerWallet/update.php @@ -0,0 +1,18 @@ + +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"); +} +?> \ No newline at end of file diff --git a/ride/payment/add.php b/ride/payment/add.php new file mode 100644 index 0000000..7701a13 --- /dev/null +++ b/ride/payment/add.php @@ -0,0 +1,42 @@ +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"); +} \ No newline at end of file diff --git a/ride/payment/delete.php b/ride/payment/delete.php new file mode 100644 index 0000000..e69de29 diff --git a/ride/payment/error_log b/ride/payment/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/payment/get.php b/ride/payment/get.php new file mode 100644 index 0000000..fa10d57 --- /dev/null +++ b/ride/payment/get.php @@ -0,0 +1,61 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/payment/getAllPayment.php b/ride/payment/getAllPayment.php new file mode 100644 index 0000000..8b5ea9b --- /dev/null +++ b/ride/payment/getAllPayment.php @@ -0,0 +1,64 @@ + 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"); +} +?> \ No newline at end of file diff --git a/ride/payment/getAllPaymentVisa.php b/ride/payment/getAllPaymentVisa.php new file mode 100644 index 0000000..d4d80c8 --- /dev/null +++ b/ride/payment/getAllPaymentVisa.php @@ -0,0 +1,39 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/payment/getCountRide.php b/ride/payment/getCountRide.php new file mode 100644 index 0000000..547ddd2 --- /dev/null +++ b/ride/payment/getCountRide.php @@ -0,0 +1,29 @@ += 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"); +} +?> \ No newline at end of file diff --git a/ride/payment/update.php b/ride/payment/update.php new file mode 100644 index 0000000..61cecf9 --- /dev/null +++ b/ride/payment/update.php @@ -0,0 +1,65 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/payment/updatePaymetToPaid.php b/ride/payment/updatePaymetToPaid.php new file mode 100644 index 0000000..53ddd99 --- /dev/null +++ b/ride/payment/updatePaymetToPaid.php @@ -0,0 +1,19 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/places/add.php b/ride/places/add.php new file mode 100755 index 0000000..264a2a5 --- /dev/null +++ b/ride/places/add.php @@ -0,0 +1,26 @@ +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'); +} +?> \ No newline at end of file diff --git a/ride/places/error_log b/ride/places/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/places_syria/add.php b/ride/places_syria/add.php new file mode 100755 index 0000000..e69de29 diff --git a/ride/places_syria/get.php b/ride/places_syria/get.php new file mode 100755 index 0000000..a22d489 --- /dev/null +++ b/ride/places_syria/get.php @@ -0,0 +1,99 @@ +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"); +} +?> diff --git a/ride/places_syria/reverse_geocode.php b/ride/places_syria/reverse_geocode.php new file mode 100755 index 0000000..b9ba455 --- /dev/null +++ b/ride/places_syria/reverse_geocode.php @@ -0,0 +1,155 @@ + '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(); +?> \ No newline at end of file diff --git a/ride/profile/error_log b/ride/profile/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/profile/get.php b/ride/profile/get.php new file mode 100644 index 0000000..5304b09 --- /dev/null +++ b/ride/profile/get.php @@ -0,0 +1,35 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/profile/getCaptainProfile.php b/ride/profile/getCaptainProfile.php new file mode 100644 index 0000000..7297c3a --- /dev/null +++ b/ride/profile/getCaptainProfile.php @@ -0,0 +1,88 @@ +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); +?> \ No newline at end of file diff --git a/ride/profile/update.php b/ride/profile/update.php new file mode 100644 index 0000000..2cab13f --- /dev/null +++ b/ride/profile/update.php @@ -0,0 +1,37 @@ + $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"); +} +?> \ No newline at end of file diff --git a/ride/profile/updateDriverEmail.php b/ride/profile/updateDriverEmail.php new file mode 100755 index 0000000..947435e --- /dev/null +++ b/ride/profile/updateDriverEmail.php @@ -0,0 +1,29 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/promo/add.php b/ride/promo/add.php new file mode 100755 index 0000000..f635b0f --- /dev/null +++ b/ride/promo/add.php @@ -0,0 +1,31 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/promo/delete.php b/ride/promo/delete.php new file mode 100644 index 0000000..a0874f3 --- /dev/null +++ b/ride/promo/delete.php @@ -0,0 +1,16 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/promo/get.php b/ride/promo/get.php new file mode 100644 index 0000000..ac8dcb6 --- /dev/null +++ b/ride/promo/get.php @@ -0,0 +1,29 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/promo/getPromoBytody.php b/ride/promo/getPromoBytody.php new file mode 100755 index 0000000..af6b86d --- /dev/null +++ b/ride/promo/getPromoBytody.php @@ -0,0 +1,27 @@ += CURDATE();"; + +$stmt = $con->prepare($sql); +$stmt->execute(); +$result = $stmt->fetchAll(PDO::FETCH_ASSOC); + +if ($result) { + jsonSuccess($result); +} else { + // Print an empty list + jsonSuccess([]); +} +?> \ No newline at end of file diff --git a/ride/promo/getPromoFirst.php b/ride/promo/getPromoFirst.php new file mode 100755 index 0000000..79f2cde --- /dev/null +++ b/ride/promo/getPromoFirst.php @@ -0,0 +1,31 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/promo/update.php b/ride/promo/update.php new file mode 100644 index 0000000..dd12d43 --- /dev/null +++ b/ride/promo/update.php @@ -0,0 +1,31 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/rate/add.php b/ride/rate/add.php new file mode 100644 index 0000000..ac7b0f5 --- /dev/null +++ b/ride/rate/add.php @@ -0,0 +1,30 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/rate/addRateToDriver.php b/ride/rate/addRateToDriver.php new file mode 100644 index 0000000..c14581f --- /dev/null +++ b/ride/rate/addRateToDriver.php @@ -0,0 +1,58 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/rate/add_rate_app.php b/ride/rate/add_rate_app.php new file mode 100755 index 0000000..b445f6d --- /dev/null +++ b/ride/rate/add_rate_app.php @@ -0,0 +1,34 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/rate/error_log b/ride/rate/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/rate/getDriverRate.php b/ride/rate/getDriverRate.php new file mode 100755 index 0000000..f95b673 --- /dev/null +++ b/ride/rate/getDriverRate.php @@ -0,0 +1,25 @@ +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"); +} +?> diff --git a/ride/rate/getPassengerRate.php b/ride/rate/getPassengerRate.php new file mode 100755 index 0000000..7747fc1 --- /dev/null +++ b/ride/rate/getPassengerRate.php @@ -0,0 +1,23 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/rate/sendEmailRateingApp.php b/ride/rate/sendEmailRateingApp.php new file mode 100755 index 0000000..db6bfc8 --- /dev/null +++ b/ride/rate/sendEmailRateingApp.php @@ -0,0 +1,77 @@ + +

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

+

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

+

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

+

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

+

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

+

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

+

فريق انطلق.

+"; + +if (mail($email, $subject, $bodyEmail, $headers)) { + echo "Email sent successfully to $email."; +} else { + echo "Failed to send email."; +} +?> + diff --git a/ride/rides/acceptRide.php b/ride/rides/acceptRide.php new file mode 100755 index 0000000..0167bb8 --- /dev/null +++ b/ride/rides/acceptRide.php @@ -0,0 +1,180 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/rides/add.php b/ride/rides/add.php new file mode 100644 index 0000000..41c1d6f --- /dev/null +++ b/ride/rides/add.php @@ -0,0 +1,128 @@ + $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()); +} +?> \ No newline at end of file diff --git a/ride/rides/add_ride.php b/ride/rides/add_ride.php new file mode 100755 index 0000000..a23b629 --- /dev/null +++ b/ride/rides/add_ride.php @@ -0,0 +1,256 @@ + (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"); +} +?> \ No newline at end of file diff --git a/ride/rides/arrive_ride.php b/ride/rides/arrive_ride.php new file mode 100755 index 0000000..ee24b6a --- /dev/null +++ b/ride/rides/arrive_ride.php @@ -0,0 +1,68 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/rides/cancelRideFromDriver.php b/ride/rides/cancelRideFromDriver.php new file mode 100755 index 0000000..01b6d79 --- /dev/null +++ b/ride/rides/cancelRideFromDriver.php @@ -0,0 +1,108 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/rides/cancel_ride_by_driver.php b/ride/rides/cancel_ride_by_driver.php new file mode 100755 index 0000000..6716503 --- /dev/null +++ b/ride/rides/cancel_ride_by_driver.php @@ -0,0 +1,122 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/rides/cancel_ride_by_passenger.php b/ride/rides/cancel_ride_by_passenger.php new file mode 100755 index 0000000..f65e4b5 --- /dev/null +++ b/ride/rides/cancel_ride_by_passenger.php @@ -0,0 +1,135 @@ +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/intaleq-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"); +} +?> \ No newline at end of file diff --git a/ride/rides/cron_ride_timeout.php b/ride/rides/cron_ride_timeout.php new file mode 100755 index 0000000..12cf541 --- /dev/null +++ b/ride/rides/cron_ride_timeout.php @@ -0,0 +1,64 @@ +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()]); +} +?> \ No newline at end of file diff --git a/ride/rides/delete.php b/ride/rides/delete.php new file mode 100644 index 0000000..2297df3 --- /dev/null +++ b/ride/rides/delete.php @@ -0,0 +1,19 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/rides/emailToPassengerTripDetail.php b/ride/rides/emailToPassengerTripDetail.php new file mode 100644 index 0000000..b34deba --- /dev/null +++ b/ride/rides/emailToPassengerTripDetail.php @@ -0,0 +1,89 @@ + + + + + +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]); +} \ No newline at end of file diff --git a/ride/rides/error_log b/ride/rides/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/rides/finish_ride_updates.php b/ride/rides/finish_ride_updates.php new file mode 100755 index 0000000..e0aa00e --- /dev/null +++ b/ride/rides/finish_ride_updates.php @@ -0,0 +1,105 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/rides/get.php b/ride/rides/get.php new file mode 100755 index 0000000..5b29861 --- /dev/null +++ b/ride/rides/get.php @@ -0,0 +1,48 @@ +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 { + jsonSuccess([], "No rides found"); + } +} catch (PDOException $e) { + jsonError("Database error: " . $e->getMessage()); +} +?> \ No newline at end of file diff --git a/ride/rides/getRealTimeHeatmap.php b/ride/rides/getRealTimeHeatmap.php new file mode 100755 index 0000000..77bbe3c --- /dev/null +++ b/ride/rides/getRealTimeHeatmap.php @@ -0,0 +1,91 @@ +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; // زيادة الوزن (حسب نوع الطلب) +} +?> \ No newline at end of file diff --git a/ride/rides/getRideOrderID.php b/ride/rides/getRideOrderID.php new file mode 100755 index 0000000..3aecd1b --- /dev/null +++ b/ride/rides/getRideOrderID.php @@ -0,0 +1,148 @@ +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()]); +} +?> \ No newline at end of file diff --git a/ride/rides/getRideOrderIDNew.php b/ride/rides/getRideOrderIDNew.php new file mode 100755 index 0000000..3aecd1b --- /dev/null +++ b/ride/rides/getRideOrderIDNew.php @@ -0,0 +1,148 @@ +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()]); +} +?> \ No newline at end of file diff --git a/ride/rides/getRideStatus.php b/ride/rides/getRideStatus.php new file mode 100644 index 0000000..2f7ce45 --- /dev/null +++ b/ride/rides/getRideStatus.php @@ -0,0 +1,26 @@ +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."); +} +?> \ No newline at end of file diff --git a/ride/rides/getRideStatusBegin.php b/ride/rides/getRideStatusBegin.php new file mode 100644 index 0000000..9599287 --- /dev/null +++ b/ride/rides/getRideStatusBegin.php @@ -0,0 +1,27 @@ +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."); +} +?> \ No newline at end of file diff --git a/ride/rides/getRideStatusFromStartApp.php b/ride/rides/getRideStatusFromStartApp.php new file mode 100644 index 0000000..2dff1b8 --- /dev/null +++ b/ride/rides/getRideStatusFromStartApp.php @@ -0,0 +1,93 @@ +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()]); +} +?> \ No newline at end of file diff --git a/ride/rides/getTripCountByCaptain.php b/ride/rides/getTripCountByCaptain.php new file mode 100644 index 0000000..f8651fd --- /dev/null +++ b/ride/rides/getTripCountByCaptain.php @@ -0,0 +1,23 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/rides/get_driver_location.php b/ride/rides/get_driver_location.php new file mode 100755 index 0000000..3f5f11b --- /dev/null +++ b/ride/rides/get_driver_location.php @@ -0,0 +1,154 @@ + "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"]); +} +?> \ No newline at end of file diff --git a/ride/rides/gterideForDriverManyTime.php b/ride/rides/gterideForDriverManyTime.php new file mode 100644 index 0000000..b582a14 --- /dev/null +++ b/ride/rides/gterideForDriverManyTime.php @@ -0,0 +1,32 @@ +prepare($sql); +$stmt->execute(); + +$row = $stmt->fetch(PDO::FETCH_ASSOC); + +echo json_encode([ + "status" => "success", + "data" => $row +]); +?> \ No newline at end of file diff --git a/ride/rides/heatmap_live.json b/ride/rides/heatmap_live.json new file mode 100644 index 0000000..de88c03 --- /dev/null +++ b/ride/rides/heatmap_live.json @@ -0,0 +1,7 @@ +[ + {"lat": 33.5100, "lng": 36.2700, "count": 5, "intensity": "high", "surge": 1.5}, + {"lat": 33.5200, "lng": 36.2800, "count": 3, "intensity": "medium", "surge": 1.2}, + {"lat": 33.5150, "lng": 36.2750, "count": 2, "intensity": "normal", "surge": 1.0}, + {"lat": 33.5050, "lng": 36.2650, "count": 6, "intensity": "high", "surge": 1.5}, + {"lat": 33.5250, "lng": 36.2850, "count": 1, "intensity": "low", "surge": 1.0} +] \ No newline at end of file diff --git a/ride/rides/public_track_location.php b/ride/rides/public_track_location.php new file mode 100755 index 0000000..7ad2e94 --- /dev/null +++ b/ride/rides/public_track_location.php @@ -0,0 +1,99 @@ + "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 = "Intaleq_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"); +} \ No newline at end of file diff --git a/ride/rides/retry_search_drivers.php b/ride/rides/retry_search_drivers.php new file mode 100755 index 0000000..2b57fc6 --- /dev/null +++ b/ride/rides/retry_search_drivers.php @@ -0,0 +1,107 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/rides/start_ride.php b/ride/rides/start_ride.php new file mode 100755 index 0000000..11f7d06 --- /dev/null +++ b/ride/rides/start_ride.php @@ -0,0 +1,96 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/rides/test_notification.php b/ride/rides/test_notification.php new file mode 100755 index 0000000..f7714bf --- /dev/null +++ b/ride/rides/test_notification.php @@ -0,0 +1,40 @@ + '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"; diff --git a/ride/rides/update.php b/ride/rides/update.php new file mode 100755 index 0000000..6568304 --- /dev/null +++ b/ride/rides/update.php @@ -0,0 +1,89 @@ + $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()); +} +?> \ No newline at end of file diff --git a/ride/rides/updateRideAndCheckIfApplied.php b/ride/rides/updateRideAndCheckIfApplied.php new file mode 100644 index 0000000..3cff662 --- /dev/null +++ b/ride/rides/updateRideAndCheckIfApplied.php @@ -0,0 +1,47 @@ +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."); +} +?> \ No newline at end of file diff --git a/ride/rides/updateStausFromSpeed.php b/ride/rides/updateStausFromSpeed.php new file mode 100755 index 0000000..25d3854 --- /dev/null +++ b/ride/rides/updateStausFromSpeed.php @@ -0,0 +1,79 @@ +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()); +} +?> \ No newline at end of file diff --git a/ride/rides/update_ride_cancel_wait.php b/ride/rides/update_ride_cancel_wait.php new file mode 100755 index 0000000..2d801d9 --- /dev/null +++ b/ride/rides/update_ride_cancel_wait.php @@ -0,0 +1,30 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/seferWallet/add.php b/ride/seferWallet/add.php new file mode 100644 index 0000000..feb1223 --- /dev/null +++ b/ride/seferWallet/add.php @@ -0,0 +1,39 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/seferWallet/error_log b/ride/seferWallet/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/seferWallet/get.php b/ride/seferWallet/get.php new file mode 100644 index 0000000..16e0427 --- /dev/null +++ b/ride/seferWallet/get.php @@ -0,0 +1,29 @@ +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"); +} + +?> \ No newline at end of file diff --git a/ride/tips/add.php b/ride/tips/add.php new file mode 100755 index 0000000..d083e4a --- /dev/null +++ b/ride/tips/add.php @@ -0,0 +1,32 @@ + 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"); +} +?> \ No newline at end of file diff --git a/ride/tips/get.php b/ride/tips/get.php new file mode 100644 index 0000000..7a31ee3 --- /dev/null +++ b/ride/tips/get.php @@ -0,0 +1,35 @@ +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"); +} +?> \ No newline at end of file diff --git a/ride/videos_driver/error_log b/ride/videos_driver/error_log new file mode 100644 index 0000000..e69de29 diff --git a/ride/videos_driver/get.php b/ride/videos_driver/get.php new file mode 100755 index 0000000..e2976ce --- /dev/null +++ b/ride/videos_driver/get.php @@ -0,0 +1,14 @@ +prepare($sql); +$stmt->execute(); +$data = $stmt->fetchAll(PDO::FETCH_ASSOC); + +if ($data) { + jsonSuccess($data); +} else { + jsonError("No video records found"); +} +?> \ No newline at end of file diff --git a/schema_primary.sql b/schema_primary.sql new file mode 100644 index 0000000..3efeeb6 --- /dev/null +++ b/schema_primary.sql @@ -0,0 +1,1784 @@ +-- 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=`intaleqUserDB1`@`%`*/ /*!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=`intaleqUserDB1`@`%`*/ /*!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 diff --git a/schema_ride.sql b/schema_ride.sql new file mode 100644 index 0000000..17b8e9b --- /dev/null +++ b/schema_ride.sql @@ -0,0 +1,1787 @@ +-- 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 diff --git a/schema_tracking.sql b/schema_tracking.sql new file mode 100644 index 0000000..57562cc --- /dev/null +++ b/schema_tracking.sql @@ -0,0 +1,1826 @@ +-- 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=`intaleqLocation`@`%`*/ /*!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=`intaleqLocation`@`%`*/ /*!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 diff --git a/serviceapp/addCartoDriver.php b/serviceapp/addCartoDriver.php new file mode 100755 index 0000000..e9eb272 --- /dev/null +++ b/serviceapp/addCartoDriver.php @@ -0,0 +1,101 @@ +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()); +} +?> \ No newline at end of file diff --git a/serviceapp/addNotesDriver.php b/serviceapp/addNotesDriver.php new file mode 100644 index 0000000..6f0b842 --- /dev/null +++ b/serviceapp/addNotesDriver.php @@ -0,0 +1,40 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/addNotesPassenger.php b/serviceapp/addNotesPassenger.php new file mode 100644 index 0000000..fbde845 --- /dev/null +++ b/serviceapp/addNotesPassenger.php @@ -0,0 +1,31 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/addWelcomeDriverNote.php b/serviceapp/addWelcomeDriverNote.php new file mode 100644 index 0000000..5d52344 --- /dev/null +++ b/serviceapp/addWelcomeDriverNote.php @@ -0,0 +1,33 @@ +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"); +} + +?> diff --git a/serviceapp/deleteDriverNotCompleteRegistration.php b/serviceapp/deleteDriverNotCompleteRegistration.php new file mode 100755 index 0000000..648897e --- /dev/null +++ b/serviceapp/deleteDriverNotCompleteRegistration.php @@ -0,0 +1,35 @@ +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"); +} + +?> \ No newline at end of file diff --git a/serviceapp/driverWhoregisterFfterCall.php b/serviceapp/driverWhoregisterFfterCall.php new file mode 100644 index 0000000..8453150 --- /dev/null +++ b/serviceapp/driverWhoregisterFfterCall.php @@ -0,0 +1,34 @@ +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."); +} +?> \ No newline at end of file diff --git a/serviceapp/drivers_list.txt b/serviceapp/drivers_list.txt new file mode 100644 index 0000000..f553044 --- /dev/null +++ b/serviceapp/drivers_list.txt @@ -0,0 +1,723 @@ +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 diff --git a/serviceapp/editCarPlate.php b/serviceapp/editCarPlate.php new file mode 100755 index 0000000..230cda5 --- /dev/null +++ b/serviceapp/editCarPlate.php @@ -0,0 +1,64 @@ +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."); +} \ No newline at end of file diff --git a/serviceapp/getCarPlateNotEdit.php b/serviceapp/getCarPlateNotEdit.php new file mode 100755 index 0000000..0af93a9 --- /dev/null +++ b/serviceapp/getCarPlateNotEdit.php @@ -0,0 +1,54 @@ +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"); +} +?> diff --git a/serviceapp/getComplaintAllData.php b/serviceapp/getComplaintAllData.php new file mode 100644 index 0000000..aa2a9cc --- /dev/null +++ b/serviceapp/getComplaintAllData.php @@ -0,0 +1,183 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getComplaintAllDataForDriver.php b/serviceapp/getComplaintAllDataForDriver.php new file mode 100644 index 0000000..fd2dee6 --- /dev/null +++ b/serviceapp/getComplaintAllDataForDriver.php @@ -0,0 +1,185 @@ +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); +} +?> \ No newline at end of file diff --git a/serviceapp/getDriverByNational.php b/serviceapp/getDriverByNational.php new file mode 100755 index 0000000..dd1815e --- /dev/null +++ b/serviceapp/getDriverByNational.php @@ -0,0 +1,125 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getDriverByPhone.php b/serviceapp/getDriverByPhone.php new file mode 100644 index 0000000..ee13765 --- /dev/null +++ b/serviceapp/getDriverByPhone.php @@ -0,0 +1,119 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getDriverDetailsForActivate.php b/serviceapp/getDriverDetailsForActivate.php new file mode 100755 index 0000000..82a64a8 --- /dev/null +++ b/serviceapp/getDriverDetailsForActivate.php @@ -0,0 +1,45 @@ +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"); +} \ No newline at end of file diff --git a/serviceapp/getDriverNotCompleteRegistration.php b/serviceapp/getDriverNotCompleteRegistration.php new file mode 100755 index 0000000..d458def --- /dev/null +++ b/serviceapp/getDriverNotCompleteRegistration.php @@ -0,0 +1,45 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getDriversPhoneNotComplete.php b/serviceapp/getDriversPhoneNotComplete.php new file mode 100755 index 0000000..d3a5793 --- /dev/null +++ b/serviceapp/getDriversPhoneNotComplete.php @@ -0,0 +1,56 @@ += (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"); +} +?> diff --git a/serviceapp/getDriversWaitingActive.php b/serviceapp/getDriversWaitingActive.php new file mode 100755 index 0000000..acb672e --- /dev/null +++ b/serviceapp/getDriversWaitingActive.php @@ -0,0 +1,32 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getEditorStatsCalls.php b/serviceapp/getEditorStatsCalls.php new file mode 100755 index 0000000..0b2021b --- /dev/null +++ b/serviceapp/getEditorStatsCalls.php @@ -0,0 +1,50 @@ +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())); +} +?> \ No newline at end of file diff --git a/serviceapp/getEmployeeDriverAfterCallingRegister.php b/serviceapp/getEmployeeDriverAfterCallingRegister.php new file mode 100755 index 0000000..6452cdb --- /dev/null +++ b/serviceapp/getEmployeeDriverAfterCallingRegister.php @@ -0,0 +1,62 @@ += '$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()); +} +?> \ No newline at end of file diff --git a/serviceapp/getEmployeeStatic.php b/serviceapp/getEmployeeStatic.php new file mode 100755 index 0000000..b2dfe89 --- /dev/null +++ b/serviceapp/getEmployeeStatic.php @@ -0,0 +1,43 @@ += '$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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getJsonFile.php b/serviceapp/getJsonFile.php new file mode 100755 index 0000000..7496488 --- /dev/null +++ b/serviceapp/getJsonFile.php @@ -0,0 +1,89 @@ += 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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getNewDriverRegister.php b/serviceapp/getNewDriverRegister.php new file mode 100644 index 0000000..2879996 --- /dev/null +++ b/serviceapp/getNewDriverRegister.php @@ -0,0 +1,73 @@ +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"); +} + +?> \ No newline at end of file diff --git a/serviceapp/getNotesForEmployee.php b/serviceapp/getNotesForEmployee.php new file mode 100755 index 0000000..7c81e03 --- /dev/null +++ b/serviceapp/getNotesForEmployee.php @@ -0,0 +1,38 @@ +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()); +} +?> \ No newline at end of file diff --git a/serviceapp/getPackages.php b/serviceapp/getPackages.php new file mode 100755 index 0000000..436d539 --- /dev/null +++ b/serviceapp/getPackages.php @@ -0,0 +1,18 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getPassengersByPhone.php b/serviceapp/getPassengersByPhone.php new file mode 100644 index 0000000..5a9062a --- /dev/null +++ b/serviceapp/getPassengersByPhone.php @@ -0,0 +1,80 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getPassengersNotCompleteRegistration.php b/serviceapp/getPassengersNotCompleteRegistration.php new file mode 100644 index 0000000..5092572 --- /dev/null +++ b/serviceapp/getPassengersNotCompleteRegistration.php @@ -0,0 +1,44 @@ += 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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getPassengersStatic.php b/serviceapp/getPassengersStatic.php new file mode 100644 index 0000000..a30ae05 --- /dev/null +++ b/serviceapp/getPassengersStatic.php @@ -0,0 +1,63 @@ +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())); +} +?> \ No newline at end of file diff --git a/serviceapp/getRidesStatic.php b/serviceapp/getRidesStatic.php new file mode 100755 index 0000000..a5dd1c3 --- /dev/null +++ b/serviceapp/getRidesStatic.php @@ -0,0 +1,64 @@ += '$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"); +} +?> \ No newline at end of file diff --git a/serviceapp/getdriverWithoutCar.php b/serviceapp/getdriverWithoutCar.php new file mode 100755 index 0000000..c4a69c6 --- /dev/null +++ b/serviceapp/getdriverWithoutCar.php @@ -0,0 +1,30 @@ +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"); +} \ No newline at end of file diff --git a/serviceapp/getdriverstotalMonthly.php b/serviceapp/getdriverstotalMonthly.php new file mode 100644 index 0000000..765b330 --- /dev/null +++ b/serviceapp/getdriverstotalMonthly.php @@ -0,0 +1,101 @@ +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())); +} +?> \ No newline at end of file diff --git a/serviceapp/login.php b/serviceapp/login.php new file mode 100755 index 0000000..60ae522 --- /dev/null +++ b/serviceapp/login.php @@ -0,0 +1,57 @@ + "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 \ No newline at end of file diff --git a/serviceapp/registerDriverAndCarService.php b/serviceapp/registerDriverAndCarService.php new file mode 100755 index 0000000..72a0c13 --- /dev/null +++ b/serviceapp/registerDriverAndCarService.php @@ -0,0 +1,237 @@ +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()); +} +?> \ No newline at end of file diff --git a/serviceapp/updateDriver.php b/serviceapp/updateDriver.php new file mode 100755 index 0000000..7d345ce --- /dev/null +++ b/serviceapp/updateDriver.php @@ -0,0 +1,92 @@ + $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"); +} +?> diff --git a/serviceapp/updateDriverToActive.php b/serviceapp/updateDriverToActive.php new file mode 100755 index 0000000..23b5a25 --- /dev/null +++ b/serviceapp/updateDriverToActive.php @@ -0,0 +1,150 @@ +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()); +} + +?> + diff --git a/serviceapp/updatePackages.php b/serviceapp/updatePackages.php new file mode 100755 index 0000000..2aeaf61 --- /dev/null +++ b/serviceapp/updatePackages.php @@ -0,0 +1,26 @@ +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"]); +} +?> \ No newline at end of file diff --git a/serviceapp/web/drivers.html b/serviceapp/web/drivers.html new file mode 100755 index 0000000..e537e1e --- /dev/null +++ b/serviceapp/web/drivers.html @@ -0,0 +1,307 @@ + + + + + + نظام إدارة المركبات + + + + + + + + + +
+ + +
+

الاستعلام عن بيانات السائق والمركبة

+
+ + +
+ +
+
+
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/serviceapp/web/f.html b/serviceapp/web/f.html new file mode 100755 index 0000000..e69de29 diff --git a/serviceapp/web/getDrivers.php b/serviceapp/web/getDrivers.php new file mode 100755 index 0000000..fb0124a --- /dev/null +++ b/serviceapp/web/getDrivers.php @@ -0,0 +1,87 @@ +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"); +} +?> \ No newline at end of file diff --git a/serviceapp/work/addCarWantWork.php b/serviceapp/work/addCarWantWork.php new file mode 100755 index 0000000..6280468 --- /dev/null +++ b/serviceapp/work/addCarWantWork.php @@ -0,0 +1,65 @@ +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); +} +?> \ No newline at end of file diff --git a/serviceapp/work/addDriverWantWork.php b/serviceapp/work/addDriverWantWork.php new file mode 100755 index 0000000..c04692b --- /dev/null +++ b/serviceapp/work/addDriverWantWork.php @@ -0,0 +1,45 @@ +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"); +} +?> \ No newline at end of file diff --git a/uploadImagePortrate.php b/uploadImagePortrate.php new file mode 100755 index 0000000..6ed43c3 --- /dev/null +++ b/uploadImagePortrate.php @@ -0,0 +1,73 @@ +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); +} \ No newline at end of file diff --git a/upload_audio.php b/upload_audio.php new file mode 100755 index 0000000..6b8c66b --- /dev/null +++ b/upload_audio.php @@ -0,0 +1,54 @@ + '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); +} +?> \ No newline at end of file diff --git a/webhook_sms/webhook.php b/webhook_sms/webhook.php new file mode 100755 index 0000000..8d25f0a --- /dev/null +++ b/webhook_sms/webhook.php @@ -0,0 +1,76 @@ + '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.']); +?> +