Initial commit with updated Auth and media ignored
This commit is contained in:
80
ride/RegisrationCar/add.php
Executable file
80
ride/RegisrationCar/add.php
Executable 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.");
|
||||
}
|
||||
0
ride/RegisrationCar/delete.php
Normal file
0
ride/RegisrationCar/delete.php
Normal file
0
ride/RegisrationCar/get.php
Normal file
0
ride/RegisrationCar/get.php
Normal file
29
ride/RegisrationCar/makeDefaultCar.php
Executable file
29
ride/RegisrationCar/makeDefaultCar.php
Executable 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.");
|
||||
}
|
||||
?>
|
||||
125
ride/RegisrationCar/selectDriverAndCarForMishwariTrip.php
Executable file
125
ride/RegisrationCar/selectDriverAndCarForMishwariTrip.php
Executable 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
61
ride/RegisrationCar/update.php
Executable 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
0
ride/apiKey/add.php
Normal file
0
ride/apiKey/delete.php
Normal file
0
ride/apiKey/delete.php
Normal file
0
ride/apiKey/error_log
Normal file
0
ride/apiKey/error_log
Normal file
48
ride/apiKey/get.php
Normal file
48
ride/apiKey/get.php
Normal 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
0
ride/apiKey/update.php
Normal file
25
ride/cancelRide/add.php
Normal file
25
ride/cancelRide/add.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
150
ride/cancelRide/addCancelTripFromDriverAfterApplied.php
Normal file
150
ride/cancelRide/addCancelTripFromDriverAfterApplied.php
Normal 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());
|
||||
}
|
||||
?>
|
||||
?>
|
||||
16
ride/cancelRide/delete.php
Normal file
16
ride/cancelRide/delete.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
0
ride/cancelRide/error_log
Normal file
0
ride/cancelRide/error_log
Normal file
15
ride/cancelRide/get.php
Normal file
15
ride/cancelRide/get.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
52
ride/cancelRide/update.php
Normal file
52
ride/cancelRide/update.php
Normal 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
55
ride/carDrivers/add.php
Executable 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
19
ride/carDrivers/delete.php
Executable 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");
|
||||
}
|
||||
?>
|
||||
0
ride/carDrivers/error_log
Normal file
0
ride/carDrivers/error_log
Normal file
89
ride/carDrivers/get.php
Executable file
89
ride/carDrivers/get.php
Executable 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");
|
||||
}
|
||||
120
ride/card-image-driver/add.php
Normal file
120
ride/card-image-driver/add.php
Normal 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'));
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
0
ride/card-image-driver/delete.php
Normal file
0
ride/card-image-driver/delete.php
Normal file
0
ride/card-image-driver/get.php
Normal file
0
ride/card-image-driver/get.php
Normal file
0
ride/card-image-driver/update.php
Normal file
0
ride/card-image-driver/update.php
Normal file
25
ride/driverPayment/add.php
Normal file
25
ride/driverPayment/add.php
Normal 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);
|
||||
}
|
||||
?>
|
||||
18
ride/driverPayment/delete.php
Normal file
18
ride/driverPayment/delete.php
Normal 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";
|
||||
}
|
||||
?>
|
||||
0
ride/driverPayment/error_log
Normal file
0
ride/driverPayment/error_log
Normal file
20
ride/driverPayment/get.php
Normal file
20
ride/driverPayment/get.php
Normal 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.";
|
||||
}
|
||||
?>
|
||||
22
ride/driverPayment/update.php
Normal file
22
ride/driverPayment/update.php
Normal 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
58
ride/driverWallet/add.php
Normal 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");
|
||||
}
|
||||
49
ride/driverWallet/addPaymentToken.php
Normal file
49
ride/driverWallet/addPaymentToken.php
Normal 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);
|
||||
}
|
||||
0
ride/driverWallet/delete.php
Normal file
0
ride/driverWallet/delete.php
Normal file
46
ride/driverWallet/driverStatistic.php
Normal file
46
ride/driverWallet/driverStatistic.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
0
ride/driverWallet/error_log
Normal file
0
ride/driverWallet/error_log
Normal file
42
ride/driverWallet/get.php
Normal file
42
ride/driverWallet/get.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
34
ride/driverWallet/getDriverDetails.php
Normal file
34
ride/driverWallet/getDriverDetails.php
Normal 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");
|
||||
}
|
||||
|
||||
?>
|
||||
37
ride/driverWallet/getDriverWeekPaymentMove.php
Normal file
37
ride/driverWallet/getDriverWeekPaymentMove.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
30
ride/driverWallet/getWalletByDriver.php
Normal file
30
ride/driverWallet/getWalletByDriver.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
122
ride/driverWallet/sendEmailTransfer.php
Normal file
122
ride/driverWallet/sendEmailTransfer.php
Normal 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";
|
||||
}
|
||||
0
ride/driverWallet/update.php
Normal file
0
ride/driverWallet/update.php
Normal file
40
ride/driver_behavior/get_driver_behavior.php
Normal file
40
ride/driver_behavior/get_driver_behavior.php
Normal 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
38
ride/driver_order/add.php
Executable 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");
|
||||
}
|
||||
}
|
||||
?>
|
||||
0
ride/driver_order/delete.php
Normal file
0
ride/driver_order/delete.php
Normal file
0
ride/driver_order/error_log
Normal file
0
ride/driver_order/error_log
Normal file
75
ride/driver_order/get.php
Executable file
75
ride/driver_order/get.php
Executable 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");
|
||||
}
|
||||
|
||||
?>
|
||||
25
ride/driver_order/getOrderCancelStatus.php
Normal file
25
ride/driver_order/getOrderCancelStatus.php
Normal 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"
|
||||
]);
|
||||
}
|
||||
?>
|
||||
32
ride/driver_order/update.php
Normal file
32
ride/driver_order/update.php
Normal 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
49
ride/driver_scam/add.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
0
ride/driver_scam/delete.php
Normal file
0
ride/driver_scam/delete.php
Normal file
0
ride/driver_scam/error_log
Normal file
0
ride/driver_scam/error_log
Normal file
48
ride/driver_scam/get.php
Executable file
48
ride/driver_scam/get.php
Executable 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());
|
||||
}
|
||||
?>
|
||||
0
ride/driver_scam/update.php
Normal file
0
ride/driver_scam/update.php
Normal file
40
ride/egyptPhones/add.php
Normal file
40
ride/egyptPhones/add.php
Normal 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());
|
||||
}
|
||||
?>
|
||||
0
ride/egyptPhones/error_log
Normal file
0
ride/egyptPhones/error_log
Normal file
0
ride/egyptPhones/get.php
Normal file
0
ride/egyptPhones/get.php
Normal file
37
ride/egyptPhones/syrianAdd.php
Executable file
37
ride/egyptPhones/syrianAdd.php
Executable 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
35
ride/feedBack/add.php
Executable 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
286
ride/feedBack/add_solve_all.php
Executable 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
0
ride/feedBack/delete.php
Normal file
0
ride/feedBack/error_log
Normal file
0
ride/feedBack/error_log
Normal file
65
ride/feedBack/get.php
Executable file
65
ride/feedBack/get.php
Executable 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
0
ride/feedBack/update.php
Normal file
47
ride/firebase/add.php
Normal file
47
ride/firebase/add.php
Normal 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");
|
||||
}
|
||||
}
|
||||
?>
|
||||
46
ride/firebase/addDriver.php
Normal file
46
ride/firebase/addDriver.php
Normal 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
47
ride/firebase/addToken.php
Executable 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
17
ride/firebase/delete.php
Normal 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
277
ride/firebase/fcm_fun.php
Executable 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
22
ride/firebase/get.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
23
ride/firebase/getALlTokenDrivers.php
Executable file
23
ride/firebase/getALlTokenDrivers.php
Executable 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");
|
||||
}
|
||||
?>
|
||||
23
ride/firebase/getAllTokenPassengers.php
Executable file
23
ride/firebase/getAllTokenPassengers.php
Executable 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");
|
||||
}
|
||||
?>
|
||||
26
ride/firebase/getDriverToken.php
Normal file
26
ride/firebase/getDriverToken.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
45
ride/firebase/getTokenParent.php
Normal file
45
ride/firebase/getTokenParent.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
22
ride/firebase/getTokensPassenger.php
Executable file
22
ride/firebase/getTokensPassenger.php
Executable 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");
|
||||
}
|
||||
?>
|
||||
41
ride/firebase/notify_driver_arrival.php
Executable file
41
ride/firebase/notify_driver_arrival.php
Executable 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
171
ride/firebase/send_fcm.php
Executable 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
19
ride/helpCenter/add.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
17
ride/helpCenter/delete.php
Normal file
17
ride/helpCenter/delete.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
0
ride/helpCenter/error_log
Normal file
0
ride/helpCenter/error_log
Normal file
28
ride/helpCenter/get.php
Normal file
28
ride/helpCenter/get.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
18
ride/helpCenter/getById.php
Normal file
18
ride/helpCenter/getById.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
19
ride/helpCenter/update.php
Normal file
19
ride/helpCenter/update.php
Normal 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
89
ride/invitor/add.php
Executable 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());
|
||||
}
|
||||
}
|
||||
?>
|
||||
97
ride/invitor/addInvitationPassenger.php
Executable file
97
ride/invitor/addInvitationPassenger.php
Executable 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
0
ride/invitor/error_log
Normal file
52
ride/invitor/get.php
Normal file
52
ride/invitor/get.php
Normal 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.");
|
||||
}
|
||||
?>
|
||||
48
ride/invitor/getDriverInvitationToPassengers.php
Executable file
48
ride/invitor/getDriverInvitationToPassengers.php
Executable 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
16
ride/invitor/update.php
Normal 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");
|
||||
}
|
||||
?>
|
||||
59
ride/invitor/updateDriverInvitationDirectly.php
Executable file
59
ride/invitor/updateDriverInvitationDirectly.php
Executable 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());
|
||||
}
|
||||
?>
|
||||
44
ride/invitor/updateInvitationCodeFromRegister.php
Executable file
44
ride/invitor/updateInvitationCodeFromRegister.php
Executable 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());
|
||||
}
|
||||
?>
|
||||
16
ride/invitor/updatePassengerGift.php
Executable file
16
ride/invitor/updatePassengerGift.php
Executable 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");
|
||||
}
|
||||
?>
|
||||
48
ride/invitor/updatePassengersInvitation.php
Executable file
48
ride/invitor/updatePassengersInvitation.php
Executable 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
45
ride/kazan/add.php
Executable 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
0
ride/kazan/delete.php
Normal file
0
ride/kazan/error_log
Normal file
0
ride/kazan/error_log
Normal file
18
ride/kazan/get.php
Normal file
18
ride/kazan/get.php
Normal 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
38
ride/kazan/update.php
Normal 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
52
ride/license/add.php
Normal 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
0
ride/license/delete.php
Normal file
0
ride/license/error_log
Normal file
0
ride/license/error_log
Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user