Initial commit with updated Auth and media ignored

This commit is contained in:
Hamza-Ayed
2026-04-28 13:04:27 +03:00
commit 67af97474c
477 changed files with 66444 additions and 0 deletions

80
ride/RegisrationCar/add.php Executable file
View File

@@ -0,0 +1,80 @@
<?php
require_once __DIR__ . '/../../connect.php';
/* ───── 1) جلب الحقول من طلب POST ───── */
$driverID = filterRequest("driverID");
$vin = filterRequest("vin");
$carPlate = filterRequest("car_plate");
$make = filterRequest("make");
$model = filterRequest("model");
$year = filterRequest("year");
$expirationDate = filterRequest("expiration_date");
$color = filterRequest("color");
$owner = filterRequest("owner");
$colorHex = filterRequest("color_hex");
$fuel = filterRequest("fuel");
/* ───── 2) التحقق من الحقول الأساسية ───── */
$required = [
'driverID' => $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.");
}

View File

View File

View File

@@ -0,0 +1,29 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
$driverID = filterRequest("driverID");
try {
// أولاً: إعادة تعيين isDefault = 0 لكل سيارات السائق
$sql1 = "UPDATE `CarRegistration` SET `isDefault` = 0 WHERE `driverID` = :driverID";
$stmt1 = $con->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.");
}
?>

View File

@@ -0,0 +1,125 @@
<?php
require_once __DIR__ . '/../../connect.php';
try {
$swLat = floatval(filterRequest("southwestLat"));
$neLat = floatval(filterRequest("northeastLat"));
$swLon = floatval(filterRequest("southwestLon"));
$neLon = floatval(filterRequest("northeastLon"));
$yearMin = 2022;
$yearMax = 2025;
if (!is_numeric($swLat) || !is_numeric($neLat) || !is_numeric($swLon) || !is_numeric($neLon)) {
throw new Exception("Invalid coordinate values provided");
}
$sql = "
WITH LatestLocations AS (
SELECT
cl.driver_id,
cl.latitude,
cl.longitude,
cl.heading,
cl.speed,
cl.status,
cl.created_at,
d.phone,
d.email,
d.first_name,
d.last_name,
d.gender,
d.maritalStatus,
d.education,
cr.make,
cr.car_plate,
cr.model,
cr.color,
cr.color_hex,
cr.year,
dt.token,
ROW_NUMBER() OVER(
PARTITION BY cl.driver_id
ORDER BY cl.created_at DESC
) AS row_num
FROM car_locations cl
JOIN driver d ON d.id = cl.driver_id
LEFT JOIN CarRegistration cr ON cr.driverID = cl.driver_id
LEFT JOIN driverToken dt ON dt.captain_id = cl.driver_id
WHERE cl.latitude BETWEEN ? AND ?
AND cl.longitude BETWEEN ? AND ?
AND cr.year BETWEEN ? AND ?
AND cl.created_at >= 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());
}

61
ride/RegisrationCar/update.php Executable file
View File

@@ -0,0 +1,61 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
$driverID = filterRequest("driverID");
// الحقول التي تحتاج لتشفير
$encryptedFields = ['vin', 'car_plate', 'owner'];
// جميع الحقول المسموح بتحديثها
$columns = ['vin', 'car_plate', 'make', 'model', 'year', 'expiration_date', 'color', 'owner', 'isDefault', 'registration_date'];
$columnValues = [];
// تحقق من القيم وأضفها إلى التحديث
foreach ($columns as $column) {
if (isset($_POST[$column])) {
$value = filterRequest($column);
if (!empty($value)) {
// تشفير الحقول الحساسة
if (in_array($column, $encryptedFields)) {
$value = $encryptionHelper->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");
}
?>

0
ride/apiKey/add.php Normal file
View File

0
ride/apiKey/delete.php Normal file
View File

0
ride/apiKey/error_log Normal file
View File

48
ride/apiKey/get.php Normal file
View File

@@ -0,0 +1,48 @@
<?php
require_once __DIR__ . '/../../connect.php';
// Load the .env file and set environment variables
$env_file = __DIR__ . '/../../.env'; // Ensure the .env file exists and is named correctly
if (file_exists($env_file)) {
$lines = file($env_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
if (strpos(trim($line), '#') === 0) {
continue; // Skip comments
}
putenv(trim($line));
}
}
// Get the specific key name from the request
$keyName = filterRequest('keyName');
// Fetch the specific environment variable
$envValue = getenv($keyName);
// Include the specific environment key in the output
$output = [];
if ($keyName && $envValue !== false) {
$output[$keyName] = $envValue;
jsonSuccess($output);
} else {
$apiKeys = getApiKeys($con);
if ($apiKeys) {
jsonSuccess($apiKeys);
} else {
jsonError("No records found or invalid key name");
}
}
function getApiKeys($con) {
$sql = "SELECT `id`, `name`, `hashed_key` FROM `api_keys`";
$stmt = $con->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
?>

0
ride/apiKey/update.php Normal file
View File

25
ride/cancelRide/add.php Normal file
View File

@@ -0,0 +1,25 @@
<?php
require_once __DIR__ . '/../../connect.php';
// استقبال المتغيرات
$driverID = filterRequest("driverID");
$passengerID = filterRequest("passengerID");
$rideID = filterRequest("rideID");
$note = filterRequest("note");
// تنفيذ الإدخال بطريقة آمنة
$sql = "INSERT INTO `canecl` (`driverID`, `passengerID`, `rideID`, `note`)
VALUES (:driverID, :passengerID, :rideID, :note)";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,150 @@
<?php
/*
require_once __DIR__ . '/../../connect.php';
// 🚀 تسجيل بداية العملية المدمجة
error_log("🚀 [cancelRideAndLog.php] Request Started: Cancel Ride + Log Driver Action.");
// 1. استقبال كافة البيانات المطلوبة للعمليتين
$rideId = filterRequest("id"); // معرف الرحلة
$driverID = filterRequest("driver_id");// معرف السائق
$note = filterRequest("notes"); // ملاحظات الإلغاء
// التحقق من البيانات الأساسية
if (!$rideId || !$driverID) {
error_log("❌ [cancelRideAndLog.php] Missing ID or Driver ID.");
jsonError("Missing Required Data (id or driver_id)");
exit;
}
// إعدادات عملية الإلغاء
$newStatus = "cancelRideFromDriver";
// الحالات المسموح بالإلغاء فيها (تأكد من مطابقتها لقاعدة البيانات)
$allowedStatuses = "'wait', 'waiting', 'Apply'";
$sqlCancel = "UPDATE `ride`
SET `status` = '$newStatus', `updated_at` = CURRENT_TIMESTAMP
WHERE `id` = :id
AND `status` IN ($allowedStatuses)";
$params = [':id' => $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());
}
?>
?>

View File

@@ -0,0 +1,16 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
$sql = "DELETE FROM `canecl` WHERE `id` = :id";
$stmt = $con->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");
}
?>

View File

15
ride/cancelRide/get.php Normal file
View File

@@ -0,0 +1,15 @@
<?php
require_once __DIR__ . '/../../connect.php';
$sql = "SELECT * FROM `canecl`";
$stmt = $con->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($stmt->rowCount() > 0) {
jsonSuccess($result);
} else {
jsonError("No records found");
}
?>

View File

@@ -0,0 +1,52 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
// تهيئة المتغيرات
$columnValues = [];
$params = [];
// التعامل مع كل حقل ديناميكيًا
if (isset($_POST["driverID"])) {
$columnValues[] = "`driverID` = :driverID";
$params[':driverID'] = filterRequest("driverID");
}
if (isset($_POST["passengerID"])) {
$columnValues[] = "`passengerID` = :passengerID";
$params[':passengerID'] = filterRequest("passengerID");
}
if (isset($_POST["rideID"])) {
$columnValues[] = "`rideID` = :rideID";
$params[':rideID'] = filterRequest("rideID");
}
if (isset($_POST["note"])) {
$columnValues[] = "`note` = :note";
$params[':note'] = filterRequest("note");
}
// تأكد من وجود بيانات لتحديثها
if (empty($columnValues)) {
jsonError("No data provided to update");
exit;
}
// بناء الاستعلام النهائي
$setClause = implode(", ", $columnValues);
$sql = "UPDATE `canecl` SET $setClause WHERE `id` = :id";
$params[':id'] = $id;
// تنفيذ الاستعلام
$stmt = $con->prepare($sql);
$stmt->execute($params);
// التحقق من النتيجة
if ($stmt->rowCount() > 0) {
jsonSuccess(null, "Data updated successfully");
} else {
jsonError("Failed to update data or no changes made");
}
?>

55
ride/carDrivers/add.php Executable file
View File

@@ -0,0 +1,55 @@
<?php
require_once __DIR__ . '/../../connect.php';
// استقبال القيم
$driverID = filterRequest("driverID");
$vin = $encryptionHelper->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");
}
?>

19
ride/carDrivers/delete.php Executable file
View File

@@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../../connect.php';
// استقبال ID السجل
$id = filterRequest("id");
// حذف السجل من جدول captains_car (أو CarRegistration لو هو الصحيح فعلاً)
$sql = "DELETE FROM captains_car WHERE id = :id";
$stmt = $con->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");
}
?>

View File

89
ride/carDrivers/get.php Executable file
View File

@@ -0,0 +1,89 @@
<?php
// get_driver_cars.php
require_once __DIR__ . '/../../connect.php';
// استقبال driverID (نصي لأنه غالباً محفوظ كنص)
$driverID = filterRequest("driverID");
try {
if (empty($driverID)) {
jsonError("driverID is required");
exit;
}
// هنعرّف دالة لتوحيد الصف من أي جدول لنفس المخطط
function normalize_car_row(array $row, string $source, $encryptionHelper): array {
// بعض الحقول قد لا تكون موجودة في كلا الجدولين
$get = function($k, $default = null) use ($row) {
return array_key_exists($k, $row) ? $row[$k] : $default;
};
// فك التشفير عند الحاجة وبشكل آمن
$dec = function($v) use ($encryptionHelper) {
if ($v === null || $v === '') return $v;
try { return $encryptionHelper->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");
}

View File

@@ -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");
// }
// }
<?php
require_once __DIR__ . '/connect.php';
// Get the image file from the request.
$image_file = $_FILES['image'];
$driverID = filterRequest("driver_id");
// Check if the image file was uploaded successfully.
if ($image_file['error'] != UPLOAD_ERR_OK) {
echo json_encode(array('status' => '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'));
}
}
?>

View File

View File

View File

View File

@@ -0,0 +1,25 @@
<?php
require_once __DIR__ . '/../../connect.php';
$amount = filterRequest("amount");
$paymentMethod = filterRequest("payment_method");
$driverID = filterRequest("driverID");
$sql = "INSERT INTO `paymentsDriverPoints` (`amount`, `payment_method`, `driverID`)
VALUES ('$amount', '$paymentMethod', '$driverID')";
$stmt = $con->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);
}
?>

View File

@@ -0,0 +1,18 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
$sql = "DELETE FROM `paymentsDriverPoints` WHERE `id` = '$id'";
$stmt = $con->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";
}
?>

View File

View File

@@ -0,0 +1,20 @@
<?php
require_once __DIR__ . '/../../connect.php';
$sql = "SELECT `id`, `amount`, `payment_method`, `driverID`, `created_at`, `updated_at`
FROM `paymentsDriverPoints`";
$stmt = $con->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.";
}
?>

View File

@@ -0,0 +1,22 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
$amount = filterRequest("amount");
$paymentMethod = filterRequest("paymentMethod");
$driverID = filterRequest("driverID");
$sql = "UPDATE `paymentsDriverPoints` SET `amount` = '$amount', `payment_method` = '$paymentMethod',
`driverID` = '$driverID' WHERE `id` = '$id'";
$stmt = $con->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";
}
?>

58
ride/driverWallet/add.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
// Include the database connection file
require_once __DIR__ . '/../../connect.php';
// Get the request parameters
$driverID = filterRequest("driverID");
$paymentID = filterRequest("paymentID");
$amount = filterRequest("amount");
$paymentMethod = filterRequest("paymentMethod");
$token = filterRequest("token");
// Retrieve token details from the database
$stmt = $con->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");
}

View File

@@ -0,0 +1,49 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
$amount = filterRequest("amount");
// Check if required fields are present
if ($driverID === null || $amount === null) {
jsonError("Missing required fields: driverID and amount must be provided");
exit;
}
// Generate a more secure token
$token = generateSecureToken($driverID, $amount);
// Store the token in the database
$stmt = $con->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);
}

View File

View File

@@ -0,0 +1,46 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
$sql = "SELECT
YEAR(`driver_orders`.`created_at`) AS `year`,
MONTH(`driver_orders`.`created_at`) AS `month`,
COUNT(*) AS `total_orders`,
SUM(CASE WHEN `ride`.`status` = 'Finished' THEN 1 ELSE 0 END) AS `completed_orders`,
SUM(CASE WHEN `ride`.`status` = 'Apply' THEN 1 ELSE 0 END) AS `pending_orders`,
SUM(CASE WHEN `ride`.`status` = 'Cancel' THEN 1 ELSE 0 END) AS `canceled_orders`,
ROUND(SUM(CASE WHEN `ride`.`status` = 'Finished' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_completed`,
ROUND(SUM(CASE WHEN `ride`.`status` = 'Apply' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_pending`,
ROUND(SUM(CASE WHEN `ride`.`status` = 'Cancel' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_canceled`,
SUM(CASE WHEN `ride`.`status` = 'Refused' THEN 1 ELSE 0 END) AS `rejected_orders`,
ROUND(SUM(CASE WHEN `ride`.`status` = 'Refused' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS `percent_rejected`
FROM
`driver_orders`
LEFT JOIN `ride` ON `ride`.`id` = `driver_orders`.`order_id`
WHERE
`driver_orders`.`driver_id` = '$driverID'
AND YEAR(`driver_orders`.`created_at`) = YEAR(CURDATE())
AND MONTH(`driver_orders`.`created_at`) = MONTH(CURDATE())
GROUP BY
YEAR(`driver_orders`.`created_at`),
MONTH(`driver_orders`.`created_at`)
ORDER BY
`year`,
`month`;
";
$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");
}
?>

View File

42
ride/driverWallet/get.php Normal file
View File

@@ -0,0 +1,42 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
$sql = "SELECT
COALESCE(dw.id, 0) AS id,
COALESCE(dw.driverID, '0') AS driverID,
COALESCE(dw.paymentID, '0') AS paymentID,
COALESCE(dw.dateCreated, '1970-01-01 00:00:00') AS dateCreated,
COALESCE(dw.amount, 0) AS amount,
COALESCE(dw.paymentMethod, '0') AS paymentMethod,
COALESCE(dw.dateUpdated, '1970-01-01 00:00:00') AS dateUpdated,
COALESCE((SELECT SUM(amount) FROM driverWallet WHERE driverID = '$driverID'), 0) AS total_amount
FROM
driverWallet dw
WHERE
dw.driverID = '$driverID'
GROUP BY
dw.id,
dw.driverID,
dw.paymentID,
dw.dateCreated,
dw.amount,
dw.paymentMethod,
dw.dateUpdated
";
$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");
}
?>

View File

@@ -0,0 +1,34 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driver_phone = filterRequest("driver_phone");
$sql = "SELECT
`driverToken`.`token`,
`driver`.`id`,
`driver`.`phone`,
`driver`.`name_arabic`as name,
driver.national_number
FROM
`driverToken`
LEFT JOIN `driver` ON `driver`.`id` = `driverToken`.`captain_id`
WHERE
`driver`.`phone` = '$driver_phone'";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,37 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
$sql = "SELECT
`id`,
`driverID`,
`paymentID`,
`dateCreated`,
`amount`,
`paymentMethod`,
`dateUpdated`,
(SELECT SUM(`amount`)
FROM `driverWallet`
WHERE `driverID` = '$driverID'
AND `dateCreated` >= 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");
}
?>

View File

@@ -0,0 +1,30 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
$sql = "SELECT
paymentsDriverPoints.`id`,
paymentsDriverPoints.amount,
paymentsDriverPoints.created_at
FROM
`paymentsDriverPoints`
WHERE
paymentsDriverPoints.driverID = '$driverID' AND paymentsDriverPoints.created_at >= 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");
}
?>

View File

@@ -0,0 +1,122 @@
<?php
// Connect to database
require_once __DIR__ . '/../../connect.php';
// Get trip details
$driverName = filterRequest('name');
$driverEmail = filterRequest('email');
$driverPhone = filterRequest('phone');
$amount = filterRequest('amount');
$newDriverName = filterRequest('newDriver');
$newEmail=filterRequest('newEmail');
// Get language preference from database or user input
$language = 'en'; // Default to English
// Email content
if ($language === 'ar') {
$bodyEmail = "<html>
<head>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f8fa;
color: #14171a;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: white;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #1da1f2;
margin-top: 0;
}
p {
line-height: 1.5;
}
a {
color: #1da1f2;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class='container'>
<h1>تفاصيل نقلك على سفر</h1>
<p>شكراً لاستخدام خدمتنا. نتمنى لك يوماً رائعاً!</p>
<p>نريد إعلامك أن مبلغ $amount تم نقله من حسابك إلى السائق الجديد، $newDriverName (هاتف: $driverPhone).</p>
<p>مع خالص التحية،<br> فريق سفر</p>
</div>
</body>
</html>";
} else {
$bodyEmail = "<html>
<head>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f8fa;
color: #14171a;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: white;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #1da1f2;
margin-top: 0;
}
p {
line-height: 1.5;
}
a {
color: #1da1f2;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class='container'>
<img src='https://lh3.googleusercontent.com/a/ACg8ocLe5TgvmTjoFx7KjIoWGxX0G2ryKBTzUZi2-mBYb9DI1dsKQ0WEYh5ZPdnA3WeFbp9VnaTNzJuA0w8S4RiQ7042AKrOwXo3=s576-c-no' alt='SEFER App Logo' style='width: 150px; margin: 20px auto; display: block;'>
<h1>Your SEFER Transfer Details</h1>
<p>Thank you for using our service. We hope you have a great day!</p>
<p>We want to inform you that an amount of $amount has been transferred from your account to the new driver: $newDriverName (Phone: $driverPhone).</p>
<p>Regards,<br> SEFER Team</p>
</div>
</body>
</html>";
}
// 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";
}

View File

View File

@@ -0,0 +1,40 @@
<?php
require_once __DIR__ . '/../../connect.php';
try {
$driver_id = filterRequest("driver_id");
// ✅ أولاً: حساب متوسط السلوك لجميع الرحلات
$sql_average = "SELECT COALESCE(AVG(behavior_score), 100) AS overall_behavior_score
FROM driver_behavior
WHERE driver_id = :driver_id";
$stmt_avg = $con->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());
}
?>

38
ride/driver_order/add.php Executable file
View File

@@ -0,0 +1,38 @@
<?php
require_once __DIR__ . '/../../connect.php';
// استقبال المتغيرات
$driver_id = filterRequest("driver_id");
$order_id = filterRequest("order_id");
$status = filterRequest("status");
// التحقق من وجود order_id مسبقًا
$checkSql = "SELECT `order_id` FROM `driver_orders` WHERE `order_id` = ?";
$checkStmt = $con->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");
}
}
?>

View File

View File

75
ride/driver_order/get.php Executable file
View File

@@ -0,0 +1,75 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driver_id = filterRequest("driver_id");
$order_id = filterRequest("order_id");
if ($driver_id != null) {
// 1. First, get the statistics for the driver
$stats_sql = "
SELECT
COUNT(*) AS total_rides,
SUM(CASE WHEN status = 'Apply' THEN 1 ELSE 0 END) AS total_applied,
SUM(CASE WHEN status = 'Refused' THEN 1 ELSE 0 END) AS total_refused
FROM driver_orders
WHERE
driver_id = :driver_id
AND MONTH(created_at) = MONTH(CURRENT_DATE())
AND YEAR(created_at) = YEAR(CURRENT_DATE())
";
$stats_stmt = $con->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");
}
?>

View File

@@ -0,0 +1,25 @@
<?php
require_once __DIR__ . '/../../connect.php';
$order_id = filterRequest("order_id");
$sql = "SELECT `id`, `driver_id`, `order_id`, `created_at`, `status` FROM `driver_orders` WHERE `order_id` = :order_id";
$stmt = $con->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"
]);
}
?>

View File

@@ -0,0 +1,32 @@
<?php
require_once __DIR__ . '/../../connect.php';
// استقبال المتغيرات
$order_id = filterRequest("order_id");
$status = filterRequest("status");
$notes = filterRequest("notes");
// ---------------------------------------------------------
// التحقق من الملاحظات: إذا كانت فارغة نضع قيمة افتراضية
// ---------------------------------------------------------
if (empty($notes)) {
$notes = "Nothing"; // أو يمكنك كتابة "لا توجد ملاحظات"
}
// تصحيح جملة SQL: يجب استخدام الفاصلة (,) للفصل بين الحقول وليس (and)
$sql = "UPDATE `driver_orders` SET `status` = :status, `notes` = :notes WHERE `order_id` = :order_id";
$stmt = $con->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"); // أو لم يحدث تغيير في البيانات
}
?>

49
ride/driver_scam/add.php Normal file
View File

@@ -0,0 +1,49 @@
<?php
require_once __DIR__ . '/../../connect.php';
// استقبال البيانات
$driverID = filterRequest("driverID");
$passengerID = filterRequest("passengerID");
$rideID = filterRequest("rideID");
$isDriverCallPassenger = filterRequest("isDriverCallPassenger");
// If the value is missing or empty, force it to '0' (False)
if ($isDriverCallPassenger === null || $isDriverCallPassenger === "") {
$isDriverCallPassenger = "0";
}
// استخدام التاريخ الحالي
$dateCreated = date("Y-m-d H:i:s");
// تجهيز الاستعلام الآمن
$sql = "INSERT INTO `driver_ride_scam` (
`driverID`,
`passengerID`,
`rideID`,
`isDriverCallPassenger`,
`dateCreated`
) VALUES (
:driverID,
:passengerID,
:rideID,
:isDriverCallPassenger,
:dateCreated
)";
$stmt = $con->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");
}
?>

View File

View File

48
ride/driver_scam/get.php Executable file
View File

@@ -0,0 +1,48 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
// Safety check: ensure driverID is not empty to prevent SQL errors
if (!$driverID) {
jsonError("Driver ID is required");
exit();
}
$sql = "SELECT
DATE(driver_ride_scam.dateCreated) AS date,
CAST(COUNT(driver_ride_scam.id) AS CHAR) AS count
FROM
driver_ride_scam
LEFT JOIN
ride ON ride.id = driver_ride_scam.rideID
AND ride.status = 'Cancel'
WHERE
driver_ride_scam.driverID = :driverID
AND driver_ride_scam.dateCreated >= 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());
}
?>

View File

40
ride/egyptPhones/add.php Normal file
View File

@@ -0,0 +1,40 @@
<?php
require_once __DIR__ . '/../../connect.php';
// Get the values from the request
$phones = filterRequest("phones");
$name = filterRequest("name");
$phones2 = filterRequest("phones2");
// Check if required fields are provided
if (empty($phones)) {
jsonError($message = "Phone number is required.");
exit();
}
// Prepare the SQL query to insert data into contactEgypt
$sql = "INSERT INTO `contactEgypt`(`phones`, `name`, `phones2`) VALUES (
:phones,
:name,
:phones2
)";
$stmt = $con->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());
}
?>

View File

0
ride/egyptPhones/get.php Normal file
View File

37
ride/egyptPhones/syrianAdd.php Executable file
View File

@@ -0,0 +1,37 @@
<?php
require_once __DIR__ . '/../../connect.php'; // تأكد من أن هذا المسار صحيح
// --- استقبال البيانات من التطبيق ---
$driverId = filterRequest("driverId");
$name = filterRequest("name");
$phone = filterRequest("phone");
// --- التحقق من وجود البيانات الضرورية ---
if (empty($driverId) || empty($phone)) {
jsonError("Driver ID and Phone number are required.");
exit();
}
// --- إعداد استعلام SQL ---
// نستخدم "INSERT IGNORE" لتجنب إدخال سجلات مكررة بناءً على المفتاح الفريد (driverId, phone)
// إذا كان السجل موجوداً مسبقاً، سيتجاهله الاستعلام ببساطة
$sql = "INSERT IGNORE INTO `contactSyria`(`driverId`, `name`, `phone`) VALUES (:driverId, :name, :phone)";
$stmt = $con->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());
}
?>

35
ride/feedBack/add.php Executable file
View File

@@ -0,0 +1,35 @@
<?php
require_once __DIR__ . '/../../connect.php';
$passengerId = filterRequest("passengerId");
$feedBack = filterRequest("feedBack");
$feedBack = $encryptionHelper->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"
]);
}
?>

286
ride/feedBack/add_solve_all.php Executable file
View File

@@ -0,0 +1,286 @@
<?php
// --- معالجة الشكوى من جهة الخادم (Backend) ---
// 1. تضمين ملف الاتصال والدوال المساعدة
// ! تأكد من أن هذا المسار صحيح بالنسبة لهيكل مشروعك
require_once __DIR__ . '/../../connect.php';
// --- إعدادات النظام ---
$geminiApiKey = getenv("GEMINI_API_KEY");
$customerServiceWhatsapp = getenv("SERVICE_PHONE1"); // يُفترض أن هذا مُعرّف في connect.php أو متغيرات البيئة
// التحقق من وجود مفتاح Gemini API
if (!$geminiApiKey) {
error_log("CRITICAL: Gemini API Key is not configured on the server."); // ⚠️ تسجيل الخطأ
jsonError("Gemini API Key is not configured on the server.");
exit;
}
// --- 2. استقبال البيانات والتحقق منها ---
$rideId = filterRequest("ride_id");
$complaintText = filterRequest("complaint_text");
$audioLink = filterRequest("audio_link");
if (empty($rideId)) {
error_log("WARNING: Complaint request failed. Ride ID is missing."); // ⚠️ تسجيل الخطأ
jsonError("Ride ID is required.");
exit;
}
// --- 3. جلب البيانات المفصلة من قاعدة البيانات ---
global $con, $encryptionHelper; // تم افتراض أن هذه المتغيرات global ومتاحة في هذا النطاق
// جلب تفاصيل الرحلة الأساسية والتحقق من حالتها
$stmt = $con->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']
]);
?>

0
ride/feedBack/delete.php Normal file
View File

0
ride/feedBack/error_log Normal file
View File

65
ride/feedBack/get.php Executable file
View File

@@ -0,0 +1,65 @@
<?php
require_once __DIR__ . '/../../connect.php';
$passengerId = filterRequest("passengerId");
$sql = "SELECT
r.id AS id,
r.start_location,
r.end_location,
r.date,
r.price,
r.status,
r.paymentMethod,
r.distance,
r.carType,
r.rideTimeFinish,
r.rideTimeStart,
r.DriverIsGoingToPassenger,
COUNT(rp.id) AS countRateFromPassengerToDrivers,
COUNT(rd.id) AS countRateFromDriverToPassengers,
MAX(rp.rating) AS rateFromPassengerToDriver,
MAX(rd.rating) AS rateFromDriversToPassengers,
MAX(rp.comment) AS commentFromPassengerToDriver,
MAX(rd.comment) AS commentFromDriverToPassenger
FROM
ride r
LEFT JOIN ratingPassenger rp ON
rp.passenger_id = r.passenger_id
LEFT JOIN ratingDriver rd ON
rd.driver_id = r.driver_id
WHERE
r.passenger_id = :passengerId
GROUP BY
r.id,
r.start_location,
r.end_location,
r.date,
r.price,
r.status,
r.paymentMethod,
r.distance,
r.carType,
r.rideTimeFinish,
r.rideTimeStart,
r.DriverIsGoingToPassenger
ORDER BY
r.date
DESC
LIMIT 1;
";
$stmt = $con->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([]);
}
?>

0
ride/feedBack/update.php Normal file
View File

47
ride/firebase/add.php Normal file
View File

@@ -0,0 +1,47 @@
<?php
require_once __DIR__ . '/../../connect.php';
// استقبال المتغيرات
$token = filterRequest("token"); // نص عادي ➜ سيتم تشفيره
$passengerID = filterRequest("passengerID"); // ID عادي
$fingerPrint = filterRequest("fingerPrint"); // مشفّر مسبقًا من Flutter ➜ لا يتم تشفيره هنا
// تشفير التوكن فقط
$tokenEncrypted = $encryptionHelper->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");
}
}
?>

View File

@@ -0,0 +1,46 @@
<?php
require_once __DIR__ . '/../../connect.php';
$token = filterRequest("token"); // نص عادي ➜ سيتم تشفيره
$captain_id = filterRequest("captain_id"); // ID
$fingerPrint = filterRequest("fingerPrint"); // مشفّر مسبقًا من Flutter
// تشفير التوكن فقط
$tokenEncrypted = $encryptionHelper->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");
}
}
?>

47
ride/firebase/addToken.php Executable file
View File

@@ -0,0 +1,47 @@
<?php
require_once __DIR__ . '/../../connect.php';
// استقبال المتغيرات
$token = filterRequest("token"); // نص عادي ➜ سيتم تشفيره
$passengerID = filterRequest("passengerID"); // ID عادي
$fingerPrint = filterRequest("fingerPrint"); // مشفّر مسبقًا من Flutter ➜ لا يتم تشفيره هنا
// تشفير التوكن فقط
$tokenEncrypted = $encryptionHelper->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");
}
}
?>

17
ride/firebase/delete.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
$sql = "DELETE FROM `tokens` WHERE `id` = :id";
$stmt = $con->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");
}
?>

277
ride/firebase/fcm_fun.php Executable file
View File

@@ -0,0 +1,277 @@
<?php
// fcm_functions.php
// مكتبة مركزية لإرسال إشعارات FCM (استدعاء داخلي - بدون HTTP)
// ============================================================================
// دالة Base64 URL-Safe Encoding
// ============================================================================
function base64UrlEncode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
// ============================================================================
// دالة الحصول على Access Token من Google OAuth2
// ============================================================================
function getFCMAccessToken($serviceAccountPath = null) {
if (!$serviceAccountPath) {
$serviceAccountPath = __DIR__ . '/service-account.json';
}
if (!file_exists($serviceAccountPath)) {
error_log("❌ FCM: service-account.json not found at: $serviceAccountPath");
return null;
}
$credentials = json_decode(file_get_contents($serviceAccountPath), 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);
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
]
]);
}
?>

22
ride/firebase/get.php Normal file
View File

@@ -0,0 +1,22 @@
<?php
require_once __DIR__ . '/../../connect.php';
$passengerID = filterRequest("passengerID");
// جلب السجل حسب passengerID
$sql = "SELECT * FROM `tokens` WHERE `passengerID` = :passengerID";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,23 @@
<?php
require_once __DIR__ . '/../../connect.php';
$sql = "SELECT * FROM `driverToken`";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,23 @@
<?php
require_once __DIR__ . '/../../connect.php';
$sql = "SELECT * FROM `tokens`";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,26 @@
<?php
require_once __DIR__ . '/../../connect.php';
$captain_id = filterRequest("captain_id");
$sql = "SELECT * FROM `driverToken` WHERE `captain_id` = :captain_id";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,45 @@
<?php
require_once __DIR__ . '/../../connect.php';
$phone = filterRequest("phone");
// 🔐 تشفير رقم الهاتف قبل البحث (لأنه مشفّر في قاعدة البيانات)
$phoneEncrypted = $encryptionHelper->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");
}
?>

View File

@@ -0,0 +1,22 @@
<?php
require_once __DIR__ . '/../../connect.php';
$passengerID = filterRequest("passengerID");
// جلب السجل حسب passengerID
$sql = "SELECT * FROM `tokens` WHERE `passengerID` = :passengerID";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,41 @@
<?php
// simple_fcm_test.php
// تجربة إرسال إشعار بسيط جداً (بدون قاعدة بيانات)
header('Content-Type: text/plain; charset=utf-8');
// 1. تضمين ملف الدوال (الذي يحتوي على sendFCM_Internal)
if (file_exists("../../functions.php")) {
include "../../functions.php";
} else {
die("❌ Error: functions.php not found!");
}
// =================================================================
// 🟢🟢 ضع التوكن الخاص بك هنا (بين علامات التنصيص) 🟢🟢
// =================================================================
$myToken = "dd35hHkHSOirLLu8luXGKz:APA91bHiW-HpEFMLAZB8nDKV5cT3IplNOYNSbQeIyieZ1KaEkjM1CjeQ8CY9JQcCNqdC8StoUAQGpn-birQiZz1xSndLObXox6O52bxgsUV_dCzr-7BOoR8";
// =================================================================
if ($myToken == "PASTE_YOUR_TOKEN_HERE") {
die("⚠️ الرجاء وضع التوكن الخاص بك داخل ملف السكريبت في السطر 15");
}
//echo "🚀 جاري إرسال الإشعار...\n";
//echo "إلى: " . substr($myToken, 0, 20) . "...\n\n";
// 2. استدعاء دالة الإرسال
$result = sendFCM_Internal(
$myToken, // الهدف
"تنبيه تجريبي 🔔", // العنوان
"أنا وصلت للموقع 📍", // الرسالة (كما طلبت)
['type' => 'test'], // بيانات إضافية بسيطة
"General" // التصنيف
);
// 3. طباعة النتيجة
//echo "النتيجة:\n";
print_r($result);
?>

171
ride/firebase/send_fcm.php Executable file
View File

@@ -0,0 +1,171 @@
<?php
// send_fcm.php - FCM HTTP v1 Sender
header('Content-Type: application/json; charset=utf-8');
$serviceAccountFile = __DIR__ . '/service-account.json';
// السماح فقط بـ POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['status' => '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);
}
?>

19
ride/helpCenter/add.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
$helpQuestion = filterRequest("helpQuestion");
$sql = "INSERT INTO `helpCenter` (`driverID`, `helpQuestion`) VALUES (:driverID, :helpQuestion)";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,17 @@
<?php
require_once __DIR__ . '/../../connect.php';
$helpID = filterRequest("id");
$sql = "DELETE FROM `helpCenter` WHERE `id` = :id";
$stmt = $con->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");
}
?>

View File

28
ride/helpCenter/get.php Normal file
View File

@@ -0,0 +1,28 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
$sql = "SELECT
`id`,
`driverID`,
`helpQuestion`,
`datecreated`
FROM
`helpCenter`
WHERE
`driverID` = :driverID
ORDER BY
`datecreated` DESC";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,18 @@
<?php
require_once __DIR__ . '/../../connect.php';
$helpID = filterRequest("id");
$sql = "SELECT * FROM `helpCenter` WHERE `id` = :id";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,19 @@
<?php
require_once __DIR__ . '/../../connect.php';
$helpID = filterRequest("id");
$newHelpQuestion = filterRequest("newHelpQuestion");
$sql = "UPDATE `helpCenter` SET `helpQuestion` = :helpQuestion WHERE `id` = :id";
$stmt = $con->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");
}
?>

89
ride/invitor/add.php Executable file
View File

@@ -0,0 +1,89 @@
<?php
require_once __DIR__ . '/../../connect.php';
function generateUniqueCode($con, $length = 7) {
while (true) {
$letters = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 4);
$numbers = substr(str_shuffle("0123456789"), 0, 3);
$code = $letters . $numbers;
$stmt = $con->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());
}
}
?>

View File

@@ -0,0 +1,97 @@
<?php
require_once __DIR__ . '/../../connect.php';
function generateUniqueCode($con, $length = 7) {
while (true) {
$letters = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 4);
$numbers = substr(str_shuffle("0123456789"), 0, 3);
$code = $letters . $numbers;
$stmt = $con->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());
}
}
?>

0
ride/invitor/error_log Normal file
View File

52
ride/invitor/get.php Normal file
View File

@@ -0,0 +1,52 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverId = filterRequest("driverId");
$sql = "SELECT
i.`id`,
i.`driverId`,
i.`inviterDriverPhone`,
i.`createdAt`,
i.`isInstall`,
d.`id` AS driverInviterId,
d.`phone` AS invitorPhone,
d.`name_arabic` AS invitorName,
COALESCE(r.finishedTrips, 0) AS countOfInvitDriver
FROM
`invites` i
LEFT JOIN `driver` d ON d.phone = i.inviterDriverPhone
LEFT JOIN (
SELECT
driver_id,
COUNT(*) AS finishedTrips
FROM
ride
WHERE
status = 'Finished'
GROUP BY
driver_id
) r ON r.driver_id = d.id
WHERE
i.driverId = :driverId
AND i.isInstall = 1";
$stmt = $con->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.");
}
?>

View File

@@ -0,0 +1,48 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverId = filterRequest("driverId");
$sql = "SELECT
i.`id`,
i.`driverId`,
i.inviterPassengerPhone,
i.`createdAt`,
i.`isInstall`,
p.`id` AS passengerId,
p.first_name AS passengerName,
COALESCE(r.finishedTrips, 0) AS countOfInvitDriver
FROM
invitesToPassengers i
LEFT JOIN `driver` d ON
d.id = i.driverId
LEFT JOIN passengers p ON
p.phone = i.inviterPassengerPhone
LEFT JOIN (
SELECT passenger_id,
COUNT(*) AS finishedTrips
FROM ride
WHERE `status` = 'Finished'
GROUP BY passenger_id
) r ON r.passenger_id = i.passengerID
WHERE
i.driverId = :driverId AND i.isInstall = 1 AND p.id != ''";
$stmt = $con->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.");
}
?>

16
ride/invitor/update.php Normal file
View File

@@ -0,0 +1,16 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
$sql = "UPDATE `invites` SET `isGiftToken` = 1 WHERE `id` = :id";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,59 @@
<?php
require_once __DIR__ . '/../../connect.php';
$inviterDriverPhone = filterRequest("inviterDriverPhone");
if (empty($inviterDriverPhone)) {
jsonError("Invalid or missing inviter phone.");
exit;
}
try {
// تشفير الرقم
$inviterDriverPhoneEncrypted = $encryptionHelper->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());
}
?>

View File

@@ -0,0 +1,44 @@
<?php
require_once __DIR__ . '/../../connect.php';
$inviteCode = filterRequest("inviteCode");
if (empty($inviteCode)) {
jsonError("Invalid or missing invite code.");
exit;
}
try {
$checkSql = "SELECT `id`, `expirationTime`, `driverId` FROM `invites`
WHERE `inviteCode` = :inviteCode
AND `isInstall` = 0
AND `expirationTime` > 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());
}
?>

View File

@@ -0,0 +1,16 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
$sql = "UPDATE `invitesToPassengers` SET `isGiftToken` = 1 WHERE `id` = :id";
$stmt = $con->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");
}
?>

View File

@@ -0,0 +1,48 @@
<?php
require_once __DIR__ . '/../../connect.php';
$inviteCode = filterRequest("inviteCode");
$passengerID = filterRequest("passengerID");
if (empty($inviteCode) || empty($passengerID)) {
jsonError("Invalid or missing invite code or passenger ID.");
exit;
}
// 🔐 تشفير كود الدعوة قبل البحث
$inviteCodeEncrypted = $encryptionHelper->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());
}
?>

45
ride/kazan/add.php Executable file
View File

@@ -0,0 +1,45 @@
<?php
require_once __DIR__ . '/../../connect.php';
$kazan = filterRequest("kazan");
$adminId = filterRequest("adminId");
$latePrice = filterRequest("latePrice");
$heavyPrice = filterRequest("heavyPrice");
$naturePrice = filterRequest("naturePrice");
$comfortPrice = filterRequest("comfortPrice");
$speedPrice = filterRequest("speedPrice");
$deliveryPrice = filterRequest("deliveryPrice");
$freePrice = filterRequest("freePrice");
$country = filterRequest("country");
$fuelPrice = filterRequest("fuelPrice");
// Prepare an SQL statement with placeholders for the values
$sql = "INSERT INTO `kazan`( `country`,`kazan`, `comfortPrice`, `speedPrice`, `deliveryPrice`, `freePrice`, `latePrice`, `heavyPrice`, `adminId`, `naturePrice`, `fuelPrice`) VALUES (:country,:kazan, :comfortPrice, :speedPrice, :deliveryPrice, :freePrice, :latePrice, :heavyPrice, :adminId, :naturePrice,:fuelPrice)";
$stmt = $con->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();
?>

0
ride/kazan/delete.php Normal file
View File

0
ride/kazan/error_log Normal file
View File

18
ride/kazan/get.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
require_once __DIR__ . '/../../connect.php';
$country = filterRequest("country");
$sql = "SELECT * FROM `kazan` WHERE `country` = :country";
$stmt = $con->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");
}
?>

38
ride/kazan/update.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
require_once __DIR__ . '/../../connect.php';
$id = filterRequest("id");
$allowedFields = [
"kazan", "comfortPrice", "speedPrice", "deliveryPrice",
"freePrice", "latePrice", "heavyPrice", "adminId", "createdAt", "naturePrice"
];
$setParts = [];
$params = [];
foreach ($allowedFields as $field) {
if (isset($_POST[$field])) {
$value = filterRequest($field);
$setParts[] = "`$field` = :$field";
$params[":$field"] = $value;
}
}
if (empty($setParts)) {
jsonError("No valid fields to update.");
exit;
}
$sql = "UPDATE `kazan` SET " . implode(", ", $setParts) . " WHERE `id` = :id";
$params[":id"] = $id;
$stmt = $con->prepare($sql);
$stmt->execute($params);
if ($stmt->rowCount() > 0) {
jsonSuccess(null, "Kazan data updated successfully");
} else {
jsonError("Failed to update kazan data");
}
?>

52
ride/license/add.php Normal file
View File

@@ -0,0 +1,52 @@
<?php
require_once __DIR__ . '/../../connect.php';
$driverID = filterRequest("driverID");
$name = filterRequest("name");
$licenseClass = filterRequest("licenseClass");
$documentNo = filterRequest("documentNo");
$address = filterRequest("address");
$height = filterRequest("height");
$postalCode = filterRequest("postalCode");
$sex = filterRequest("sex");
$stateCode = filterRequest("stateCode");
$expireDate = filterRequest("expireDate");
$dateOfBirth = filterRequest("dateOfBirth");
$sql = "INSERT INTO `lisenceDetails`(`id`,`driverID`, `name`, `licenseClass`, `documentNo`, `address`, `height`, `postalCode`, `sex`, `stateCode`, `expireDate`, `dateOfBirth`) VALUES (
UUID(),
:driverID
:name,
:licenseClass,
:documentNo,
:address,
:height,
:postalCode,
:sex,
:stateCode,
:expireDate,
:dateOfBirth
)";
$stmt = $con->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");
}
?>

0
ride/license/delete.php Normal file
View File

0
ride/license/error_log Normal file
View File

Some files were not shown because too many files have changed in this diff Show More