Initial commit with updated Auth and media ignored
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.DS_Store
|
||||
logs/
|
||||
*.log
|
||||
.gemini/
|
||||
portrate_captain_image/
|
||||
0
Admin/AdminCaptain/add.php
Normal file
0
Admin/AdminCaptain/add.php
Normal file
0
Admin/AdminCaptain/delete.php
Normal file
0
Admin/AdminCaptain/delete.php
Normal file
0
Admin/AdminCaptain/error_log
Normal file
0
Admin/AdminCaptain/error_log
Normal file
75
Admin/AdminCaptain/get.php
Normal file
75
Admin/AdminCaptain/get.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$sql = "SELECT
|
||||
`driver`.`id`,
|
||||
`driver`.`phone`,
|
||||
`driver`.`email`,
|
||||
`driver`.`gender`,
|
||||
`driver`.`status`,
|
||||
`driver`.`birthdate`,
|
||||
`driver`.`site`,
|
||||
`driver`.`first_name`,
|
||||
`driver`.`last_name`,
|
||||
`driver`.`employmentType`,
|
||||
`driver`.`maritalStatus`,
|
||||
`driver`.`created_at`,
|
||||
`driver`.`updated_at`,
|
||||
(
|
||||
SELECT COUNT(`driver`.`id`) FROM `driver`
|
||||
) AS countPassenger,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2))
|
||||
FROM `ratingPassenger`
|
||||
WHERE `ratingPassenger`.`driverID` = `driver`.`id`
|
||||
) AS ratingPassenger,
|
||||
(
|
||||
SELECT COUNT(*) FROM `ratingPassenger` WHERE `driverID` = `driver`.`id`
|
||||
) AS countDriverRate,
|
||||
(
|
||||
SELECT COUNT(*) FROM `canecl` WHERE `driverID` = `driver`.`id`
|
||||
) AS countPassengerCancel,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2))
|
||||
FROM `ratingDriver`
|
||||
WHERE `driver_id` = `driver`.`id`
|
||||
) AS passengerAverageRating,
|
||||
(
|
||||
SELECT COUNT(*) FROM `ratingDriver` WHERE `driver_id` = `driver`.`id`
|
||||
) AS countPassengerRate,
|
||||
(
|
||||
SELECT COUNT(*) FROM `ride` WHERE `driver_id` = `driver`.`id`
|
||||
) AS countPassengerRide,
|
||||
(
|
||||
SELECT `token`
|
||||
FROM `driverToken`
|
||||
WHERE `captain_id` = `driver`.`id`
|
||||
LIMIT 1
|
||||
) AS passengerToken
|
||||
FROM `driver`
|
||||
ORDER BY passengerAverageRating DESC
|
||||
LIMIT 10";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// فك تشفير الحقول الحساسة
|
||||
foreach ($result as &$row) {
|
||||
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
||||
$row['email'] = $encryptionHelper->decryptData($row['email']);
|
||||
$row['gender'] = $encryptionHelper->decryptData($row['gender']);
|
||||
$row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']);
|
||||
$row['site'] = $encryptionHelper->decryptData($row['site']);
|
||||
$row['first_name'] = $encryptionHelper->decryptData($row['first_name']);
|
||||
$row['last_name'] = $encryptionHelper->decryptData($row['last_name']);
|
||||
$row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']);
|
||||
$row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']);
|
||||
}
|
||||
|
||||
if (count($result) > 0) {
|
||||
jsonSuccess($result);
|
||||
} else {
|
||||
jsonError("No records found");
|
||||
}
|
||||
?>
|
||||
86
Admin/AdminCaptain/getCaptainDetailsByEmailOrIDOrPhone.php
Normal file
86
Admin/AdminCaptain/getCaptainDetailsByEmailOrIDOrPhone.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$driver_id = filterRequest("driver_id");
|
||||
$driverEmail = $encryptionHelper->encryptData(filterRequest("driverEmail"));
|
||||
$driverPhone = $encryptionHelper->encryptData(filterRequest("driverPhone"));
|
||||
|
||||
$sql = "SELECT
|
||||
`driver`.`id`,
|
||||
`driver`.`phone`,
|
||||
`driver`.`email`,
|
||||
`driver`.`gender`,
|
||||
`driver`.`status`,
|
||||
`driver`.`birthdate`,
|
||||
`driver`.`site`,
|
||||
`driver`.`first_name`,
|
||||
`driver`.`last_name`,
|
||||
`driver`.`education`,
|
||||
`driver`.`employmentType`,
|
||||
`driver`.`maritalStatus`,
|
||||
`driver`.`created_at`,
|
||||
`driver`.`updated_at`,
|
||||
(
|
||||
SELECT COUNT(*) FROM `driver`
|
||||
) AS countPassenger,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2))
|
||||
FROM `ratingPassenger`
|
||||
WHERE `ratingPassenger`.`driverID` = `driver`.`id`
|
||||
) AS ratingPassenger,
|
||||
(
|
||||
SELECT COUNT(*) FROM `ratingPassenger` WHERE `driverID` = `driver`.`id`
|
||||
) AS countDriverRate,
|
||||
(
|
||||
SELECT COUNT(*) FROM `canecl` WHERE `driverID` = `driver`.`id`
|
||||
) AS countPassengerCancel,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2))
|
||||
FROM `ratingDriver`
|
||||
WHERE `driver_id` = `driver`.`id`
|
||||
) AS passengerAverageRating,
|
||||
(
|
||||
SELECT COUNT(*) FROM `ratingDriver` WHERE `driver_id` = `driver`.`id`
|
||||
) AS countPassengerRate,
|
||||
(
|
||||
SELECT COUNT(*) FROM `ride` WHERE `driver_id` = `driver`.`id`
|
||||
) AS countPassengerRide,
|
||||
(
|
||||
SELECT `token`
|
||||
FROM `driverToken`
|
||||
WHERE `captain_id` = `driver`.`id`
|
||||
LIMIT 1
|
||||
) AS passengerToken
|
||||
FROM `driver`
|
||||
WHERE `driver`.`email` = :email OR `driver`.`phone` = :phone OR `driver`.`id` = :id
|
||||
ORDER BY passengerAverageRating DESC
|
||||
LIMIT 10
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(":email", $driverEmail);
|
||||
$stmt->bindParam(":phone", $driverPhone);
|
||||
$stmt->bindParam(":id", $driver_id);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// فك تشفير الحقول الحساسة
|
||||
foreach ($result as &$row) {
|
||||
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
||||
$row['email'] = $encryptionHelper->decryptData($row['email']);
|
||||
$row['gender'] = $encryptionHelper->decryptData($row['gender']);
|
||||
$row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']);
|
||||
$row['site'] = $encryptionHelper->decryptData($row['site']);
|
||||
$row['first_name'] = $encryptionHelper->decryptData($row['first_name']);
|
||||
$row['last_name'] = $encryptionHelper->decryptData($row['last_name']);
|
||||
$row['education'] = $encryptionHelper->decryptData($row['education']);
|
||||
$row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']);
|
||||
$row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']);
|
||||
}
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess($result);
|
||||
} else {
|
||||
jsonError("No records found");
|
||||
}
|
||||
?>
|
||||
87
Admin/AdminCaptain/getCaptainDetailsById.php
Normal file
87
Admin/AdminCaptain/getCaptainDetailsById.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// تشفير driver_id قبل استخدامه في SQL
|
||||
$driver_id = filterRequest("driver_id");
|
||||
|
||||
$sql = "SELECT
|
||||
`driver`.`id`,
|
||||
`driver`.`phone`,
|
||||
`driver`.`email`,
|
||||
`driver`.`gender`,
|
||||
`driver`.`status`,
|
||||
`driver`.`birthdate`,
|
||||
`driver`.`site`,
|
||||
`driver`.`first_name`,
|
||||
`driver`.`last_name`,
|
||||
`driver`.`education`,
|
||||
`driver`.`employmentType`,
|
||||
`driver`.`maritalStatus`,
|
||||
`driver`.`created_at`,
|
||||
`driver`.`updated_at`,
|
||||
(
|
||||
SELECT COUNT(*) FROM `driver`
|
||||
) AS countPassenger,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2))
|
||||
FROM `ratingPassenger`
|
||||
WHERE `ratingPassenger`.`driverID` = `driver`.`id`
|
||||
) AS ratingPassenger,
|
||||
(
|
||||
SELECT COUNT(*) FROM `ratingPassenger`
|
||||
WHERE `ratingPassenger`.`driverID` = `driver`.`id`
|
||||
) AS countDriverRate,
|
||||
(
|
||||
SELECT COUNT(*) FROM `canecl`
|
||||
WHERE `canecl`.`driverID` = `driver`.`id`
|
||||
) AS countPassengerCancel,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2))
|
||||
FROM `ratingDriver`
|
||||
WHERE `ratingDriver`.`driver_id` = `driver`.`id`
|
||||
) AS passengerAverageRating,
|
||||
(
|
||||
SELECT COUNT(*) FROM `ratingDriver`
|
||||
WHERE `ratingDriver`.`driver_id` = `driver`.`id`
|
||||
) AS countPassengerRate,
|
||||
(
|
||||
SELECT COUNT(*) FROM `ride`
|
||||
WHERE `ride`.`driver_id` = `driver`.`id`
|
||||
) AS countPassengerRide,
|
||||
(
|
||||
SELECT `token`
|
||||
FROM `driverToken`
|
||||
WHERE `driverToken`.`captain_id` = `driver`.`id`
|
||||
LIMIT 1
|
||||
) AS passengerToken
|
||||
FROM `driver`
|
||||
WHERE `driver`.`id` = :driver_id
|
||||
ORDER BY passengerAverageRating DESC
|
||||
LIMIT 10";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':driver_id', $driver_id);
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// فك تشفير الحقول الحساسة بعد الجلب
|
||||
foreach ($result as &$row) {
|
||||
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
||||
$row['email'] = $encryptionHelper->decryptData($row['email']);
|
||||
$row['gender'] = $encryptionHelper->decryptData($row['gender']);
|
||||
$row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']);
|
||||
$row['site'] = $encryptionHelper->decryptData($row['site']);
|
||||
$row['first_name'] = $encryptionHelper->decryptData($row['first_name']);
|
||||
$row['last_name'] = $encryptionHelper->decryptData($row['last_name']);
|
||||
$row['education'] = $encryptionHelper->decryptData($row['education']);
|
||||
$row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']);
|
||||
$row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']);
|
||||
}
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess($result);
|
||||
} else {
|
||||
jsonError("No records found");
|
||||
}
|
||||
?>
|
||||
33
Admin/AdminCaptain/getDriversPhonesAndTokens.php
Executable file
33
Admin/AdminCaptain/getDriversPhonesAndTokens.php
Executable file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
d.phone,
|
||||
d.id,
|
||||
d.name_arabic,
|
||||
dt.token
|
||||
FROM
|
||||
`driver` d
|
||||
LEFT JOIN driverToken dt ON
|
||||
dt.captain_id = d.id
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// فك التشفير للحقول الحساسة
|
||||
foreach ($result as &$row) {
|
||||
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
||||
if (!empty($row['token'])) {
|
||||
$row['token'] = $encryptionHelper->decryptData($row['token']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess($result);
|
||||
} else {
|
||||
jsonError("No records found");
|
||||
}
|
||||
?>
|
||||
0
Admin/AdminCaptain/update.php
Normal file
0
Admin/AdminCaptain/update.php
Normal file
79
Admin/AdminRide/get.php
Normal file
79
Admin/AdminRide/get.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$sql = "SELECT
|
||||
(
|
||||
SELECT TIME_FORMAT(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, rideTimeStart, rideTimeFinish))), '%Hh %im')
|
||||
FROM ride
|
||||
WHERE rideTimeStart IS NOT NULL AND rideTimeFinish IS NOT NULL
|
||||
) AS driver_avg_duration,
|
||||
|
||||
(
|
||||
SELECT COUNT(*) FROM (
|
||||
SELECT COUNT(driver_id) FROM ride GROUP BY driver_id
|
||||
) AS sub
|
||||
) AS num_Driver,
|
||||
|
||||
(
|
||||
SELECT COUNT(*) FROM ride
|
||||
) AS total_rides,
|
||||
|
||||
(
|
||||
SELECT COUNT(*) FROM ride WHERE status = 'waiting'
|
||||
) AS ongoing_rides,
|
||||
|
||||
(
|
||||
SELECT COUNT(*) FROM ride WHERE status = 'Finished'
|
||||
) AS completed_rides,
|
||||
|
||||
(
|
||||
SELECT COUNT(*) FROM ride WHERE status = 'cancelled'
|
||||
) AS cancelled_rides,
|
||||
|
||||
(
|
||||
SELECT TIME_FORMAT(SEC_TO_TIME(MAX(TIMESTAMPDIFF(SECOND, rideTimeStart, rideTimeFinish))), '%Hh %im')
|
||||
FROM ride
|
||||
WHERE rideTimeStart IS NOT NULL AND rideTimeFinish IS NOT NULL
|
||||
) AS longest_duration,
|
||||
|
||||
(
|
||||
SELECT ROUND(SUM(distance), 2) FROM ride
|
||||
) AS total_distance,
|
||||
|
||||
(
|
||||
SELECT ROUND(AVG(distance), 2) FROM ride
|
||||
) AS average_distance,
|
||||
|
||||
(
|
||||
SELECT ROUND(MAX(distance), 2) FROM ride
|
||||
) AS longest_distance,
|
||||
|
||||
(
|
||||
SELECT ROUND(SUM(price_for_driver), 2) FROM ride
|
||||
) AS total_driver_earnings,
|
||||
|
||||
(
|
||||
SELECT ROUND(SUM(price_for_passenger), 2) FROM ride
|
||||
) AS total_company_earnings,
|
||||
|
||||
(
|
||||
SELECT ROUND(
|
||||
(SELECT SUM(price_for_passenger) FROM ride) /
|
||||
NULLIF((SELECT SUM(price_for_driver) FROM ride), 0),
|
||||
2
|
||||
)
|
||||
) AS companyPercent
|
||||
|
||||
FROM dual
|
||||
LIMIT 1";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess($result);
|
||||
} else {
|
||||
jsonError("No records found");
|
||||
}
|
||||
?>
|
||||
52
Admin/AdminRide/getRidesPerMonth.php
Normal file
52
Admin/AdminRide/getRidesPerMonth.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$currentYear = date('Y');
|
||||
$currentMonth = date('m');
|
||||
|
||||
// SQL to get daily ride counts
|
||||
$sql = "
|
||||
SELECT
|
||||
YEAR(date) AS year,
|
||||
MONTH(date) AS month,
|
||||
DAY(date) AS day,
|
||||
COUNT(*) AS rides_count
|
||||
FROM
|
||||
ride
|
||||
GROUP BY
|
||||
YEAR(date),
|
||||
MONTH(date),
|
||||
DAY(date)
|
||||
ORDER BY
|
||||
YEAR(date),
|
||||
MONTH(date),
|
||||
DAY(date)
|
||||
";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$dailyRides = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// SQL to get current month's total ride count
|
||||
$sqlMonth = "
|
||||
SELECT COUNT(*) AS current_month_rides_count
|
||||
FROM ride
|
||||
WHERE MONTH(date) = :currentMonth AND YEAR(date) = :currentYear
|
||||
";
|
||||
$stmtMonth = $con->prepare($sqlMonth);
|
||||
$stmtMonth->bindParam(':currentMonth', $currentMonth);
|
||||
$stmtMonth->bindParam(':currentYear', $currentYear);
|
||||
$stmtMonth->execute();
|
||||
$monthRides = $stmtMonth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// Append current month total to each row (if needed)
|
||||
foreach ($dailyRides as &$row) {
|
||||
$row['current_month_rides_count'] = $monthRides['current_month_rides_count'];
|
||||
}
|
||||
|
||||
// Return result
|
||||
if ($dailyRides) {
|
||||
jsonSuccess($dailyRides);
|
||||
} else {
|
||||
jsonError("No records found");
|
||||
}
|
||||
?>
|
||||
25
Admin/adminUser/add.php
Normal file
25
Admin/adminUser/add.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$deviceNumber = filterRequest("deviceNumber"); // Assuming you'll get deviceNumber as input
|
||||
$name = filterRequest("name");
|
||||
|
||||
$sql = "INSERT INTO `adminUser`(`id`, `device_number`, `name`) VALUES (
|
||||
UUID(),
|
||||
:deviceNumber,
|
||||
:name
|
||||
)";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':deviceNumber', $deviceNumber);
|
||||
$stmt->bindParam(':name', $name);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Print a success message
|
||||
jsonSuccess($message = "Admin user data saved successfully");
|
||||
} else {
|
||||
// Print a failure message
|
||||
jsonError($message = "Failed to save admin user data");
|
||||
}
|
||||
?>
|
||||
75
Admin/adminUser/add_invoice.php
Executable file
75
Admin/adminUser/add_invoice.php
Executable file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
// عرض كافة الأخطاء
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$driverID = filterRequest("driverID");
|
||||
$invoiceNumber = filterRequest("invoiceNumber");
|
||||
$amount = filterRequest("amount");
|
||||
$date = filterRequest("date");
|
||||
$name = filterRequest("name");
|
||||
|
||||
$linkImage = null;
|
||||
$uploadDate = date("Y-m-d H:i:s");
|
||||
|
||||
// ✅ طباعة بيانات الإدخال للتأكد
|
||||
error_log("[add_invoice.php] 📥 Data received | driverID: $driverID, invoiceNumber: $invoiceNumber, amount: $amount, date: $date");
|
||||
|
||||
// التحقق من وجود ملف الصورة
|
||||
if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
|
||||
$image_file = $_FILES['image'];
|
||||
$image_name = $image_file['name'];
|
||||
$image_extension = strtolower(pathinfo($image_name, PATHINFO_EXTENSION));
|
||||
$allowed_extensions = ['jpg', 'jpeg', 'png'];
|
||||
|
||||
if (!in_array($image_extension, $allowed_extensions)) {
|
||||
error_log("[add_invoice.php] ❌ Invalid image extension: .$image_extension");
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid file type.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$new_filename = $invoiceNumber . "_" . $driverID . '.' . $image_extension;
|
||||
$target_dir = "invoice_images/";
|
||||
$target_file = $target_dir . $new_filename;
|
||||
|
||||
if (!is_dir($target_dir)) {
|
||||
if (!mkdir($target_dir, 0755, true)) {
|
||||
error_log("[add_invoice.php] ❌ Failed to create directory: $target_dir");
|
||||
}
|
||||
}
|
||||
|
||||
if (!move_uploaded_file($image_file['tmp_name'], $target_file)) {
|
||||
error_log("[add_invoice.php] ❌ Failed to move uploaded file.");
|
||||
echo json_encode(['status' => 'error', 'message' => 'Failed to upload image.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$linkImage = 'https://intaleq.xyz/intaleq/Admin/adminUser/invoice_images/' . $new_filename;
|
||||
error_log("[add_invoice.php] ✅ Image uploaded successfully: $linkImage");
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $con->prepare("INSERT INTO invoice_records (driverID, invoice_number,name, amount, date, image_link, created_at)
|
||||
VALUES (?, ?, ?,?, ?, ?, ?)");
|
||||
$stmt->execute([$driverID, $invoiceNumber,$name, $amount, $date, $linkImage, $uploadDate]);
|
||||
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'message' => 'Invoice data saved.',
|
||||
'image' => $linkImage
|
||||
]);
|
||||
|
||||
error_log("[add_invoice.php] ✅ Invoice saved successfully.");
|
||||
} catch (PDOException $e) {
|
||||
$errorMsg = $e->getMessage();
|
||||
error_log("[add_invoice.php] 🛑 PDO ERROR: $errorMsg");
|
||||
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'message' => "Database error: $errorMsg"
|
||||
]);
|
||||
}
|
||||
0
Admin/adminUser/delete.php
Normal file
0
Admin/adminUser/delete.php
Normal file
0
Admin/adminUser/error_log
Normal file
0
Admin/adminUser/error_log
Normal file
24
Admin/adminUser/get.php
Normal file
24
Admin/adminUser/get.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$device_number = filterRequest("device_number");
|
||||
|
||||
$sql = "SELECT
|
||||
*
|
||||
FROM
|
||||
`adminUser`
|
||||
WHERE
|
||||
`device_number` = '$device_number'";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (count($result) === 1) {
|
||||
// Print the first record as a success message
|
||||
jsonSuccess($result[0]);
|
||||
} else {
|
||||
// Print a failure message
|
||||
jsonError($message = "Failed to retrieve Password or user name incorrect");
|
||||
}
|
||||
?>
|
||||
BIN
Admin/adminUser/invoice_images/INV-20250729-224_123.jpg
Normal file
BIN
Admin/adminUser/invoice_images/INV-20250729-224_123.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
BIN
Admin/adminUser/invoice_images/INV-20250729-592_123.jpg
Normal file
BIN
Admin/adminUser/invoice_images/INV-20250729-592_123.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
BIN
Admin/adminUser/invoice_images/INV-20250810-859_123.jpg
Normal file
BIN
Admin/adminUser/invoice_images/INV-20250810-859_123.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
BIN
Admin/adminUser/invoice_images/INV-20250812-737_123.jpg
Normal file
BIN
Admin/adminUser/invoice_images/INV-20250812-737_123.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 MiB |
28
Admin/adminUser/invoice_total.php
Executable file
28
Admin/adminUser/invoice_total.php
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// ✅ استرجاع كل الفواتير من قاعدة البيانات
|
||||
try {
|
||||
$stmt = $con->prepare("SELECT * FROM invoice_records ORDER BY date DESC");
|
||||
$stmt->execute();
|
||||
$invoices = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// ✅ حساب عدد الفواتير ومجموع المبالغ
|
||||
$count = count($invoices);
|
||||
$totalAmount = array_sum(array_column($invoices, 'amount'));
|
||||
|
||||
echo json_encode([
|
||||
"status" => "success",
|
||||
"data" => $invoices,
|
||||
"summary" => [
|
||||
"count" => $count,
|
||||
"total" => $totalAmount
|
||||
]
|
||||
]);
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Database error: " . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
?>
|
||||
0
Admin/adminUser/update.php
Normal file
0
Admin/adminUser/update.php
Normal file
26
Admin/auth/login.php
Executable file
26
Admin/auth/login.php
Executable file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
//login.php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$device = filterRequest("device_number");
|
||||
$phone = filterRequest("phone_number");
|
||||
|
||||
if (empty($device) || empty($phone)) {
|
||||
jsonError("device_number أو phone_number مفقود");
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $con->prepare("SELECT * FROM adminUser WHERE device_number = ? AND name = ?");
|
||||
$stmt->execute([$device, $phone]);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
$admin = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// يمكن لاحقًا توليد توكن أو بيانات أخرى
|
||||
printSuccess([
|
||||
"message" => "تم التحقق بنجاح",
|
||||
"admin" => $admin,
|
||||
]);
|
||||
} else {
|
||||
jsonError("بيانات الدخول غير صحيحة أو غير مسجلة.");
|
||||
}
|
||||
56
Admin/auth/send_otp_admin.php
Executable file
56
Admin/auth/send_otp_admin.php
Executable file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
// send_otp_admin.php — إرسال رمز التحقق لمسؤول عبر WhatsApp
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
error_log("--- [send_otp_admin] Script started ---");
|
||||
|
||||
// جلب الرقم من الطلب
|
||||
$receiver = filterRequest("receiver");
|
||||
//error_log("[send_otp_admin] Received phone number: " . var_export($receiver, true));
|
||||
|
||||
if (!$receiver) {
|
||||
// error_log("[send_otp_admin] Missing phone number");
|
||||
jsonError("رقم الهاتف مفقود.");
|
||||
exit;
|
||||
}
|
||||
|
||||
// قراءة الأرقام المصرح بها من ENV
|
||||
$allowedPhones = explode(',', getenv('ADMIN_PHONE_NUMBERS'));
|
||||
//error_log("[send_otp_admin] Allowed phones: " . implode(', ', $allowedPhones));
|
||||
|
||||
if (!in_array($receiver, $allowedPhones)) {
|
||||
error_log("[send_otp_admin] Unauthorized phone number attempted: $receiver");
|
||||
jsonError("رقم الهاتف غير مصرح له.");
|
||||
exit;
|
||||
}
|
||||
|
||||
// توليد رمز تحقق عشوائي
|
||||
$otp = rand(10000, 99999);
|
||||
$messageBody = "رمز التحقق الخاص بك للدخول إلى لوحة الإدارة هو: $otp";
|
||||
//error_log("[send_otp_admin] Generated OTP: $otp for $receiver");
|
||||
|
||||
// إرسال الرسالة عبر WhatsApp
|
||||
$success = sendWhatsAppFromServer($receiver, $messageBody);
|
||||
error_log("[send_otp_admin] WhatsApp sending result: " . ($success ? "success" : "failure"));
|
||||
|
||||
if ($success) {
|
||||
try {
|
||||
$stmt = $con->prepare("INSERT INTO token_verification_admin (phone_number, token, expiration_time)
|
||||
VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 5 MINUTE))
|
||||
ON DUPLICATE KEY UPDATE token = VALUES(token), expiration_time = VALUES(expiration_time)");
|
||||
$stmt->execute([$receiver, $otp]);
|
||||
// error_log("[send_otp_admin] OTP saved to database successfully for $receiver");
|
||||
|
||||
jsonSuccess(null, "OTP sent successfully.");
|
||||
} catch (PDOException $e) {
|
||||
// error_log("[send_otp_admin] Database error: " . $e->getMessage());
|
||||
jsonError("حدث خطأ في حفظ الرمز.");
|
||||
}
|
||||
} else {
|
||||
// error_log("[send_otp_admin] Failed to send WhatsApp message to $receiver");
|
||||
jsonError("فشل في إرسال الرمز عبر WhatsApp.");
|
||||
}
|
||||
|
||||
//error_log("--- [send_otp_admin] Script ended ---");
|
||||
?>
|
||||
46
Admin/auth/verify_otp_admin.php
Executable file
46
Admin/auth/verify_otp_admin.php
Executable file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$phone = filterRequest("phone_number");
|
||||
$otp = filterRequest("otp");
|
||||
$deviceNumber = filterRequest("device_number");
|
||||
|
||||
if (empty($phone) || empty($otp)) {
|
||||
jsonError("رقم الهاتف أو رمز التحقق مفقود.");
|
||||
exit;
|
||||
}
|
||||
|
||||
// التحقق من رمز التحقق (OTP)
|
||||
$stmt = $con->prepare("SELECT * FROM token_verification_admin
|
||||
WHERE phone_number = ? AND token = ?
|
||||
AND expiration_time >= NOW()");
|
||||
$stmt->execute([$phone, $otp]);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// ✅ تحقق ناجح - ننتقل إلى إدخال أو تحديث سجل adminUser
|
||||
|
||||
// تحقق إن كان المستخدم موجود مسبقًا
|
||||
$checkAdmin = $con->prepare("SELECT * FROM adminUser WHERE name = ?");
|
||||
$checkAdmin->execute([$phone]);
|
||||
|
||||
$now = date("Y-m-d H:i:s");
|
||||
|
||||
if ($checkAdmin->rowCount() > 0) {
|
||||
// المستخدم موجود ✅ تحديث device_number و updated_at
|
||||
$update = $con->prepare("UPDATE adminUser
|
||||
SET device_number = ?, updated_at = ?
|
||||
WHERE name = ?");
|
||||
$update->execute([$deviceNumber, $now, $phone]);
|
||||
jsonSuccess(["message" => "verified and updated existing admin"]);
|
||||
} else {
|
||||
// المستخدم غير موجود ✅ إدخال جديد
|
||||
$insert = $con->prepare("INSERT INTO adminUser (device_number, name, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?)");
|
||||
$insert->execute([$deviceNumber, $phone, $now, $now]);
|
||||
jsonSuccess(["message" => "verified and new admin created"]);
|
||||
}
|
||||
|
||||
} else {
|
||||
// ❌ رمز التحقق غير صالح
|
||||
jsonError("رمز التحقق غير صالح أو منتهي.");
|
||||
}
|
||||
69
Admin/dashbord.php
Normal file
69
Admin/dashbord.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
-- العدادات العامة
|
||||
(SELECT COUNT(*) FROM passengers) AS countPassengers,
|
||||
(SELECT COUNT(*) FROM driver) AS countDriver,
|
||||
(SELECT COUNT(*) FROM ride) AS countRide,
|
||||
|
||||
-- إحصائيات الشهر الحالي
|
||||
(SELECT COUNT(*) FROM passengers WHERE created_at BETWEEN DATE_FORMAT(CURDATE(), '%Y-%m-01') AND LAST_DAY(CURDATE())) AS countPassengersThisMonth,
|
||||
(SELECT COUNT(*) FROM driver WHERE created_at BETWEEN DATE_FORMAT(CURDATE(), '%Y-%m-01') AND LAST_DAY(CURDATE())) AS countDriverThisMonth,
|
||||
(SELECT COUNT(*) FROM ride WHERE created_at BETWEEN DATE_FORMAT(CURDATE(), '%Y-%m-01') AND LAST_DAY(CURDATE())) AS countRideThisMonth,
|
||||
(SELECT COUNT(*) FROM CarRegistration WHERE created_at BETWEEN DATE_FORMAT(CURDATE(), '%Y-%m-01') AND LAST_DAY(CURDATE())) AS countCarRegistrationThisMonth,
|
||||
|
||||
-- شكاوى
|
||||
(SELECT COUNT(*) FROM complaint WHERE date_filed BETWEEN DATE_FORMAT(CURDATE(), '%Y-%m-01') AND LAST_DAY(CURDATE())) AS countComplaintThisMonth,
|
||||
(SELECT COUNT(*) FROM complaint WHERE date_filed BETWEEN DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) AND DATE_ADD(DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY), INTERVAL 6 DAY)) AS countComplaintThisWeek,
|
||||
(SELECT COUNT(*) FROM complaint WHERE DATE(date_filed) = CURDATE()) AS countComplaintToday,
|
||||
|
||||
-- المحافظ والتحويلات
|
||||
|
||||
-- إحصائيات وقت ومسافة الرحلات
|
||||
(SELECT TIME_FORMAT(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, rideTimeStart, rideTimeFinish))), '%Hh %im') FROM ride WHERE rideTimeStart IS NOT NULL AND rideTimeFinish IS NOT NULL) AS driver_avg_duration,
|
||||
(SELECT MAX(SEC_TO_TIME(TIMESTAMPDIFF(SECOND, rideTimeStart, rideTimeFinish))) FROM ride WHERE rideTimeStart IS NOT NULL AND rideTimeFinish IS NOT NULL) AS longest_duration,
|
||||
(SELECT ROUND(SUM(distance),2) FROM ride) AS total_distance,
|
||||
(SELECT ROUND(AVG(distance),2) FROM ride) AS average_distance,
|
||||
(SELECT ROUND(MAX(distance),2) FROM ride) AS longest_distance,
|
||||
|
||||
-- أرباح السائق والشركة
|
||||
(SELECT SUM(price_for_driver) FROM ride WHERE status = 'Finished') AS total_driver_earnings,
|
||||
(SELECT ROUND(AVG(price_for_passenger),2) FROM ride) AS avg_passenger_price,
|
||||
|
||||
-- توزيع الرحلات حسب الوقت
|
||||
(SELECT COUNT(*) FROM ride WHERE HOUR(created_at) BETWEEN 6 AND 11) AS morning_ride_count,
|
||||
(SELECT COUNT(*) FROM ride WHERE HOUR(created_at) BETWEEN 12 AND 17) AS evening_ride_count,
|
||||
(SELECT COUNT(*) FROM ride WHERE HOUR(created_at) BETWEEN 18 AND 23 OR HOUR(created_at) BETWEEN 0 AND 5) AS night_ride_count,
|
||||
|
||||
-- أنواع الرحلات
|
||||
(SELECT COUNT(*) FROM ride WHERE carType = 'Comfort') AS comfort,
|
||||
(SELECT COUNT(*) FROM ride WHERE carType = 'Speed') AS speed,
|
||||
(SELECT COUNT(*) FROM ride WHERE carType = 'Lady') AS lady,
|
||||
|
||||
-- حالة الرحلات
|
||||
(SELECT COUNT(*) FROM ride WHERE status = 'wait') AS ongoing_rides,
|
||||
(SELECT COUNT(*) FROM ride WHERE status = 'Finished') AS completed_rides,
|
||||
(SELECT COUNT(*) FROM ride WHERE status = 'cancel') AS cancelled_rides,
|
||||
|
||||
-- عدد السائقين الفريدين
|
||||
(SELECT COUNT(*) FROM (SELECT driver_id FROM ride GROUP BY driver_id) AS sub) AS num_Driver,
|
||||
|
||||
-- التحويلات البنكية
|
||||
(SELECT COUNT(*) FROM payments WHERE payment_method = 'TransferFrom') AS transfer_from_count
|
||||
|
||||
FROM passengers
|
||||
LIMIT 1;
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($result) {
|
||||
jsonSuccess($result);
|
||||
} else {
|
||||
jsonError("No dashboard data found");
|
||||
}
|
||||
?>
|
||||
41
Admin/driver/deleteCaptain.php
Executable file
41
Admin/driver/deleteCaptain.php
Executable file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$driver_id = filterRequest("driver_id");
|
||||
$phone = filterRequest("phone");
|
||||
$reason = filterRequest("reason"); // يمكن أن يأتي من البارامتر أو نخليه افتراضي
|
||||
|
||||
if (empty($driver_id) || empty($phone)) {
|
||||
jsonError("Driver ID and phone are required.");
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// تشفير رقم الهاتف
|
||||
$encPhone = $encryptionHelper->encryptData($phone);
|
||||
|
||||
// حذف السائق من جدول driver
|
||||
$sqlDel = "DELETE FROM driver WHERE id = :id";
|
||||
$stmtDel = $con->prepare($sqlDel);
|
||||
$stmtDel->bindParam(':id', $driver_id, PDO::PARAM_INT);
|
||||
$stmtDel->execute();
|
||||
|
||||
if ($stmtDel->rowCount() > 0) {
|
||||
// إضافة بيانات السائق المحذوف إلى البلاك ليست
|
||||
$sqlInsert = "INSERT INTO blacklist_driver (driver_id, phone, reason)
|
||||
VALUES (:driver_id, :phone, :reason)";
|
||||
$stmtInsert = $con->prepare($sqlInsert);
|
||||
$stmtInsert->execute([
|
||||
'driver_id' => $driver_id,
|
||||
'phone' => $encPhone,
|
||||
'reason' => !empty($reason) ? $reason : "Deleted & blacklisted by admin"
|
||||
]);
|
||||
|
||||
jsonSuccess(null, "Driver deleted and blacklisted successfully.");
|
||||
} else {
|
||||
jsonError("No driver found with the provided ID.");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
jsonError("Error: " . $e->getMessage());
|
||||
}
|
||||
30
Admin/driver/deleteRecord.php
Executable file
30
Admin/driver/deleteRecord.php
Executable file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$driver_id = filterRequest("driver_id");
|
||||
|
||||
// Prepare the DELETE query
|
||||
$sql = "DELETE FROM `car_locations` WHERE driver_id = :driver_id";
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// Bind the driver_id parameter
|
||||
$stmt->bindParam(':driver_id', $driver_id, PDO::PARAM_STR);
|
||||
|
||||
try {
|
||||
// Execute the query
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Success response
|
||||
jsonSuccess(null, "Record(s) deleted successfully.");
|
||||
} else {
|
||||
// Failure response: no records found to delete
|
||||
jsonError("No records found for the provided driver ID.");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
// Handle any SQL errors
|
||||
jsonError("Error deleting records: " . $e->getMessage());
|
||||
}
|
||||
|
||||
?>
|
||||
55
Admin/driver/find_driver_by_phone.php
Executable file
55
Admin/driver/find_driver_by_phone.php
Executable file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$phone = filterRequest("phone");
|
||||
|
||||
if (empty($phone)) {
|
||||
jsonError("Phone number is required.");
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// تشفير الرقم المدخل للبحث
|
||||
$encPhone = $encryptionHelper->encryptData($phone);
|
||||
|
||||
// احضار كل الأعمدة باستثناء كلمة المرور
|
||||
$sql = "SELECT *
|
||||
FROM driver
|
||||
WHERE phone = :phone
|
||||
LIMIT 1";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute([':phone' => $encPhone]);
|
||||
|
||||
$driver = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($driver) {
|
||||
// ✅ الحقول المشفرة اللي لازم تنفك:
|
||||
$encryptedFields = [
|
||||
'phone',
|
||||
'email',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'national_number',
|
||||
'address','gender','site',
|
||||
'birthdate',
|
||||
'name_arabic',
|
||||
];
|
||||
|
||||
foreach ($encryptedFields as $field) {
|
||||
if (!empty($driver[$field])) {
|
||||
$driver[$field] = $encryptionHelper->decryptData($driver[$field]);
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ احذف كلمة المرور من النتيجة
|
||||
unset($driver['password']);
|
||||
|
||||
jsonSuccess($driver);
|
||||
|
||||
} else {
|
||||
jsonError("No driver found with this phone.");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
jsonError("Error searching driver: " . $e->getMessage());
|
||||
}
|
||||
48
Admin/driver/getBestDriver.php
Executable file
48
Admin/driver/getBestDriver.php
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$sql = "SELECT
|
||||
COUNT(`car_locations`.driver_id) AS driver_count,
|
||||
driver.id,
|
||||
driver.phone,
|
||||
driver.name_arabic,
|
||||
MAX(dt.token) AS token
|
||||
FROM
|
||||
`car_locations`
|
||||
LEFT JOIN driver ON driver.id = car_locations.driver_id
|
||||
LEFT JOIN driverToken dt ON dt.captain_id = driver.id
|
||||
WHERE
|
||||
`car_locations`.created_at > TIMESTAMP(DATE_SUB(NOW(), INTERVAL 7 DAY))
|
||||
GROUP BY
|
||||
driver.id
|
||||
ORDER BY
|
||||
driver_count DESC
|
||||
LIMIT 19;
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// فك التشفير للحقول الحساسة
|
||||
foreach ($rows as &$row) {
|
||||
if (!empty($row['phone'])) {
|
||||
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
||||
}
|
||||
if (!empty($row['name_arabic'])) {
|
||||
$row['name_arabic'] = $encryptionHelper->decryptData($row['name_arabic']);
|
||||
}
|
||||
if (!empty($row['token'])) {
|
||||
$row['token'] = $encryptionHelper->decryptData($row['token']);
|
||||
}
|
||||
}
|
||||
|
||||
jsonSuccess($rows);
|
||||
} else {
|
||||
jsonError($message = "No recent driver location activity found");
|
||||
}
|
||||
|
||||
?>
|
||||
45
Admin/driver/getDriverGiftPayment.php
Executable file
45
Admin/driver/getDriverGiftPayment.php
Executable file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$phone = filterRequest("phone");
|
||||
|
||||
// Encrypt phone
|
||||
$encphone = $encryptionHelper->encryptData($phone);
|
||||
|
||||
$sql = "SELECT
|
||||
*
|
||||
FROM
|
||||
`driver`
|
||||
WHERE
|
||||
phone = :encPhone";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// FIX 1: Bind AFTER preparing the statement
|
||||
// FIX 2: Use the same placeholder name (:encPhone)
|
||||
$stmt->bindParam(':encPhone', $encphone, PDO::PARAM_STR);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Decrypt sensitive fields
|
||||
foreach ($rows as &$row) {
|
||||
if (!empty($row['phone'])) {
|
||||
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
||||
}
|
||||
if (!empty($row['name_arabic'])) {
|
||||
$row['name_arabic'] = $encryptionHelper->decryptData($row['name_arabic']);
|
||||
}
|
||||
}
|
||||
|
||||
jsonSuccess($rows);
|
||||
|
||||
} else {
|
||||
jsonError("No recent driver location activity found");
|
||||
}
|
||||
|
||||
?>
|
||||
27
Admin/driver/remove_from_blacklist.php
Executable file
27
Admin/driver/remove_from_blacklist.php
Executable file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$phone = filterRequest("phone");
|
||||
|
||||
if (empty($phone)) {
|
||||
jsonError("Phone number is required.");
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// تشفير الرقم للمطابقة مع المخزن
|
||||
$encPhone = $encryptionHelper->encryptData($phone);
|
||||
|
||||
$sql = "DELETE FROM blacklist_driver WHERE phone = :phone";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute([':phone' => $encPhone]);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess(null, "Driver removed from blacklist successfully.");
|
||||
} else {
|
||||
jsonError("No driver found in blacklist with this phone.");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
jsonError("Error removing from blacklist: " . $e->getMessage());
|
||||
}
|
||||
30
Admin/driver/updateDriverFromAdmin.php
Executable file
30
Admin/driver/updateDriverFromAdmin.php
Executable file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$driver_id = filterRequest("id");
|
||||
$phone = filterRequest("phone");
|
||||
|
||||
// تشفير رقم الهاتف
|
||||
$encphone = $encryptionHelper->encryptData($phone);
|
||||
|
||||
$sql = "UPDATE `driver` SET `phone` = :encphone WHERE `id` = :id";
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// Bind values
|
||||
$stmt->bindParam(':encphone', $encphone, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':id', $driver_id, PDO::PARAM_STR);
|
||||
|
||||
try {
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// تم التحديث بنجاح
|
||||
jsonSuccess(null, "Phone updated successfully.");
|
||||
} else {
|
||||
// لم يتم العثور على أي سجل للتحديث
|
||||
jsonError("No records updated. Please check the driver ID.");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
jsonError("Error updating record: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
31
Admin/employee/add.php
Executable file
31
Admin/employee/add.php
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// Get the data from the request
|
||||
$name = filterRequest("name");
|
||||
$education = filterRequest("education");
|
||||
$site = filterRequest("site");
|
||||
$phone = filterRequest("phone");
|
||||
$status = filterRequest("status");
|
||||
$id=filterRequest("id");
|
||||
|
||||
// Set the current timestamp for the 'created_at' field
|
||||
$created_at = date("Y-m-d H:i:s");
|
||||
|
||||
// Prepare the SQL insert query using parameterized statements to avoid SQL injection
|
||||
$sql = "INSERT INTO `employee` (`id`,`name`, `education`, `site`, `phone`, `created_at`, `status`)
|
||||
VALUES (?,?, ?, ?, ?, ?, ?)";
|
||||
|
||||
// Prepare and execute the statement
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute([$id, $name, $education, $site, $phone, $created_at, $status]);
|
||||
|
||||
// Check if the query successfully inserted the record
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// If a row was inserted, print success
|
||||
jsonSuccess($message = "Employee record added successfully");
|
||||
} else {
|
||||
// If no rows were inserted, print failure
|
||||
jsonError($message = "Failed to add employee record");
|
||||
}
|
||||
?>
|
||||
29
Admin/employee/get.php
Executable file
29
Admin/employee/get.php
Executable file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// Prepare the SQL query to select all records from the employee table with a limit of 10
|
||||
$sql = "SELECT
|
||||
*
|
||||
FROM
|
||||
`employee` e
|
||||
ORDER BY
|
||||
e.created_at
|
||||
DESC
|
||||
";
|
||||
|
||||
// Prepare and execute the statement
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
// Fetch all records as an associative array
|
||||
$employee_data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Check if any records were retrieved
|
||||
if ($employee_data) {
|
||||
// If records were found, print the data as JSON
|
||||
jsonSuccess($data = $employee_data);
|
||||
} else {
|
||||
// If no records were found, print a failure message
|
||||
jsonError($message = "No employee records found");
|
||||
}
|
||||
?>
|
||||
18
Admin/error/error_list_last20.php
Executable file
18
Admin/error/error_list_last20.php
Executable file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
// File: /v1/admin/error/error_list_last20.php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
try {
|
||||
$sql = "SELECT `id`, `error`, `userId`, `userType`, `phone`, `created_at`, `device`, `details`, `status`
|
||||
FROM `error`
|
||||
ORDER BY `created_at` DESC
|
||||
LIMIT 20";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
jsonSuccess($rows);
|
||||
} catch (Exception $e) {
|
||||
error_log("error_list_last20.php: " . $e->getMessage());
|
||||
jsonError($message = "Failed to fetch last 20 errors");
|
||||
}
|
||||
32
Admin/error/error_search_by_phone.php
Executable file
32
Admin/error/error_search_by_phone.php
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// File: /v1/admin/error/error_search_by_phone.php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
try {
|
||||
$phone = filterRequest("phone");
|
||||
if ($phone === false || $phone === null || trim($phone) === "") {
|
||||
jsonError("Phone is required");
|
||||
exit;
|
||||
}
|
||||
|
||||
// في حال مخزّن الهاتف مشفّر، طبق نفس دالتك للتشفير هنا:
|
||||
// $enc_phone = $encryptionHelper->encryptData(trim($phone));
|
||||
// ثم بدّل الحقل في WHERE إلى phone = :ph
|
||||
$sql = "SELECT `id`, `error`, `userId`, `userType`, `phone`, `created_at`, `device`, `details`, `status`
|
||||
FROM `error`
|
||||
WHERE `phone` = :ph OR `phone` LIKE :phLike
|
||||
ORDER BY `created_at` DESC
|
||||
LIMIT 20";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute([
|
||||
":ph" => trim($phone),
|
||||
":phLike" => '%' . trim($phone) . '%', // يسمح بجزء من الرقم إن أردت
|
||||
]);
|
||||
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
jsonSuccess($rows);
|
||||
} catch (Exception $e) {
|
||||
error_log("error_search_by_phone.php: " . $e->getMessage());
|
||||
jsonError($message = "Failed to search errors by phone");
|
||||
}
|
||||
40
Admin/errorApp.php
Executable file
40
Admin/errorApp.php
Executable file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
// استلام البيانات من الطلب
|
||||
$error = filterRequest("error");
|
||||
$userId = filterRequest("userId");
|
||||
$userType = filterRequest("userType");
|
||||
$phone = filterRequest("phone");
|
||||
$device = filterRequest("device");
|
||||
$details = filterRequest("details");
|
||||
|
||||
// تسجيل الخطأ في ملف logs/app.log للمتابعة السريعة
|
||||
$logMsg = "[$userType ID: $userId] Error: $error | Where: $device | Details: $details";
|
||||
appLog($logMsg, "APP_ERROR");
|
||||
|
||||
// جملة SQL لإدخال البيانات، مع إضافة الحقل الجديد
|
||||
// لاحظ أننا لا نرسل حقل 'status' لأنه سيأخذ القيمة الافتراضية 'new' تلقائياً في قاعدة البيانات
|
||||
$sql = "INSERT INTO `error` (`error`, `userId`, `userType`, `phone`, `device`, `details`)
|
||||
VALUES (:error, :userId, :userType, :phone, :device, :details)";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// ربط المتغيرات بالقيم
|
||||
$stmt->bindParam(':error', $error);
|
||||
$stmt->bindParam(':userId', $userId);
|
||||
$stmt->bindParam(':userType', $userType);
|
||||
$stmt->bindParam(':phone', $phone);
|
||||
$stmt->bindParam(':device', $device);
|
||||
$stmt->bindParam(':details', $details); // <-- ربط المتغير الجديد
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// طباعة رسالة نجاح مع تفاصيل الخطأ لسهولة التتبع في الكونسول
|
||||
jsonSuccess($error);
|
||||
} else {
|
||||
// طباعة رسالة فشل
|
||||
jsonError("Failed to save error data");
|
||||
}
|
||||
?>
|
||||
0
Admin/error_log
Normal file
0
Admin/error_log
Normal file
37
Admin/facebook.php
Executable file
37
Admin/facebook.php
Executable file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
require_once 'vendor/autoload.php'; // Include the Composer autoloader
|
||||
|
||||
use Facebook\Facebook;
|
||||
|
||||
$appId = '$appId'; // Replace with your App ID
|
||||
$appSecret = '$appSecret'; // Replace with your App Secret
|
||||
$accessToken = '$accessToken'; // Replace with the token you want to debug
|
||||
|
||||
$fb = new Facebook([
|
||||
'app_id' => $appId,
|
||||
'app_secret' => $appSecret,
|
||||
'default_graph_version' => 'v16.0', // Adjust based on your API version
|
||||
]);
|
||||
|
||||
try {
|
||||
// Generate the app token
|
||||
$appToken = $appId . '|' . $appSecret;
|
||||
|
||||
// Debug the token
|
||||
$response = $fb->get('/debug_token?input_token=' . $accessToken, $appToken);
|
||||
$tokenData = $response->getDecodedBody();
|
||||
|
||||
// Display the token details
|
||||
echo "Token Data:\n";
|
||||
print_r($tokenData);
|
||||
|
||||
if (isset($tokenData['data']['expires_at'])) {
|
||||
echo "Expires At: " . date('Y-m-d H:i:s', $tokenData['data']['expires_at']) . "\n";
|
||||
} else {
|
||||
echo "The token does not have an expiration time.\n";
|
||||
}
|
||||
} catch (Facebook\Exceptions\FacebookResponseException $e) {
|
||||
echo 'Graph API Error: ' . $e->getMessage();
|
||||
} catch (Facebook\Exceptions\FacebookSDKException $e) {
|
||||
echo 'SDK Error: ' . $e->getMessage();
|
||||
}
|
||||
100
Admin/getPassengerDetails.php
Normal file
100
Admin/getPassengerDetails.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
$sql = "SELECT
|
||||
`passengers`.`id`,
|
||||
`passengers`.`phone`,
|
||||
`passengers`.`email`,
|
||||
`passengers`.`gender`,
|
||||
`passengers`.`status`,
|
||||
`passengers`.`birthdate`,
|
||||
`passengers`.`site`,
|
||||
`passengers`.`first_name`,
|
||||
`passengers`.`last_name`,
|
||||
`passengers`.`sosPhone`,
|
||||
`passengers`.`education`,
|
||||
`passengers`.`employmentType`,
|
||||
`passengers`.`maritalStatus`,
|
||||
`passengers`.`created_at`,
|
||||
`passengers`.`updated_at`,
|
||||
(
|
||||
SELECT COUNT(`id`) FROM `passengers`
|
||||
) AS countPassenger,
|
||||
(
|
||||
SELECT COUNT(`id`) FROM `feedBack`
|
||||
) AS countFeedback,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10,2))
|
||||
FROM `ratingPassenger`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS ratingPassenger,
|
||||
(
|
||||
SELECT COUNT(`driverID`)
|
||||
FROM `ratingPassenger`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS countDriverRate,
|
||||
(
|
||||
SELECT COUNT(`passengerID`)
|
||||
FROM `canecl`
|
||||
WHERE `passengerID` = `passengers`.`id`
|
||||
) AS countPassengerCancel,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10,2))
|
||||
FROM `ratingDriver`
|
||||
WHERE `passenger_iD` = `passengers`.`id`
|
||||
) AS passengerAverageRating,
|
||||
(
|
||||
SELECT COUNT(`driver_id`)
|
||||
FROM `ratingDriver`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS countPassengerRate,
|
||||
(
|
||||
SELECT COUNT(`ride`.`passenger_id`)
|
||||
FROM `ride`
|
||||
WHERE `ride`.`passenger_id` = `passengers`.`id`
|
||||
) AS countPassengerRide,
|
||||
(
|
||||
SELECT `token`
|
||||
FROM `tokens`
|
||||
WHERE `tokens`.`passengerID` = `passengers`.`id`
|
||||
) AS passengerToken
|
||||
FROM
|
||||
`passengers`
|
||||
GROUP BY
|
||||
`passengers`.`id`
|
||||
ORDER BY
|
||||
countPassengerRide DESC
|
||||
LIMIT 10";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// ✅ فك التشفير للحقول الحساسة
|
||||
foreach ($result as &$row) {
|
||||
$fieldsToDecrypt = [
|
||||
"phone", "email", "gender", "birthdate", "site",
|
||||
"first_name", "last_name", "sosPhone",
|
||||
"education", "employmentType", "maritalStatus", "passengerToken"
|
||||
];
|
||||
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null) {
|
||||
$decrypted = $encryptionHelper->decryptData($row[$field]);
|
||||
if ($decrypted !== false) {
|
||||
$row[$field] = $decrypted;
|
||||
} else {
|
||||
// سجل أو تجاهل القيم التي فشل فك تشفيرها
|
||||
$row[$field] = null; // أو احتفظ بالقيمة المشفرة
|
||||
error_log("Failed to decrypt field '$field' for passenger ID: " . $row['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess($data = $result);
|
||||
} else {
|
||||
jsonError("No records found");
|
||||
}
|
||||
?>
|
||||
96
Admin/getPassengerDetailsByPassengerID.php
Normal file
96
Admin/getPassengerDetailsByPassengerID.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
$passengerID = filterRequest("passengerID");
|
||||
|
||||
$sql = "SELECT
|
||||
`passengers`.`id`,
|
||||
`passengers`.`phone`,
|
||||
`passengers`.`email`,
|
||||
`passengers`.`gender`,
|
||||
`passengers`.`status`,
|
||||
`passengers`.`birthdate`,
|
||||
`passengers`.`site`,
|
||||
`passengers`.`first_name`,
|
||||
`passengers`.`last_name`,
|
||||
`passengers`.`sosPhone`,
|
||||
`passengers`.`education`,
|
||||
`passengers`.`employmentType`,
|
||||
`passengers`.`maritalStatus`,
|
||||
`passengers`.`created_at`,
|
||||
`passengers`.`updated_at`,
|
||||
(
|
||||
SELECT COUNT(`id`) FROM `passengers`
|
||||
) AS countPassenger,
|
||||
(
|
||||
SELECT COUNT(`id`) FROM `feedBack`
|
||||
) AS countFeedback,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10,2))
|
||||
FROM `ratingPassenger`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS ratingPassenger,
|
||||
(
|
||||
SELECT COUNT(`driverID`)
|
||||
FROM `ratingPassenger`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS countDriverRate,
|
||||
(
|
||||
SELECT COUNT(`passengerID`)
|
||||
FROM `canecl`
|
||||
WHERE `passengerID` = `passengers`.`id`
|
||||
) AS countPassengerCancel,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10,2))
|
||||
FROM `ratingDriver`
|
||||
WHERE `passenger_iD` = `passengers`.`id`
|
||||
) AS passengerAverageRating,
|
||||
(
|
||||
SELECT COUNT(`driver_id`)
|
||||
FROM `ratingDriver`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS countPassengerRate,
|
||||
(
|
||||
SELECT COUNT(`ride`.`passenger_id`)
|
||||
FROM `ride`
|
||||
WHERE `ride`.`passenger_id` = `passengers`.`id`
|
||||
) AS countPassengerRide,
|
||||
(
|
||||
SELECT `token`
|
||||
FROM `tokens`
|
||||
WHERE `tokens`.`passengerID` = `passengers`.`id`
|
||||
) AS passengerToken
|
||||
FROM
|
||||
`passengers`
|
||||
WHERE
|
||||
passengers.id = '$passengerID'
|
||||
GROUP BY
|
||||
`passengers`.`id`
|
||||
ORDER BY
|
||||
countPassengerRide DESC";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// ✅ فك تشفير الحقول الحساسة
|
||||
foreach ($result as &$row) {
|
||||
$fieldsToDecrypt = [
|
||||
"phone", "email", "gender", "birthdate", "site",
|
||||
"first_name", "last_name", "sosPhone",
|
||||
"education", "employmentType", "maritalStatus", "passengerToken"
|
||||
];
|
||||
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null) {
|
||||
$row[$field] = $encryptionHelper->decryptData($row[$field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess($result);
|
||||
} else {
|
||||
jsonError("No records found");
|
||||
}
|
||||
?>
|
||||
91
Admin/getPassengerbyEmail.php
Normal file
91
Admin/getPassengerbyEmail.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
$passengerEmail = $encryptionHelper->encryptData(filterRequest("passengerEmail"));
|
||||
$passengerId = filterRequest("passengerId");
|
||||
$passengerphone = $encryptionHelper->encryptData(filterRequest("passengerphone"));
|
||||
|
||||
$sql = "SELECT
|
||||
`passengers`.`id`,
|
||||
`passengers`.`phone`,
|
||||
`passengers`.`email`,
|
||||
`passengers`.`gender`,
|
||||
`passengers`.`status`,
|
||||
`passengers`.`birthdate`,
|
||||
`passengers`.`site`,
|
||||
`passengers`.`first_name`,
|
||||
`passengers`.`last_name`,
|
||||
`passengers`.`sosPhone`,
|
||||
`passengers`.`education`,
|
||||
`passengers`.`employmentType`,
|
||||
`passengers`.`maritalStatus`,
|
||||
`passengers`.`created_at`,
|
||||
`passengers`.`updated_at`,
|
||||
(
|
||||
SELECT COUNT(`id`) FROM `passengers`
|
||||
) AS countPassenger,
|
||||
(
|
||||
SELECT COUNT(`id`) FROM `feedBack`
|
||||
) AS countFeedback,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2)) FROM `ratingPassenger`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS ratingPassenger,
|
||||
(
|
||||
SELECT COUNT(`driverID`) FROM `ratingPassenger`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS countDriverRate,
|
||||
(
|
||||
SELECT COUNT(`passengerID`) FROM `canecl`
|
||||
WHERE `passengerID` = `passengers`.`id`
|
||||
) AS countPassengerCancel,
|
||||
(
|
||||
SELECT CAST(AVG(`rating`) AS DECIMAL(10, 2)) FROM `ratingDriver`
|
||||
WHERE `passenger_iD` = `passengers`.`id`
|
||||
) AS passengerAverageRating,
|
||||
(
|
||||
SELECT COUNT(`driver_id`) FROM `ratingDriver`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS countPassengerRate,
|
||||
(
|
||||
SELECT COUNT(`passenger_id`) FROM `ride`
|
||||
WHERE `passenger_id` = `passengers`.`id`
|
||||
) AS countPassengerRide,
|
||||
(
|
||||
SELECT `token` FROM `tokens`
|
||||
WHERE `passengerID` = `passengers`.`id`
|
||||
) AS passengerToken
|
||||
FROM
|
||||
`passengers`
|
||||
WHERE
|
||||
passengers.email = :email OR passengers.phone = :phone OR passengers.id = :id
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(":email", $passengerEmail);
|
||||
$stmt->bindParam(":phone", $passengerphone);
|
||||
$stmt->bindParam(":id", $passengerId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// فك التشفير للحقول الحساسة
|
||||
foreach ($result as &$row) {
|
||||
$fieldsToDecrypt = [
|
||||
"phone", "email", "gender", "birthdate", "site",
|
||||
"first_name", "last_name", "sosPhone",
|
||||
"education", "employmentType", "maritalStatus"
|
||||
];
|
||||
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field])) {
|
||||
$row[$field] = $encryptionHelper->decryptData($row[$field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess($data = $result);
|
||||
} else {
|
||||
jsonError("No records found");
|
||||
}
|
||||
?>
|
||||
48
Admin/getVisaForEachDriver.php
Normal file
48
Admin/getVisaForEachDriver.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
// جلب البيانات
|
||||
$sql = "SELECT
|
||||
COUNT(DISTINCT driverID) AS driver_count,
|
||||
`payments`.driverID,
|
||||
COALESCE(SUM(amount), 0) AS total_amount,
|
||||
`driver`.`phone`,
|
||||
`driver`.`name_arabic`,
|
||||
`driver`.`accountBank`,
|
||||
`driver`.`bankCode`,
|
||||
`driver`.`email`
|
||||
FROM
|
||||
payments
|
||||
LEFT JOIN `driver` ON `driver`.`id` = payments.driverID
|
||||
WHERE
|
||||
isGiven = 'waiting' AND payment_method IN(
|
||||
'visa-in', 'visa', 'visaRide', 'TransferFrom',
|
||||
'payout', 'TransferTo', 'payFromSeferToDriver'
|
||||
)
|
||||
AND WEEK(`payments`.created_at) = WEEK(CURRENT_DATE)
|
||||
GROUP BY
|
||||
driverID
|
||||
HAVING
|
||||
COALESCE(SUM(amount), 0) > 0 AND total_amount > 100
|
||||
LIMIT 0, 25";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// فك التشفير للحقول المطلوبة
|
||||
foreach ($result as &$row) {
|
||||
$fieldsToDecrypt = ['phone', 'email', 'accountBank', 'bankCode', 'name_arabic'];
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null) {
|
||||
$row[$field] = $encryptionHelper->decryptData($row[$field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess($result);
|
||||
} else {
|
||||
jsonError("No wallet record found");
|
||||
}
|
||||
?>
|
||||
53
Admin/ggg.php
Normal file
53
Admin/ggg.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// ============================================================
|
||||
// Admin/ggg.php
|
||||
// أداة تشفير وفك تشفير للمشرفين
|
||||
// ============================================================
|
||||
|
||||
require_once __DIR__ . '/../core/bootstrap.php';
|
||||
|
||||
// نضمن أن الرد دائماً JSON
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
// 1) قراءة الـ body كـ JSON أو POST
|
||||
$action = filterRequest('action');
|
||||
$text = filterRequest('text');
|
||||
$adminPhoneParam = filterRequest('admin_phone');
|
||||
|
||||
// 2) التحقق من رقم هاتف الأدمن المصرّح له
|
||||
$phonesRaw = getenv('ADMIN_PHONE_NUMBERS') ?: '';
|
||||
$ALLOWED_TOOL_PHONES = array_values(
|
||||
array_filter(
|
||||
array_map(function ($p) {
|
||||
return preg_replace('/\D+/', '', $p);
|
||||
}, explode(',', $phonesRaw))
|
||||
)
|
||||
);
|
||||
|
||||
$adminPhoneParam = $adminPhoneParam ? preg_replace('/\D+/', '', $adminPhoneParam) : '';
|
||||
|
||||
if ($adminPhoneParam === '' || !in_array($adminPhoneParam, $ALLOWED_TOOL_PHONES, true)) {
|
||||
securityLog("Unauthorized encrypt/decrypt attempt", ['phone' => $adminPhoneParam]);
|
||||
jsonError('Access denied for this admin phone.', 403);
|
||||
}
|
||||
|
||||
if (empty($text) || ($action !== 'encrypt' && $action !== 'decrypt')) {
|
||||
jsonError('Invalid input: need action=encrypt|decrypt and non-empty text.', 400);
|
||||
}
|
||||
|
||||
// 4) تنفيذ التشفير / الفك (التوافق مع CBC الحالي)
|
||||
try {
|
||||
if ($action === 'encrypt') {
|
||||
$result = $encryptionHelper->encryptData($text);
|
||||
} else { // decrypt
|
||||
$result = $encryptionHelper->decryptData($text);
|
||||
}
|
||||
|
||||
jsonSuccess([
|
||||
'action' => $action,
|
||||
'result' => (string) $result,
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
securityLog("Encryption tool failed", ['error' => $e->getMessage()]);
|
||||
jsonError('Operation failed.', 500);
|
||||
}
|
||||
77
Admin/jwtService.php
Executable file
77
Admin/jwtService.php
Executable file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
// ============================================================
|
||||
// Admin/jwtService.php (Customer Service Login)
|
||||
// ============================================================
|
||||
|
||||
require_once __DIR__ . '/../core/bootstrap.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
header("Access-Control-Allow-Origin: https://intaleqapp.com");
|
||||
header("Access-Control-Allow-Methods: POST, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Authorization");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── Rate Limiting ───────────────────────────────────────────
|
||||
$limiter = new RateLimiter($redis);
|
||||
$limiter->enforce(RateLimiter::identifier(), 'login');
|
||||
|
||||
try {
|
||||
$email = filterRequest('email') ?? '';
|
||||
$password = filterRequest('password') ?? '';
|
||||
$audience = filterRequest('aud') ?? '';
|
||||
|
||||
$allowed1 = getenv('allowedService1');
|
||||
$allowed2 = getenv('allowedService2');
|
||||
$allowedAudiences = array_values(array_filter([$allowed1, $allowed2]));
|
||||
|
||||
if (empty($email) || empty($password) || empty($audience)) {
|
||||
jsonError('Email and password are required.', 400);
|
||||
}
|
||||
|
||||
if (!in_array($audience, $allowedAudiences, true)) {
|
||||
jsonError('Invalid audience', 400);
|
||||
}
|
||||
|
||||
$con = Database::get('main');
|
||||
|
||||
// استخدام user table ويفضل استخدام password_hash لاحقا مثل admin_users
|
||||
$stmt = $con->prepare("SELECT `id`, `password`, `email` FROM `users` WHERE email = :email LIMIT 1");
|
||||
$stmt->execute([':email' => $email]);
|
||||
$user = $stmt->fetch();
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
// دعم password_verify مع البقاء على التوافق مع كلمات السر القديمة (Plain Text)
|
||||
if ($user && (password_verify($password, $user['password']) || $user['password'] === $password)) {
|
||||
|
||||
$limiter->reset(RateLimiter::identifier(), 'login');
|
||||
|
||||
$jwtService = new JwtService($redis);
|
||||
$jwt = $jwtService->generateAccessToken($user['id'], 'service', $audience);
|
||||
$refresh = $jwtService->generateRefreshToken($user['id']);
|
||||
|
||||
jsonSuccess([
|
||||
'jwt' => $jwt,
|
||||
'refresh_token' => $refresh['token'],
|
||||
'expires_in' => 900 // أو 6600 كما كان في الكود الأصلي
|
||||
]);
|
||||
|
||||
} else {
|
||||
$elapsed = microtime(true) - $startTime;
|
||||
if ($elapsed < 0.1) usleep((int)((0.1 - $elapsed) * 1000000));
|
||||
|
||||
securityLog("Service login failed", ['email' => $email]);
|
||||
jsonError('Invalid email or password', 401);
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
securityLog("Service Login PDO Error", ['msg' => $e->getMessage()]);
|
||||
jsonError('Login failed: Database error', 500);
|
||||
} catch (Exception $e) {
|
||||
securityLog("Service Login Error", ['msg' => $e->getMessage()]);
|
||||
jsonError('Login failed: Server error', 500);
|
||||
}
|
||||
52
Admin/passenger/admin_delete_and_blacklist_passenger.php
Executable file
52
Admin/passenger/admin_delete_and_blacklist_passenger.php
Executable file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
function normalize_phone($s) { return preg_replace('/\D+/', '', (string)$s); }
|
||||
|
||||
$id = filterRequest("id"); // أو
|
||||
$phone = filterRequest("phone"); // أحدهما مطلوب
|
||||
$reason= filterRequest("reason"); // اختياري
|
||||
$exp = filterRequest("expires_at"); // اختياري Y-m-d H:i:s
|
||||
|
||||
if (empty($id) && empty($phone)) { jsonError("Provide id or phone"); exit; }
|
||||
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
|
||||
// احضر السجل
|
||||
if (!empty($id)) {
|
||||
$sel = $con->prepare("SELECT id, phone FROM passengers WHERE id = :id LIMIT 1");
|
||||
$sel->execute(['id' => $id]);
|
||||
} else {
|
||||
$sel = $con->prepare("SELECT id, phone FROM passengers WHERE phone = :ph LIMIT 1");
|
||||
$sel->execute(['ph' => $phone]);
|
||||
}
|
||||
$p = $sel->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$p) { throw new Exception("Passenger not found"); }
|
||||
|
||||
$phRaw = $p['phone'];
|
||||
$phNorm= normalize_phone($phRaw);
|
||||
|
||||
// أدخِل/حدّث في البلاك ليست
|
||||
$ins = $con->prepare("
|
||||
INSERT INTO passenger_blacklist (phone, phone_normalized, reason, expires_at)
|
||||
VALUES (:ph, :phn, :r, :exp)
|
||||
ON DUPLICATE KEY UPDATE reason = VALUES(reason), expires_at = VALUES(expires_at)
|
||||
");
|
||||
$ins->execute([
|
||||
'ph' => $phRaw,
|
||||
'phn' => $phNorm,
|
||||
'r' => $reason ?: 'Deleted & blacklisted',
|
||||
'exp' => $exp ?: null
|
||||
]);
|
||||
|
||||
// حذف فعلي
|
||||
$del = $con->prepare("DELETE FROM passengers WHERE id = :id");
|
||||
$del->execute(['id' => $p['id']]);
|
||||
|
||||
$con->commit();
|
||||
jsonSuccess(null, "Passenger deleted and blacklisted");
|
||||
} catch (Throwable $e) {
|
||||
$con->rollBack();
|
||||
jsonError("Failed: ".$e->getMessage());
|
||||
}
|
||||
14
Admin/passenger/admin_unblacklist.php
Executable file
14
Admin/passenger/admin_unblacklist.php
Executable file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
function normalize_phone($s) { return preg_replace('/\D+/', '', (string)$s); }
|
||||
|
||||
$phone = filterRequest("phone");
|
||||
if (empty($phone)) { jsonError("phone is required"); exit; }
|
||||
|
||||
$phn = normalize_phone($phone);
|
||||
$stmt = $con->prepare("DELETE FROM passenger_blacklist WHERE phone_normalized = :phn");
|
||||
$stmt->execute(['phn' => $phn]);
|
||||
|
||||
if ($stmt->rowCount() > 0) { jsonSuccess(null, "Removed from blacklist"); }
|
||||
else { jsonError("Phone was not blacklisted"); }
|
||||
50
Admin/passenger/admin_update_passenger.php
Executable file
50
Admin/passenger/admin_update_passenger.php
Executable file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
|
||||
|
||||
$id = filterRequest("id"); // مفضّل
|
||||
|
||||
$first_name = filterRequest("first_name");
|
||||
$last_name = filterRequest("last_name");
|
||||
$new_phone = filterRequest("phone");
|
||||
|
||||
if (empty($id) ) { jsonError("Provide id or phone_lookup"); exit; }
|
||||
if ($first_name === null && $last_name === null && $new_phone === null) {
|
||||
jsonError("Nothing to update"); exit;
|
||||
}
|
||||
|
||||
$sets = [];
|
||||
$params = [];
|
||||
$new_phone = $encryptionHelper->encryptData($new_phone);
|
||||
$first_name = $encryptionHelper->encryptData($first_name);
|
||||
$last_name = $encryptionHelper->encryptData($last_name);
|
||||
|
||||
$enc_norm = $encryptionHelper->encryptData($norm);
|
||||
if ($first_name !== null) { $sets[] = "first_name = :first_name"; $params['first_name'] = trim($first_name); }
|
||||
if ($last_name !== null) { $sets[] = "last_name = :last_name"; $params['last_name'] = trim($last_name); }
|
||||
if ($new_phone !== null) {
|
||||
$sets[] = "phone = :phone";
|
||||
$params['phone'] = trim($new_phone);
|
||||
|
||||
// منع تكرار الهاتف على راكب آخر
|
||||
$q = $con->prepare("SELECT id FROM passengers WHERE phone = :ph LIMIT 1");
|
||||
$q->execute(['ph' => $params['phone']]);
|
||||
$row = $q->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row) {
|
||||
if (!empty($id) && $row['id'] != $id) { jsonError("Phone already used by another passenger"); exit; }
|
||||
if (empty($id) && $row['id'] != $phoneLookup) { jsonError("Phone already used by another passenger"); exit; }
|
||||
}
|
||||
}
|
||||
|
||||
$whereSql = "";
|
||||
$whereParams = [];
|
||||
if (!empty($id)) { $whereSql = "id = :pid"; $whereParams['pid'] = $id; }
|
||||
else { $whereSql = "phone = :plk"; $whereParams['plk'] = $phoneLookup; }
|
||||
|
||||
$sql = "UPDATE passengers SET ".implode(", ", $sets).", updated_at = CURRENT_TIMESTAMP WHERE $whereSql";
|
||||
$stmt = $con->prepare($sql);
|
||||
$ok = $stmt->execute(array_merge($params, $whereParams));
|
||||
|
||||
if ($ok && $stmt->rowCount() > 0) { jsonSuccess(null, "Passenger updated"); }
|
||||
else { jsonError("No change or passenger not found"); }
|
||||
103
Admin/rides/admin_get_rides_by_phone.php
Executable file
103
Admin/rides/admin_get_rides_by_phone.php
Executable file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$phone = filterRequest('phone');
|
||||
if (!$phone) {
|
||||
error_log("[get_last_ride] Missing phone parameter");
|
||||
jsonError("Phone is required");
|
||||
exit;
|
||||
}
|
||||
|
||||
$raw = $phone;
|
||||
|
||||
// شَفِّر قبل الاستعلام
|
||||
$enc_raw = $encryptionHelper->encryptData($raw);
|
||||
|
||||
try {
|
||||
error_log("[get_last_ride] Searching passenger with phone=$raw");
|
||||
|
||||
// 1) ابحث عن الراكب بالهاتف المشفّر
|
||||
$selP = $con->prepare("
|
||||
SELECT id, first_name, last_name, phone
|
||||
FROM passengers
|
||||
WHERE phone =:enc_raw
|
||||
LIMIT 1
|
||||
");
|
||||
$selP->execute(['enc_raw' => $enc_raw]);
|
||||
$passenger = $selP->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$passenger) {
|
||||
error_log("[get_last_ride] Passenger not found (phone=$raw)");
|
||||
jsonError('Passenger not found for provided phone');
|
||||
exit;
|
||||
}
|
||||
|
||||
error_log("[get_last_ride] Passenger found id=" . $passenger['id']);
|
||||
|
||||
// 2) آخر رحلة لهذا الراكب
|
||||
$rideStmt = $con->prepare("
|
||||
SELECT
|
||||
r.id,
|
||||
r.start_location,
|
||||
r.end_location,
|
||||
r.date,
|
||||
r.time,
|
||||
r.endtime,
|
||||
r.status,
|
||||
r.paymentMethod,
|
||||
r.carType,
|
||||
r.price,
|
||||
r.price_for_driver,
|
||||
r.price_for_passenger,
|
||||
r.distance,
|
||||
r.driver_id,
|
||||
r.passenger_id,
|
||||
r.created_at,
|
||||
r.updated_at,
|
||||
r.DriverIsGoingToPassenger,
|
||||
r.rideTimeStart,
|
||||
r.rideTimeFinish,
|
||||
d.first_name AS driver_first_name,
|
||||
d.last_name AS driver_last_name
|
||||
FROM ride r
|
||||
LEFT JOIN driver d ON d.id = r.driver_id
|
||||
WHERE r.passenger_id = :pid
|
||||
ORDER BY r.created_at DESC, r.id DESC
|
||||
LIMIT 1
|
||||
");
|
||||
$rideStmt->execute(['pid' => $passenger['id']]);
|
||||
$ride = $rideStmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$ride) {
|
||||
error_log("[get_last_ride] No rides found for passenger_id=" . $passenger['id']);
|
||||
jsonError('No rides found for this passenger');
|
||||
exit;
|
||||
}
|
||||
|
||||
error_log("[get_last_ride] Found ride id=" . $ride['id'] . " for passenger_id=" . $passenger['id']);
|
||||
|
||||
// فك التشفير
|
||||
$passenger['first_name'] = $encryptionHelper->decryptData($passenger['first_name']);
|
||||
$passenger['last_name'] = $encryptionHelper->decryptData($passenger['last_name']);
|
||||
$passenger['phone'] = $encryptionHelper->decryptData($passenger['phone']);
|
||||
$ride['driver_first_name'] = $encryptionHelper->decryptData($ride['driver_first_name']);
|
||||
$ride['driver_last_name'] = $encryptionHelper->decryptData($ride['driver_last_name']);
|
||||
|
||||
// 3) اطبع النتيجة
|
||||
$response = [
|
||||
'passenger' => [
|
||||
'id' => $passenger['id'],
|
||||
'first_name' => $passenger['first_name'],
|
||||
'last_name' => $passenger['last_name'],
|
||||
'phone' => $passenger['phone'],
|
||||
],
|
||||
'ride' => $ride
|
||||
];
|
||||
|
||||
error_log("[get_last_ride] Success response for passenger_id=" . $passenger['id']);
|
||||
jsonSuccess($response);
|
||||
|
||||
} catch (Throwable $e) {
|
||||
error_log("[get_last_ride] Exception: " . $e->getMessage());
|
||||
jsonError("Error: " . $e->getMessage());
|
||||
}
|
||||
87
Admin/rides/admin_update_ride_status.php
Executable file
87
Admin/rides/admin_update_ride_status.php
Executable file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
|
||||
|
||||
$rideId = filterRequest('id');
|
||||
$status = filterRequest('status');
|
||||
$reason = filterRequest('reason'); // اختياري
|
||||
|
||||
if (empty($rideId) || empty($status)) {
|
||||
jsonError("id and status are required");
|
||||
exit;
|
||||
}
|
||||
|
||||
/* whitelist للحالات المسموحة – عدّل حسب نظامك */
|
||||
$allowed = [
|
||||
'Pending', 'Accepted', 'EnRoute', 'Arrived',
|
||||
'Started', 'Completed', 'Canceled'
|
||||
];
|
||||
|
||||
if (!in_array($status, $allowed, true)) {
|
||||
jsonError("Invalid status");
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
|
||||
// إن أردت ختم وقت النهاية تلقائيًا عند الإكمال
|
||||
if ($status === 'Completed') {
|
||||
$sql = "UPDATE ride
|
||||
SET status = :st, rideTimeFinish = IFNULL(rideTimeFinish, NOW()), updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = :id";
|
||||
} else {
|
||||
$sql = "UPDATE ride
|
||||
SET status = :st, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = :id";
|
||||
}
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$ok = $stmt->execute(['st' => $status, 'id' => $rideId]);
|
||||
|
||||
if (!$ok || $stmt->rowCount() === 0) {
|
||||
$con->rollBack();
|
||||
jsonError("Ride not found or no change");
|
||||
exit;
|
||||
}
|
||||
|
||||
// أعِدّ بيانات الرحلة المحدّثة (للتحديث الفوري في الواجهة)
|
||||
$fetch = $con->prepare("
|
||||
SELECT
|
||||
r.id,
|
||||
r.start_location,
|
||||
r.end_location,
|
||||
r.date,
|
||||
r.time,
|
||||
r.endtime,
|
||||
r.status,
|
||||
r.paymentMethod,
|
||||
r.carType,
|
||||
r.price,
|
||||
r.price_for_driver,
|
||||
r.price_for_passenger,
|
||||
r.distance,
|
||||
r.driver_id,
|
||||
r.passenger_id,
|
||||
r.created_at,
|
||||
r.updated_at,
|
||||
r.DriverIsGoingToPassenger,
|
||||
r.rideTimeStart,
|
||||
r.rideTimeFinish,
|
||||
d.first_name AS driver_first_name,
|
||||
d.last_name AS driver_last_name
|
||||
FROM ride r
|
||||
LEFT JOIN driver d ON d.id = r.driver_id
|
||||
WHERE r.id = :id
|
||||
LIMIT 1
|
||||
");
|
||||
$fetch->execute(['id' => $rideId]);
|
||||
$ride = $fetch->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$con->commit();
|
||||
jsonSuccess(['ride' => $ride, 'message' => 'Status updated']);
|
||||
} catch (Throwable $e) {
|
||||
if ($con->inTransaction()) $con->rollBack();
|
||||
jsonError("Error: ".$e->getMessage());
|
||||
}
|
||||
50
Admin/rides/get_driver_live_pos.php
Executable file
50
Admin/rides/get_driver_live_pos.php
Executable file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// =================================================================
|
||||
// ملف: get_driver_live_pos.php
|
||||
// الوظيفة: جلب الموقع اللحظي لسائق محدد (بناءً على ID)
|
||||
// =================================================================
|
||||
|
||||
require_once __DIR__ . '/../../connect.php'; // تأكد أن هذا الملف يحتوي على $con_tracking
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Content-Type: application/json; charset=UTF-8");
|
||||
|
||||
try {
|
||||
// 1. استقبال معرف السائق
|
||||
$driver_id = filterRequest("driver_id");
|
||||
|
||||
if (!$driver_id) {
|
||||
jsonError("driver_id is required");
|
||||
exit;
|
||||
}
|
||||
|
||||
// 2. الاستعلام من قاعدة بيانات التتبع (car_locations)
|
||||
// نجلب أحدث إحداثيات تم تسجيلها لهذا السائق
|
||||
$sql = "
|
||||
SELECT
|
||||
latitude,
|
||||
longitude,
|
||||
heading,
|
||||
speed,
|
||||
updated_at
|
||||
FROM car_locations
|
||||
WHERE driver_id = ?
|
||||
ORDER BY updated_at DESC
|
||||
LIMIT 1
|
||||
";
|
||||
|
||||
$stmt = $con_tracking->prepare($sql);
|
||||
$stmt->execute([$driver_id]);
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($data) {
|
||||
jsonSuccess($data);
|
||||
} else {
|
||||
// السائق ليس له موقع مسجل (ربما لم يشغل التطبيق بعد)
|
||||
jsonError("No location found for this driver");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
jsonError("Database Error: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
108
Admin/rides/get_rides_by_status.php
Executable file
108
Admin/rides/get_rides_by_status.php
Executable file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
try {
|
||||
$statusFilter = filterRequest("status");
|
||||
// القيم المتوقعة من التطبيق: 'All', 'Begin', 'New', 'Completed', 'Canceled'
|
||||
if (!$statusFilter) $statusFilter = "Begin";
|
||||
|
||||
$params = [];
|
||||
$whereClause = "";
|
||||
|
||||
// --- منطق ترجمة الحالات (Mapping Logic) ---
|
||||
switch ($statusFilter) {
|
||||
case 'All':
|
||||
$whereClause = ""; // لا يوجد شرط، اجلب الكل
|
||||
break;
|
||||
|
||||
case 'Begin':
|
||||
// قد تكون الرحلة بدأت أو وصل السائق
|
||||
$whereClause = "WHERE r.status IN ('Begin','Apply','Applied')";
|
||||
break;
|
||||
|
||||
case 'New':
|
||||
$whereClause = "WHERE r.status = 'New'";
|
||||
break;
|
||||
|
||||
case 'Completed':
|
||||
// في قاعدة البيانات الحالة اسمها Finished
|
||||
$whereClause = "WHERE r.status = 'Finished'";
|
||||
break;
|
||||
|
||||
case 'Canceled':
|
||||
// نجمع كل حالات الإلغاء الممكنة
|
||||
$whereClause = "WHERE r.status IN ('Cancel', 'CancelFromDriverAfterApply', 'TimeOut')";
|
||||
break;
|
||||
|
||||
default:
|
||||
// في حال تم إرسال حالة محددة غير المذكورين
|
||||
$whereClause = "WHERE r.status = ?";
|
||||
$params[] = $statusFilter;
|
||||
break;
|
||||
}
|
||||
|
||||
// --- الاستعلام ---
|
||||
$sql = "
|
||||
SELECT
|
||||
r.*,
|
||||
-- بيانات السائق
|
||||
d.first_name as d_fname, d.last_name as d_lname, d.phone as d_phone, d.id as driver_real_id,
|
||||
-- إحصائيات السائق (نحسب المكتمل والملغي بشكل أدق)
|
||||
(SELECT COUNT(*) FROM ride WHERE driver_id = d.id AND status = 'Finished') as d_completed,
|
||||
(SELECT COUNT(*) FROM ride WHERE driver_id = d.id AND status LIKE 'Cancel%') as d_canceled,
|
||||
|
||||
-- بيانات الراكب
|
||||
p.first_name as p_fname, p.last_name as p_lname, p.phone as p_phone,
|
||||
-- إحصائيات الراكب
|
||||
(SELECT COUNT(*) FROM ride WHERE passenger_id = p.id AND status = 'Finished') as p_completed,
|
||||
|
||||
-- سبب الإلغاء
|
||||
-- نحاول جلبه من جدول driver_orders (ملاحظات السائق)
|
||||
-- نستخدم COALESCE لجلب 'لا يوجد سبب' إذا كانت القيمة فارغة
|
||||
COALESCE(
|
||||
(SELECT notes FROM driver_orders WHERE order_id = r.id LIMIT 1),
|
||||
'لا يوجد سبب مسجل'
|
||||
) as cancel_reason
|
||||
|
||||
FROM ride r
|
||||
LEFT JOIN driver d ON r.driver_id = d.id
|
||||
LEFT JOIN passengers p ON r.passenger_id = p.id
|
||||
$whereClause
|
||||
ORDER BY r.id DESC
|
||||
LIMIT 100
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$rides = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach ($rides as $row) {
|
||||
// فك التشفير
|
||||
try { $row['d_fname'] = $encryptionHelper->decryptData($row['d_fname']); } catch(Exception $e){}
|
||||
try { $row['d_lname'] = $encryptionHelper->decryptData($row['d_lname']); } catch(Exception $e){}
|
||||
try { $row['d_phone'] = $encryptionHelper->decryptData($row['d_phone']); } catch(Exception $e){}
|
||||
|
||||
try { $row['p_fname'] = $encryptionHelper->decryptData($row['p_fname']); } catch(Exception $e){}
|
||||
try { $row['p_lname'] = $encryptionHelper->decryptData($row['p_lname']); } catch(Exception $e){}
|
||||
try { $row['p_phone'] = $encryptionHelper->decryptData($row['p_phone']); } catch(Exception $e){}
|
||||
|
||||
$row['driver_full_name'] = trim($row['d_fname'] . ' ' . $row['d_lname']);
|
||||
$row['passenger_full_name'] = trim($row['p_fname'] . ' ' . $row['p_lname']);
|
||||
|
||||
if(empty($row['driver_full_name'])) $row['driver_full_name'] = "Unknown Driver";
|
||||
if(empty($row['passenger_full_name'])) $row['passenger_full_name'] = "Unknown Passenger";
|
||||
|
||||
$data[] = $row;
|
||||
}
|
||||
|
||||
jsonSuccess($data);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
jsonError("Database Error: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
150
Admin/rides/monitorRide.php
Executable file
150
Admin/rides/monitorRide.php
Executable file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// 1. Log the start of the request
|
||||
$phone = filterRequest("phone");
|
||||
error_log("[MONITOR_RIDE] ---------------- START REQUEST ----------------");
|
||||
error_log("[MONITOR_RIDE] 1. Received Phone: " . $phone);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 1) البحث عن الهاتف أولاً في جدول السائق ثم جدول الراكب
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
$encPhone = $encryptionHelper->encryptData($phone);
|
||||
error_log("[MONITOR_RIDE] 2. Encrypted Phone: " . $encPhone);
|
||||
|
||||
// Check Driver Table
|
||||
$driverQuery = $con->prepare("SELECT id AS driverID FROM driver WHERE phone = :phone LIMIT 1");
|
||||
$driverQuery->execute([':phone' => $encPhone]);
|
||||
$driver = $driverQuery->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// Check Passenger Table
|
||||
$customerQuery = $con->prepare("SELECT id AS customerID FROM passengers WHERE phone = :phone LIMIT 1");
|
||||
$customerQuery->execute([':phone' => $encPhone]);
|
||||
$customer = $customerQuery->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
|
||||
// حدد نوع المستخدم
|
||||
$userType = '';
|
||||
$driverID = null;
|
||||
$customerID = null;
|
||||
|
||||
if ($driver) {
|
||||
$userType = 'driver';
|
||||
$driverID = $driver['driverID'];
|
||||
error_log("[MONITOR_RIDE] 3. User Found: Type = DRIVER, ID = " . $driverID);
|
||||
} elseif ($customer) {
|
||||
$userType = 'customer';
|
||||
$customerID = $customer['customerID'];
|
||||
error_log("[MONITOR_RIDE] 3. User Found: Type = CUSTOMER, ID = " . $customerID);
|
||||
} else {
|
||||
error_log("[MONITOR_RIDE] 3. FAILURE: Phone number not found in Driver or Passenger tables.");
|
||||
jsonError("رقم الهاتف غير موجود في النظام.");
|
||||
exit;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 2) جلب آخر رحلة حالتها "بدأت" بناءً على نوع المستخدم
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
if ($userType == 'driver') {
|
||||
error_log("[MONITOR_RIDE] 4. Searching for active ride for Driver ID: " . $driverID);
|
||||
$rideQuery = $con->prepare("
|
||||
SELECT * FROM ride
|
||||
WHERE driver_id = :driverID AND status = 'Begin'
|
||||
ORDER BY id DESC LIMIT 1
|
||||
");
|
||||
$rideQuery->execute([':driverID' => $driverID]);
|
||||
} else {
|
||||
error_log("[MONITOR_RIDE] 4. Searching for active ride for Customer ID: " . $customerID);
|
||||
$rideQuery = $con->prepare("
|
||||
SELECT * FROM ride
|
||||
WHERE passenger_id = :customerID AND status = 'Begin'
|
||||
ORDER BY id DESC LIMIT 1
|
||||
");
|
||||
$rideQuery->execute([':customerID' => $customerID]);
|
||||
}
|
||||
|
||||
$ride = $rideQuery->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$ride) {
|
||||
error_log("[MONITOR_RIDE] 4. FAILURE: No ride with status 'Begin' found.");
|
||||
jsonError("لا توجد رحلة بدأت لهذا المستخدم.");
|
||||
exit;
|
||||
} else {
|
||||
error_log("[MONITOR_RIDE] 4. SUCCESS: Active Ride Found. Ride ID: " . $ride['id']);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 3) جلب معلومات السائق من الرحلة
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// FIX 1: Safe assignment of driver ID (checking driverID vs driver_id)
|
||||
$rideDriverID = $ride['driverID'] ?? $ride['driver_id'];
|
||||
|
||||
error_log("[MONITOR_RIDE] 5. Fetching info for Driver ID from Ride: " . $rideDriverID);
|
||||
|
||||
// FIX 2: Select first_name and last_name instead of fullname
|
||||
$driverInfoQuery = $con->prepare("
|
||||
SELECT id, first_name, last_name, phone
|
||||
FROM driver
|
||||
WHERE id = :driverID
|
||||
LIMIT 1
|
||||
");
|
||||
|
||||
$driverInfoQuery->execute([':driverID' => $rideDriverID]);
|
||||
$driverInfo = $driverInfoQuery->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($driverInfo) {
|
||||
// فك التشفير للهاتف
|
||||
$driverInfo['phone'] = $encryptionHelper->decryptData($driverInfo['phone']);
|
||||
|
||||
// FIX 4: Decrypt First Name and Last Name
|
||||
$driverInfo['first_name'] = $encryptionHelper->decryptData($driverInfo['first_name']);
|
||||
$driverInfo['last_name'] = $encryptionHelper->decryptData($driverInfo['last_name']);
|
||||
|
||||
// Construct fullname for the response
|
||||
$fullName = $driverInfo['first_name'] . " " . $driverInfo['last_name'];
|
||||
$driverInfo['fullname'] = $fullName;
|
||||
|
||||
error_log("[MONITOR_RIDE] 5. Driver Info Found: " . $fullName);
|
||||
} else {
|
||||
error_log("[MONITOR_RIDE] 5. WARNING: Driver info not found for ID " . $rideDriverID);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 4) جلب آخر موقع للسائق من جدول driver_location بشرط الحالة ON
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
error_log("[MONITOR_RIDE] 6. Querying Tracking DB for Driver ID: " . $rideDriverID);
|
||||
|
||||
// FIX 3: Changed ORDER BY id DESC to ORDER BY updated_at DESC
|
||||
$locationQuery = $con_tracking->prepare("
|
||||
SELECT latitude, longitude, speed, heading, updated_at
|
||||
FROM car_locations
|
||||
WHERE driver_id = :driverID AND status = 'ON'
|
||||
ORDER BY updated_at DESC LIMIT 1
|
||||
");
|
||||
$locationQuery->execute([':driverID' => $rideDriverID]);
|
||||
$location = $locationQuery->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($location) {
|
||||
error_log("[MONITOR_RIDE] 6. Location Found: Lat=" . $location['latitude'] . " Lng=" . $location['longitude'] . " Updated=" . $location['updated_at']);
|
||||
} else {
|
||||
error_log("[MONITOR_RIDE] 6. WARNING: No live location found (status=ON) or list empty.");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 5) تجهيز البيانات للرد
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
$response = [
|
||||
"ride_details" => $ride,
|
||||
"driver_details" => $driverInfo,
|
||||
"driver_location" => $location ?: "No live location"
|
||||
];
|
||||
|
||||
error_log("[MONITOR_RIDE] 7. Sending Success Response.");
|
||||
jsonSuccess($response);
|
||||
|
||||
?>
|
||||
87
Admin/sendEmailToDrivertransaction.php
Normal file
87
Admin/sendEmailToDrivertransaction.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
// File: send_payment_received_email.php
|
||||
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
$driverID = filterRequest('driverID');
|
||||
$totalAmount = filterRequest('total_amount');
|
||||
$driverPhone = filterRequest('phone');
|
||||
$driverArabicName = filterRequest('name_arabic');
|
||||
$accountBank = filterRequest('accountBank');
|
||||
$driverEmail = filterRequest('email');
|
||||
|
||||
// لغة الإيميل (تلقائي إنجليزي حالياً، يمكن تعيينها لاحقًا حسب المستخدم)
|
||||
$language = 'en';
|
||||
|
||||
// عنوان واسم التطبيق الرسمي
|
||||
$appName = "tripz"; // الاسم الجديد مع حرف "Z"
|
||||
$domain = "https://tripz-egypt.com";
|
||||
|
||||
// محتوى الإيميل - باللغة الإنجليزية
|
||||
$bodyEmail = "<html>
|
||||
<head>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; color: #333; background: #f9f9f9; padding: 20px; }
|
||||
.container { background: #fff; padding: 30px; border-radius: 8px; max-width: 600px; margin: auto; }
|
||||
h1 { color: #007bff; }
|
||||
p { font-size: 16px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='container'>
|
||||
<img src='$domain/assets/logo.png' alt='$appName Logo' style='width: 150px; margin: 20px auto; display: block;'>
|
||||
<h1>Payment Sent - $appName</h1>
|
||||
<p>Thank you for being a valued driver on the $appName platform.</p>
|
||||
<p>We have sent a payment of <strong>$totalAmount EGP</strong> to your account <strong>$accountBank</strong>.</p>
|
||||
<p>Please note that it may take a few days for your bank to process this transaction.</p>
|
||||
<p>We appreciate your efforts and are proud to have you on board with $appName.</p>
|
||||
<p style='margin-top: 40px;'>Regards,<br><strong>tripz Team</strong></p>
|
||||
<p style='font-size: 12px; color: #888;'>tripz, Egypt | $domain</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
// محتوى الإيميل - باللغة العربية
|
||||
$bodyEmailAr = "<html>
|
||||
<head>
|
||||
<style>
|
||||
body { font-family: 'Cairo', sans-serif; color: #333; background: #f9f9f9; padding: 20px; direction: rtl; }
|
||||
.container { background: #fff; padding: 30px; border-radius: 8px; max-width: 600px; margin: auto; text-align: right; }
|
||||
h1 { color: #007bff; }
|
||||
p { font-size: 16px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='container'>
|
||||
<img src='$domain/assets/logo.png' alt='$appName' style='width: 150px; margin: 20px auto; display: block;'>
|
||||
<h1>تم إرسال الدفعة - $appName</h1>
|
||||
<p>شكرًا لك لكونك سائقًا مميزًا على منصة $appName.</p>
|
||||
<p>لقد تم إرسال دفعة قدرها <strong>$totalAmount جنيه</strong> إلى حسابك <strong>$accountBank</strong>.</p>
|
||||
<p>يرجى ملاحظة أن عملية التحويل قد تستغرق بضعة أيام حسب إجراءات البنك.</p>
|
||||
<p>نقدّر جهودك ونتطلع إلى استمرار الشراكة معك على تطبيق $appName.</p>
|
||||
<p style='margin-top: 40px;'>مع التحية،<br><strong>فريق $appName</strong></p>
|
||||
<p style='font-size: 12px; color: #888;'>$appName - مصر | $domain</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
// إعدادات الإيميل
|
||||
$supportEmail = 'support@tripz-egypt.com';
|
||||
$headers = "MIME-Version: 1.0\r\n";
|
||||
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
|
||||
$headers .= "From: tripz Egypt <$supportEmail>\r\n";
|
||||
|
||||
// إرسال الإيميل إن وُجد عنوان صالح
|
||||
if (!empty($driverEmail)) {
|
||||
$subject = "Payment Sent - $appName";
|
||||
$message = ($language === 'ar') ? $bodyEmailAr : $bodyEmail;
|
||||
|
||||
if (mail($driverEmail, $subject, $message, $headers)) {
|
||||
jsonSuccess(null, "Email sent successfully to $driverEmail");
|
||||
} else {
|
||||
jsonError("Failed to send email to $driverEmail");
|
||||
}
|
||||
} else {
|
||||
jsonError("Invalid or missing driver email address.");
|
||||
}
|
||||
?>
|
||||
79
Admin/send_whatsapp_message.php
Executable file
79
Admin/send_whatsapp_message.php
Executable file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
// File: send_whatsapp_message.php
|
||||
// هذا السكربت يرسل رسالة واتساب فقط باستخدام RaseelPlus API
|
||||
|
||||
require_once __DIR__ . '/../connect.php'; // فقط إذا كنت تحتاج للوصول إلى environment
|
||||
|
||||
error_log("--- [send_whatsapp_message.php] Script execution started ---");
|
||||
|
||||
// استقبال المعطيات من POST
|
||||
$receiver = filterRequest("receiver"); // رقم الهاتف
|
||||
$message = filterRequest("message"); // نص الرسالة
|
||||
|
||||
if (empty($receiver) || empty($message)) {
|
||||
error_log("[send_whatsapp_message.php] Error: Missing receiver or message.");
|
||||
jsonError('Phone number and message are required.');
|
||||
exit();
|
||||
}
|
||||
|
||||
// بيانات Raseel
|
||||
$instanceId = getenv("RASEEL_DRIVER_INSTANCE_ID");
|
||||
$accessToken = getenv("RASEEL_DRIVER_ACCESS_TOKEN");
|
||||
|
||||
// API URL
|
||||
$apiUrl = 'https://raseelplus.com/api/send';
|
||||
|
||||
// تجهيز البيانات للإرسال
|
||||
$payload = [
|
||||
"number" => $receiver,
|
||||
"type" => "text",
|
||||
"message" => $message,
|
||||
"instance_id" => $instanceId,
|
||||
"access_token"=> $accessToken
|
||||
];
|
||||
|
||||
error_log("[send_whatsapp_message.php] Sending payload: " . json_encode($payload));
|
||||
|
||||
// إرسال الطلب
|
||||
$response = callAPI("POST", $apiUrl, json_encode($payload));
|
||||
error_log("[send_whatsapp_message.php] Raw response: " . print_r($response, true));
|
||||
|
||||
// فحص الاستجابة
|
||||
if ($response && !isset($response->error) && (isset($response->status) && $response->status == 'success' || isset($response->message))) {
|
||||
jsonSuccess(null, "Message sent successfully.");
|
||||
} else {
|
||||
$errorMessage = isset($response->message) ? $response->message : "Unknown error.";
|
||||
error_log("[send_whatsapp_message.php] Failed to send: $errorMessage");
|
||||
jsonError("Failed to send message: $errorMessage");
|
||||
}
|
||||
|
||||
// دالة cURL
|
||||
function callAPI($method, $url, $data)
|
||||
{
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_ENCODING => "",
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_POSTFIELDS => $data,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
"Content-Type: application/json",
|
||||
"Accept: application/json"
|
||||
],
|
||||
]);
|
||||
$response = curl_exec($curl);
|
||||
$err = curl_error($curl);
|
||||
curl_close($curl);
|
||||
|
||||
if ($err) {
|
||||
error_log("[callAPI] cURL Error: $err");
|
||||
return null;
|
||||
} else {
|
||||
return json_decode($response);
|
||||
}
|
||||
}
|
||||
?>
|
||||
31
Admin/view_errors.php
Executable file
31
Admin/view_errors.php
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
// استلام 'status' كمتغير اختياري لتصفية النتائج
|
||||
// مثلاً: view_errors.php?status=new سيجلب الأخطاء الجديدة فقط
|
||||
$status = filterRequest("status");
|
||||
|
||||
// إذا تم تحديد status، قم بتصفية النتائج بناءً عليه
|
||||
if (!empty($status)) {
|
||||
$stmt = $con->prepare("SELECT * FROM `error` WHERE `status` = ? ORDER BY `created_at` DESC");
|
||||
$stmt->execute(array($status));
|
||||
} else {
|
||||
// إذا لم يتم تحديد status، قم بجلب جميع الأخطاء
|
||||
$stmt = $con->prepare("SELECT * FROM `error` ORDER BY `created_at` DESC");
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
// جلب جميع النتائج
|
||||
$errors = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$count = $stmt->rowCount();
|
||||
|
||||
if ($count > 0) {
|
||||
// إرجاع البيانات كـ JSON مع رسالة نجاح
|
||||
echo json_encode(array("status" => "success", "data" => $errors));
|
||||
} else {
|
||||
// في حال عدم وجود أخطاء، إرجاع رسالة نجاح مع بيانات فارغة
|
||||
echo json_encode(array("status" => "success", "data" => []));
|
||||
}
|
||||
|
||||
?>
|
||||
0
EgyptDocuments/error_log
Normal file
0
EgyptDocuments/error_log
Normal file
60
EgyptDocuments/uploadEgyptIdBack.php
Normal file
60
EgyptDocuments/uploadEgyptIdBack.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
// Get the image file from the request.
|
||||
$image_file = $_FILES['image'];
|
||||
$driverID = filterRequest("driverID");
|
||||
|
||||
// Define allowed extensions
|
||||
$allowed_extensions = ['jpg', 'jpeg', 'png'];
|
||||
|
||||
// Get the image file from the request.
|
||||
$image_file = $_FILES['image'];
|
||||
|
||||
// Check if the image file was uploaded successfully.
|
||||
if ($image_file['error'] !== UPLOAD_ERR_OK) {
|
||||
echo "Image upload failed";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Get file information
|
||||
$image_name = $image_file['name'];
|
||||
$image_size = $image_file['size'];
|
||||
$image_extension = strtolower(pathinfo($image_name, PATHINFO_EXTENSION));
|
||||
|
||||
// Validate file extension
|
||||
if (!in_array($image_extension, $allowed_extensions)) {
|
||||
echo "Invalid image format";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Generate a unique filename using timestamp and random string
|
||||
$new_filename = $driverID . '.' . $image_extension;
|
||||
|
||||
// Set target directory for uploads
|
||||
$target_dir = "card_image/";
|
||||
|
||||
// Construct target file path
|
||||
$target_file = $target_dir . $new_filename;
|
||||
|
||||
// Move the image file to the target location
|
||||
if (!move_uploaded_file($image_file['tmp_name'], $target_file)) {
|
||||
echo json_encode(array('status' => "Failed to save image")); ;
|
||||
exit;
|
||||
}
|
||||
|
||||
// Store additional information (modify based on your needs)
|
||||
$image_url = $target_dir . $new_filename; // Update if needed
|
||||
$image_details = [
|
||||
"name" => $image_name,
|
||||
"size" => $image_size,
|
||||
"extension" => $image_extension,
|
||||
"url" => $image_url,
|
||||
];
|
||||
|
||||
// Use the image details for further processing (e.g., display, store in database)
|
||||
// ...
|
||||
|
||||
echo json_encode(array('status' => 'Image uploaded successfully!'));
|
||||
|
||||
?>
|
||||
60
EgyptDocuments/uploadEgyptidFront.php
Normal file
60
EgyptDocuments/uploadEgyptidFront.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
// Get the image file from the request.
|
||||
$image_file = $_FILES['image'];
|
||||
$driverID = filterRequest("driverID");
|
||||
|
||||
// Define allowed extensions
|
||||
$allowed_extensions = ['jpg', 'jpeg', 'png'];
|
||||
|
||||
// Get the image file from the request.
|
||||
$image_file = $_FILES['image'];
|
||||
|
||||
// Check if the image file was uploaded successfully.
|
||||
if ($image_file['error'] !== UPLOAD_ERR_OK) {
|
||||
echo "Image upload failed";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Get file information
|
||||
$image_name = $image_file['name'];
|
||||
$image_size = $image_file['size'];
|
||||
$image_extension = strtolower(pathinfo($image_name, PATHINFO_EXTENSION));
|
||||
|
||||
// Validate file extension
|
||||
if (!in_array($image_extension, $allowed_extensions)) {
|
||||
echo "Invalid image format";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Generate a unique filename using timestamp and random string
|
||||
$new_filename = $driverID . '.' . $image_extension;
|
||||
|
||||
// Set target directory for uploads
|
||||
$target_dir = "egypt/idFront/";
|
||||
|
||||
// Construct target file path
|
||||
$target_file = $target_dir . $new_filename;
|
||||
|
||||
// Move the image file to the target location
|
||||
if (!move_uploaded_file($image_file['tmp_name'], $target_file)) {
|
||||
echo json_encode(array('status' => "Failed to save image")); ;
|
||||
exit;
|
||||
}
|
||||
|
||||
// Store additional information (modify based on your needs)
|
||||
$image_url = $target_dir . $new_filename; // Update if needed
|
||||
$image_details = [
|
||||
"name" => $image_name,
|
||||
"size" => $image_size,
|
||||
"extension" => $image_extension,
|
||||
"url" => $image_url,
|
||||
];
|
||||
|
||||
// Use the image details for further processing (e.g., display, store in database)
|
||||
// ...
|
||||
|
||||
echo json_encode(array('status' => 'Image uploaded successfully!'));
|
||||
|
||||
?>
|
||||
40
aggregate_files.py
Normal file
40
aggregate_files.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
|
||||
# Configuration
|
||||
PROJECT_DIR = '.'
|
||||
OUTPUT_FILE = 'intaleq_v1_secure_latest.md'
|
||||
EXCLUDED_DIRS = {'.git', 'vendor', 'node_modules', '.gemini'}
|
||||
EXCLUDED_FILES = {OUTPUT_FILE, 'aggregate_files.py'}
|
||||
|
||||
def aggregate_files():
|
||||
with open(OUTPUT_FILE, 'w', encoding='utf-8') as outfile:
|
||||
outfile.write(f'# Intaleq V1 - Secure Latest Version\n\n')
|
||||
|
||||
for root, dirs, files in os.walk(PROJECT_DIR):
|
||||
# Prune excluded directories
|
||||
dirs[:] = [d for d in dirs if d not in EXCLUDED_DIRS]
|
||||
|
||||
for file in files:
|
||||
if file in EXCLUDED_FILES:
|
||||
continue
|
||||
|
||||
filepath = os.path.join(root, file)
|
||||
rel_path = os.path.relpath(filepath, PROJECT_DIR)
|
||||
|
||||
# We mainly want to include code files
|
||||
if any(file.endswith(ext) for ext in ['.php', '.sql', '.ini', '.json', '.md', '.txt', '.py', '.sh']):
|
||||
try:
|
||||
with open(filepath, 'r', encoding='utf-8', errors='ignore') as infile:
|
||||
content = infile.read()
|
||||
|
||||
outfile.write(f'## File: {rel_path}\n')
|
||||
outfile.write(f'```\n')
|
||||
outfile.write(content)
|
||||
outfile.write(f'\n```\n\n')
|
||||
print(f"Added: {rel_path}")
|
||||
except Exception as e:
|
||||
print(f"Could not read {rel_path}: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
aggregate_files()
|
||||
print(f"\nDone! File created: {OUTPUT_FILE}")
|
||||
0
auth/Tester/error_log
Normal file
0
auth/Tester/error_log
Normal file
29
auth/Tester/getTesterApp.php
Normal file
29
auth/Tester/getTesterApp.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$appPlatform = filterRequest("appPlatform");
|
||||
|
||||
|
||||
$sql = "SELECT
|
||||
*
|
||||
FROM
|
||||
`testApp`
|
||||
WHERE
|
||||
appPlatform = '$appPlatform'-- AND isTest = 0;";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Print the retrieved data
|
||||
// echo json_encode($result);
|
||||
jsonSuccess($data = $result);
|
||||
} else {
|
||||
// Print a failure message
|
||||
|
||||
jsonError($message = "No driver order data found");
|
||||
}
|
||||
|
||||
?>
|
||||
23
auth/Tester/updateTesterApp.php
Normal file
23
auth/Tester/updateTesterApp.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$appPlatform = filterRequest("appPlatform");
|
||||
|
||||
$sql = "UPDATE
|
||||
`testApp`
|
||||
SET
|
||||
`isTest` = '1'
|
||||
WHERE
|
||||
`testApp`.appPlatform = '$appPlatform';";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Print a success message
|
||||
jsonSuccess($message = "Test data updated successfully");
|
||||
} else {
|
||||
// Print a failure message
|
||||
jsonError($message = "Failed to update driver order data");
|
||||
}
|
||||
?>
|
||||
35
auth/captin/addCriminalDocuments.php
Normal file
35
auth/captin/addCriminalDocuments.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// Sanitize and validate input
|
||||
$driverId = filterRequest("driverId");
|
||||
$issueDate = filterRequest("IssueDate");
|
||||
$inspectionResult = filterRequest("InspectionResult");
|
||||
|
||||
// Prepare SQL statement
|
||||
$sql = "INSERT INTO criminalDocuments (driverId, IssueDate, InspectionResult)
|
||||
VALUES (:driverId, :issueDate, :inspectionResult)";
|
||||
|
||||
try {
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// Bind parameters
|
||||
$stmt->bindParam(':driverId', $driverId, PDO::PARAM_INT);
|
||||
$stmt->bindParam(':issueDate', $issueDate, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':inspectionResult', $inspectionResult, PDO::PARAM_STR);
|
||||
|
||||
// Execute the statement
|
||||
$stmt->execute();
|
||||
|
||||
// Check if the insertion was successful
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess(null, "Criminal document data saved successfully");
|
||||
} else {
|
||||
jsonError("Failed to save criminal document data");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
// Log the error and print a generic failure message
|
||||
error_log("Database Error: " . $e->getMessage());
|
||||
jsonError("An error occurred while saving the data");
|
||||
}
|
||||
?>
|
||||
60
auth/captin/deletecaptainAccounr.php
Normal file
60
auth/captin/deletecaptainAccounr.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$id = filterRequest("id");
|
||||
// يمكن استقبال سبب الحظر من التطبيق أو وضعه كقيمة افتراضية
|
||||
$reason = "Driver requested deletion (deleteFromHimself)";
|
||||
|
||||
// تأكد أن المعرف رقم صحيح
|
||||
if (!is_numeric($id)) {
|
||||
jsonError("Invalid ID");
|
||||
exit();
|
||||
}
|
||||
|
||||
try {
|
||||
// 1. جلب رقم الهاتف الخاص بالسائق قبل التحديث
|
||||
// نحتاج الهاتف لإضافته في القائمة السوداء
|
||||
$stmtPhone = $con->prepare("SELECT phone FROM `driver` WHERE `id` = :id");
|
||||
$stmtPhone->bindParam(':id', $id, PDO::PARAM_INT);
|
||||
$stmtPhone->execute();
|
||||
$driverData = $stmtPhone->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// التحقق من وجود السائق
|
||||
if (!$driverData) {
|
||||
jsonError("Driver not found");
|
||||
exit();
|
||||
}
|
||||
|
||||
$phone = $driverData['phone'];
|
||||
|
||||
// 2. تحديث حالة السائق
|
||||
$sql = "UPDATE `driver` SET `status` = 'deleteFromHimself' WHERE `id` = :id";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// 3. الإضافة إلى القائمة السوداء (blacklist_driver)
|
||||
// نستخدم NOW() لتسجيل الوقت الحالي تلقائياً
|
||||
// لا نمرر id العمود الأول لأنه غالباً Auto Increment في قاعدة البيانات
|
||||
$insertSql = "INSERT INTO `blacklist_driver` (`driver_id`, `phone`, `reason`, `created_at`)
|
||||
VALUES (:driver_id, :phone, :reason, NOW())";
|
||||
|
||||
$insertStmt = $con->prepare($insertSql);
|
||||
$insertStmt->execute([
|
||||
':driver_id' => $id,
|
||||
':phone' => $phone,
|
||||
':reason' => $reason
|
||||
]);
|
||||
|
||||
jsonSuccess(null, "Record marked as deleted and added to blacklist successfully");
|
||||
} else {
|
||||
jsonError("Failed to update record or no change made");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// في حال حدوث خطأ في قاعدة البيانات (مثلاً تكرار الإضافة)
|
||||
jsonError("Database Error: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
15
auth/captin/error_log
Normal file
15
auth/captin/error_log
Normal file
@@ -0,0 +1,15 @@
|
||||
[21-May-2025 12:28:44 Europe/Berlin] PHP Fatal error: Uncaught PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'driver.education' in 'field list' in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php:43
|
||||
Stack trace:
|
||||
#0 /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php(43): PDO->prepare('SELECT\n driv...')
|
||||
#1 {main}
|
||||
thrown in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php on line 43
|
||||
[21-May-2025 21:09:18 Europe/Berlin] PHP Fatal error: Uncaught PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'driver.education' in 'field list' in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php:43
|
||||
Stack trace:
|
||||
#0 /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php(43): PDO->prepare('SELECT\n driv...')
|
||||
#1 {main}
|
||||
thrown in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php on line 43
|
||||
[22-May-2025 03:30:03 Europe/Berlin] PHP Fatal error: Uncaught PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'driver.education' in 'field list' in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php:43
|
||||
Stack trace:
|
||||
#0 /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php(43): PDO->prepare('SELECT\n driv...')
|
||||
#1 {main}
|
||||
thrown in /home2/seferli1/server.sefer.live/sefer.click/sefer/auth/captin/loginFromGoogle.php on line 43
|
||||
0
auth/captin/forgetPassword.php
Normal file
0
auth/captin/forgetPassword.php
Normal file
24
auth/captin/getAccount.php
Normal file
24
auth/captin/getAccount.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$driverID = filterRequest("id");
|
||||
|
||||
// تحقق أن المعرف رقم صحيح
|
||||
if (!is_numeric($driverID)) {
|
||||
jsonError("Invalid driver ID");
|
||||
exit();
|
||||
}
|
||||
|
||||
// استخدم bindParam لتفادي حقن SQL
|
||||
$sql = "SELECT `accountBank` FROM `driver` WHERE `id` = :id";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':id', $driverID, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
$row = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
jsonSuccess($row);
|
||||
} else {
|
||||
jsonError("No account bank record found");
|
||||
}
|
||||
?>
|
||||
39
auth/captin/getAllDriverSecure.php
Normal file
39
auth/captin/getAllDriverSecure.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
`id`,
|
||||
`phone`,
|
||||
`email`,
|
||||
`gender`,
|
||||
`birthdate`,
|
||||
`first_name`,
|
||||
`last_name`,
|
||||
`sosPhone`
|
||||
FROM
|
||||
`passengers`
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// فك تشفير الحقول الحساسة
|
||||
foreach ($rows as &$row) {
|
||||
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
||||
$row['email'] = $encryptionHelper->decryptData($row['email']);
|
||||
$row['gender'] = $encryptionHelper->decryptData($row['gender']);
|
||||
$row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']);
|
||||
$row['first_name'] = $encryptionHelper->decryptData($row['first_name']);
|
||||
$row['last_name'] = $encryptionHelper->decryptData($row['last_name']);
|
||||
$row['sosPhone'] = $encryptionHelper->decryptData($row['sosPhone']);
|
||||
}
|
||||
|
||||
jsonSuccess($rows);
|
||||
} else {
|
||||
jsonError("No wallet record found");
|
||||
}
|
||||
?>
|
||||
23
auth/captin/getPromptDriverDocumentsEgypt.php
Normal file
23
auth/captin/getPromptDriverDocumentsEgypt.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// $driverID = filterRequest("id");
|
||||
|
||||
$sql = "
|
||||
SELECT * FROM `promptDriverIDEgypt`";
|
||||
|
||||
$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");
|
||||
}
|
||||
?>
|
||||
66
auth/captin/login.php
Normal file
66
auth/captin/login.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$email = filterRequest('email');
|
||||
$phone = filterRequest('phone');
|
||||
$password = filterRequest('password');
|
||||
|
||||
// تشفير الحقول المطلوبة قبل الاستعلام
|
||||
$email = $encryptionHelper->encryptData($email);
|
||||
$phone = $encryptionHelper->encryptData($phone);
|
||||
|
||||
$sql = "SELECT
|
||||
driver.id,
|
||||
driver.phone,
|
||||
driver.email,
|
||||
driver.password,
|
||||
driver.gender,
|
||||
driver.birthdate,
|
||||
driver.site,
|
||||
driver.first_name,
|
||||
driver.last_name,
|
||||
driver.education,
|
||||
driver.employmentType,
|
||||
driver.maritalStatus,
|
||||
driver.created_at,
|
||||
driver.updated_at,
|
||||
email_verifications.verified
|
||||
FROM
|
||||
driver
|
||||
LEFT JOIN email_verifications ON email_verifications.email = driver.email
|
||||
WHERE
|
||||
driver.phone = :phone AND driver.email = :email";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':email', $email);
|
||||
$stmt->bindParam(':phone', $phone);
|
||||
$stmt->execute();
|
||||
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$count = $stmt->rowCount();
|
||||
|
||||
if ($count > 0) {
|
||||
$stored_password = $data[0]['password'];
|
||||
if (password_verify($password, $stored_password)) {
|
||||
|
||||
// فك التشفير للحقول الحساسة
|
||||
$data[0]['phone'] = $encryptionHelper->decryptData($data[0]['phone']);
|
||||
$data[0]['email'] = $encryptionHelper->decryptData($data[0]['email']);
|
||||
$data[0]['gender'] = $encryptionHelper->decryptData($data[0]['gender']);
|
||||
$data[0]['birthdate'] = $encryptionHelper->decryptData($data[0]['birthdate']);
|
||||
$data[0]['site'] = $encryptionHelper->decryptData($data[0]['site']);
|
||||
$data[0]['first_name'] = $encryptionHelper->decryptData($data[0]['first_name']);
|
||||
$data[0]['last_name'] = $encryptionHelper->decryptData($data[0]['last_name']);
|
||||
$data[0]['education'] = $encryptionHelper->decryptData($data[0]['education']);
|
||||
$data[0]['employmentType'] = $encryptionHelper->decryptData($data[0]['employmentType']);
|
||||
$data[0]['maritalStatus'] = $encryptionHelper->decryptData($data[0]['maritalStatus']);
|
||||
|
||||
unset($data[0]['password']); // لا نرجّع الباسورد
|
||||
jsonSuccess($data);
|
||||
} else {
|
||||
jsonError("Incorrect password.");
|
||||
}
|
||||
} else {
|
||||
jsonError("User does not exist.");
|
||||
}
|
||||
?>
|
||||
111
auth/captin/loginFromGoogle.php
Executable file
111
auth/captin/loginFromGoogle.php
Executable file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
// loginFromGoogle.php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
try {
|
||||
/* ────────────────────────────────
|
||||
1) قراءة القيم الأولية
|
||||
───────────────────────────────── */
|
||||
// $emailRaw = filterRequest('email'); // البريد القادم من التطبيق (غير مشفَّر)
|
||||
$driverID = filterRequest('id'); // DriverID المُرسل
|
||||
|
||||
// error_log("[Debug] Email (raw): $emailRaw");
|
||||
error_log("[Debug] DriverID: $driverID");
|
||||
|
||||
/* ────────────────────────────────
|
||||
2) تشفير الإيميل
|
||||
───────────────────────────────── */
|
||||
// $emailEnc = $encryptionHelper->encryptData($emailRaw);
|
||||
// error_log("[Debug] Email (encrypted): $emailEnc");
|
||||
|
||||
/* ────────────────────────────────
|
||||
3) إعداد الاستعلام الموحَّد
|
||||
───────────────────────────────── */
|
||||
$sql = "
|
||||
SELECT
|
||||
driver.id, driver.phone, driver.email, driver.gender, driver.birthdate,
|
||||
driver.site, driver.first_name, driver.last_name, driver.bankCode,
|
||||
driver.accountBank, driver.employmentType,driver.status, driver.maritalStatus,
|
||||
driver.created_at, driver.updated_at,
|
||||
phone_verification.is_verified,
|
||||
CarRegistration.make, CarRegistration.model, CarRegistration.year,
|
||||
df.is_claimed, inv.isInstall, inv.isGiftToken
|
||||
FROM driver
|
||||
LEFT JOIN phone_verification ON phone_verification.phone_number = driver.phone
|
||||
LEFT JOIN driver_gifts df ON df.driver_id = driver.id
|
||||
LEFT JOIN CarRegistration ON CarRegistration.driverID = driver.id
|
||||
LEFT JOIN invites inv ON inv.driverId = driver.id
|
||||
WHERE
|
||||
|
||||
driver.id = :id
|
||||
-- AND phone_verification.is_verified = '1'
|
||||
LIMIT 1
|
||||
";
|
||||
|
||||
// error_log("[Debug] queryString:\n$sql");
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// باراميترات الربط
|
||||
$params = [
|
||||
//':email' => $emailEnc,
|
||||
':id' => $driverID,
|
||||
];
|
||||
foreach ($params as $k => $v) {
|
||||
$stmt->bindValue($k, $v);
|
||||
}
|
||||
|
||||
/* ───────── dumpParams (اختياري) ───────── */
|
||||
ob_start();
|
||||
$stmt->debugDumpParams();
|
||||
error_log("[Debug] dumpParams:\n" . ob_get_clean());
|
||||
|
||||
/* ────────────────────────────────
|
||||
4) تنفيذ الاستعلام
|
||||
───────────────────────────────── */
|
||||
$stmt->execute();
|
||||
error_log("[Debug] stmt->rowCount(): " . $stmt->rowCount());
|
||||
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
// error_log("[Debug] Raw fetched JSON: " . json_encode($rows, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
if (!$rows) {
|
||||
jsonError("User does not exist or phone not verified.");
|
||||
exit;
|
||||
}
|
||||
|
||||
/* ────────────────────────────────
|
||||
5) فك التشفير للحقول الحسّاسة
|
||||
───────────────────────────────── */
|
||||
$data = &$rows[0]; // مرجع لتوفير الذاكرة
|
||||
|
||||
$decryptIfNotNull = function($field) use (&$data, $encryptionHelper) {
|
||||
if (isset($data[$field]) && $data[$field] !== null) {
|
||||
$data[$field] = $encryptionHelper->decryptData($data[$field]);
|
||||
}
|
||||
};
|
||||
|
||||
foreach ([
|
||||
'phone', 'email', 'gender', 'birthdate', 'site',
|
||||
'first_name', 'last_name'
|
||||
] as $field) {
|
||||
$decryptIfNotNull($field);
|
||||
}
|
||||
error_log("[Debug] Raw fetched JSON: " . json_encode($rows, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
echo json_encode([
|
||||
"status" => "success",
|
||||
"count" => 1,
|
||||
"data" => $rows // نتيجة واحدة فقط
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
} catch (PDOException $e) {
|
||||
error_log("[PDO ERROR] " . $e->getMessage());
|
||||
jsonError("Database error: ".$e->getCode());
|
||||
} catch (Exception $e) {
|
||||
error_log("[GENERAL ERROR] " . $e->getMessage());
|
||||
jsonError("Error occurred.");
|
||||
} finally {
|
||||
$stmt = null;
|
||||
$con = null;
|
||||
}
|
||||
?>
|
||||
77
auth/captin/loginUsingCredentialsWithoutGoogle.php
Executable file
77
auth/captin/loginUsingCredentialsWithoutGoogle.php
Executable file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$email = filterRequest('email');
|
||||
$password = filterRequest('password');
|
||||
|
||||
// تشفير الإيميل لاستخدامه في الاستعلام
|
||||
$encryptedEmail = $encryptionHelper->encryptData($email);
|
||||
|
||||
// SQL لاسترجاع المستخدم بناءً على البريد الإلكتروني المشفر
|
||||
$sql = "SELECT
|
||||
driver.id,
|
||||
driver.phone,
|
||||
driver.email,
|
||||
driver.gender,
|
||||
driver.birthdate,
|
||||
driver.site,
|
||||
driver.first_name,
|
||||
driver.last_name,
|
||||
driver.bankCode,
|
||||
driver.accountBank,
|
||||
driver.education,
|
||||
driver.employmentType,
|
||||
driver.maritalStatus,
|
||||
driver.created_at,
|
||||
driver.updated_at,
|
||||
driver.password,
|
||||
phone_verification.is_verified,
|
||||
CarRegistration.make,
|
||||
CarRegistration.model,
|
||||
CarRegistration.year
|
||||
FROM
|
||||
driver
|
||||
LEFT JOIN phone_verification ON phone_verification.phone_number = driver.phone
|
||||
LEFT JOIN CarRegistration ON CarRegistration.driverID = driver.id
|
||||
WHERE
|
||||
driver.email = :email AND phone_verification.is_verified = '1'
|
||||
LIMIT 1";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':email', $encryptedEmail);
|
||||
$stmt->execute();
|
||||
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($data) {
|
||||
if (password_verify($password, $data['password'])) {
|
||||
unset($data['password']);
|
||||
|
||||
// فك تشفير الحقول الحساسة
|
||||
$data['phone'] = $encryptionHelper->decryptData($data['phone']);
|
||||
$data['email'] = $encryptionHelper->decryptData($data['email']);
|
||||
$data['gender'] = $encryptionHelper->decryptData($data['gender']);
|
||||
$data['birthdate'] = $encryptionHelper->decryptData($data['birthdate']);
|
||||
$data['site'] = $encryptionHelper->decryptData($data['site']);
|
||||
$data['first_name'] = $encryptionHelper->decryptData($data['first_name']);
|
||||
$data['last_name'] = $encryptionHelper->decryptData($data['last_name']);
|
||||
$data['education'] = $encryptionHelper->decryptData($data['education']);
|
||||
$data['employmentType'] = $encryptionHelper->decryptData($data['employmentType']);
|
||||
$data['maritalStatus'] = $encryptionHelper->decryptData($data['maritalStatus']);
|
||||
|
||||
echo json_encode([
|
||||
"status" => "success",
|
||||
"data" => $data
|
||||
]);
|
||||
} else {
|
||||
jsonError("Incorrect password.");
|
||||
}
|
||||
} else {
|
||||
jsonError("User does not exist or phone number not verified.");
|
||||
}
|
||||
|
||||
$stmt = null;
|
||||
$con = null;
|
||||
exit();
|
||||
?>
|
||||
132
auth/captin/register.php
Executable file
132
auth/captin/register.php
Executable file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
$allowRegistration = true;
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
|
||||
|
||||
try {
|
||||
/* =========== 1) الحقول الواردة من الـ POST =========== */
|
||||
$required = ["phone", "password", "first_name", "last_name"];
|
||||
$optional = [
|
||||
"id", "email", "gender", "license_type", "national_number",
|
||||
"name_arabic", "issue_date", "expiry_date", "license_categories",
|
||||
"address", "licenseIssueDate", "status", "birthdate", "site",
|
||||
"accountBank", "bankCode", "employmentType",
|
||||
"maritalStatus", "fullNameMaritial", "expirationDate"
|
||||
];
|
||||
|
||||
$data = [];
|
||||
|
||||
// التحقق من الحقول المطلوبة
|
||||
foreach ($required as $f) {
|
||||
$val = filterRequest($f);
|
||||
if ($val === null || $val === '') {
|
||||
jsonError("Missing required field: $f");
|
||||
exit;
|
||||
}
|
||||
$data[$f] = $val;
|
||||
}
|
||||
|
||||
// قراءة الحقول الاختيارية
|
||||
foreach ($optional as $f) {
|
||||
$v = filterRequest($f);
|
||||
$data[$f] = ($v === null || $v === '' || $v === 'Not specified') ? null : $v;
|
||||
}
|
||||
|
||||
if ($data['email'] === null) {
|
||||
// phone هنا ما زال خامًا (غير مُشفَّر)
|
||||
$data['email'] = $data['phone'] . '@intaleqapp.com';
|
||||
}
|
||||
/* =========== 2) تشفير الحقول الحسّاسة =========== */
|
||||
$encryptThese = ["phone", "email", "first_name", "last_name", "name_arabic","gender", "national_number",
|
||||
"address", "site", "fullNameMaritial"];
|
||||
|
||||
foreach ($encryptThese as $f) {
|
||||
if ($data[$f] !== null) {
|
||||
$data[$f] = $encryptionHelper->encryptData($data[$f]);
|
||||
}
|
||||
}
|
||||
|
||||
/* =========== 3) توليد driver ID (id) إذا لم يُرسَل =========== */
|
||||
|
||||
|
||||
/* =========== 4) هَش كلمة المرور =========== */
|
||||
$data['password_hashed'] = password_hash($data['password'], PASSWORD_DEFAULT);
|
||||
|
||||
/* =========== 5) منع التكرار في الهاتف / الإيميل =========== */
|
||||
$dup = $con->prepare(
|
||||
"SELECT id FROM driver WHERE phone = :phone OR email = :email"
|
||||
);
|
||||
$dup->execute([
|
||||
':phone' => $data['phone'],
|
||||
':email' => $data['email']
|
||||
]);
|
||||
if ($dup->rowCount() > 0) {
|
||||
jsonError("Phone or email already registered.");
|
||||
exit;
|
||||
}
|
||||
|
||||
/* =========== 6) إدخال السجل الجديد =========== */
|
||||
$sql = "
|
||||
INSERT INTO driver (
|
||||
id, phone, email, password, gender, license_type, national_number,
|
||||
name_arabic, issue_date, expiry_date, license_categories,
|
||||
address, licenseIssueDate, status, birthdate, site,
|
||||
first_name, last_name, accountBank, bankCode,
|
||||
employmentType, maritalStatus, fullNameMaritial, expirationDate,
|
||||
created_at, updated_at
|
||||
) VALUES (
|
||||
:id, :phone, :email, :pwd, :gender, :license_type, :national_number,
|
||||
:name_arabic, :issue_date, :expiry_date, :license_categories,
|
||||
:address, :licenseIssueDate, :status, :birthdate, :site,
|
||||
:first_name, :last_name, :accountBank, :bankCode,
|
||||
:employmentType, :maritalStatus, :fullNameMaritial, :expirationDate,
|
||||
NOW(), NOW()
|
||||
)
|
||||
";
|
||||
|
||||
$ins = $con->prepare($sql);
|
||||
|
||||
// خريطة الربط (تطابق تمامًا أسماء الـ placeholders في الـ SQL أعلاه)
|
||||
$bind = [
|
||||
'id' => $data['id'],
|
||||
'phone' => $data['phone'],
|
||||
'email' => $data['email'],
|
||||
'pwd' => $data['password_hashed'],
|
||||
'gender' => $data['gender'],
|
||||
'license_type' => $data['license_type'],
|
||||
'national_number' => $data['national_number'],
|
||||
'name_arabic' => $data['name_arabic'],
|
||||
'issue_date' => $data['issue_date'],
|
||||
'expiry_date' => $data['expiry_date'],
|
||||
'license_categories'=> $data['license_categories']?? 'B',
|
||||
'address' => $data['address'],
|
||||
'licenseIssueDate' => $data['licenseIssueDate'],
|
||||
'status' => $data['status'] ?? 'yet',
|
||||
'birthdate' => $data['birthdate'],
|
||||
'site' => $data['site'],
|
||||
'first_name' => $data['first_name'],
|
||||
'last_name' => $data['last_name'],
|
||||
'accountBank' => 'yet',
|
||||
'bankCode' => 'yet',
|
||||
'employmentType' => $data['employmentType']?? 'yet',
|
||||
'maritalStatus' => $data['maritalStatus']?? 'yet',
|
||||
'fullNameMaritial' => $data['fullNameMaritial']?? 'yet',
|
||||
'expirationDate' => $data['expirationDate']?? 'yet',
|
||||
];
|
||||
|
||||
foreach ($bind as $key => $value) {
|
||||
$ins->bindValue(":$key", $value);
|
||||
}
|
||||
|
||||
if ($ins->execute()) {
|
||||
jsonSuccess($data['id']); // ترجع driver ID
|
||||
} else {
|
||||
jsonError("Failed to insert driver record.");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
error_log("DriverInsert PDO: " . $e->getMessage());
|
||||
jsonError("Database error.");
|
||||
}
|
||||
?>
|
||||
16
auth/captin/removeAccount.php
Normal file
16
auth/captin/removeAccount.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$id = filterRequest("id");
|
||||
|
||||
$sql = "DELETE FROM `passengers` WHERE `id` = :id";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess(null, "Passenger deleted successfully.");
|
||||
} else {
|
||||
jsonError("Failed to delete passenger.");
|
||||
}
|
||||
?>
|
||||
130
auth/captin/sendOtpMessageDriver.php
Executable file
130
auth/captin/sendOtpMessageDriver.php
Executable file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// استرجاع البيانات من الطلب
|
||||
$phone_number = filterRequest("phone_number");
|
||||
$driverId = filterRequest("driverId");
|
||||
$email = filterRequest("email");
|
||||
$expiration_time = filterRequest("expiration_time"); // اختياري للمستقبل
|
||||
|
||||
// تحقق من وجود رقم الهاتف
|
||||
if (empty($phone_number)) {
|
||||
jsonError("Phone number is required");
|
||||
exit;
|
||||
}
|
||||
|
||||
// توليد رمز تحقق مكوّن من 5 أرقام
|
||||
$token_code = str_pad(random_int(0, 99999), 5, '0', STR_PAD_LEFT);
|
||||
|
||||
// تشفير البيانات الحساسة
|
||||
$encryptedPhone = $encryptionHelper->encryptData($phone_number);
|
||||
$encryptedToken = $encryptionHelper->encryptData($token_code);
|
||||
$encryptedEmail = $encryptionHelper->encryptData($email); // اختياري إذا بتحب تشفيره
|
||||
|
||||
// التحقق من وجود الرقم مسبقاً في قاعدة البيانات
|
||||
$sqlCheck = "SELECT * FROM `phone_verification` WHERE `phone_number` = :phone";
|
||||
$stmtCheck = $con->prepare($sqlCheck);
|
||||
$stmtCheck->bindParam(":phone", $encryptedPhone);
|
||||
$stmtCheck->execute();
|
||||
|
||||
$success = false;
|
||||
|
||||
// إذا كان الرقم موجود → تحديث
|
||||
if ($stmtCheck->rowCount() > 0) {
|
||||
$sqlUpdate = "UPDATE `phone_verification`
|
||||
SET `token_code` = :token,
|
||||
`expiration_time` = DATE_ADD(NOW(), INTERVAL 5 MINUTE)
|
||||
WHERE `phone_number` = :phone";
|
||||
$stmt = $con->prepare($sqlUpdate);
|
||||
$stmt->bindParam(":token", $encryptedToken);
|
||||
$stmt->bindParam(":phone", $encryptedPhone);
|
||||
$stmt->execute();
|
||||
$success = $stmt->rowCount() > 0;
|
||||
} else {
|
||||
// إذا الرقم غير موجود → إدخال جديد
|
||||
$sqlInsert = "INSERT INTO `phone_verification`
|
||||
(`phone_number`, `driverId`, `email`, `token_code`, `expiration_time`, `is_verified`, `created_at`)
|
||||
VALUES
|
||||
(:phone, :driverId, :email, :token, DATE_ADD(NOW(), INTERVAL 5 MINUTE), 0, NOW())";
|
||||
$stmt = $con->prepare($sqlInsert);
|
||||
$stmt->bindParam(":phone", $encryptedPhone);
|
||||
$stmt->bindParam(":driverId", $driverId);
|
||||
$stmt->bindParam(":email", $encryptedEmail);
|
||||
$stmt->bindParam(":token", $encryptedToken);
|
||||
$stmt->execute();
|
||||
$success = $stmt->rowCount() > 0;
|
||||
}
|
||||
|
||||
// إذا تم الحفظ بنجاح → أرسل الرمز عبر SMS
|
||||
if ($success) {
|
||||
// تحميل بيانات الاتصال بالـ SMS API من المتغيرات البيئية
|
||||
$username = getenv('SMS_USERNAME');
|
||||
$password = getenv('SMS_PASSWORD_EGYPT');
|
||||
$sender = getenv('SMS_SENDER');
|
||||
|
||||
if (!$username || !$password || !$sender) {
|
||||
jsonError("SMS credentials are missing");
|
||||
exit;
|
||||
}
|
||||
|
||||
$message = "Tripz app code is " . $token_code;
|
||||
$receiver = $phone_number;
|
||||
|
||||
$apiUrl = 'https://sms.kazumi.me/api/sms/send-sms';
|
||||
$payload = [
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'language' => 'e',
|
||||
'sender' => $sender,
|
||||
'receiver' => $receiver,
|
||||
'message' => $message
|
||||
];
|
||||
|
||||
$jsonPayload = json_encode($payload);
|
||||
$smsResponse = callAPI("POST", $apiUrl, $jsonPayload);
|
||||
|
||||
if ($smsResponse) {
|
||||
jsonSuccess(null, "Verification code sent and saved successfully");
|
||||
} else {
|
||||
jsonError("Code saved, but SMS sending failed");
|
||||
}
|
||||
} else {
|
||||
jsonError("Failed to save verification data");
|
||||
}
|
||||
|
||||
// دالة الاتصال بالـ API
|
||||
function callAPI($method, $url, $data) {
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_POSTFIELDS => $data,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
"Content-Type: application/json",
|
||||
"Accept: application/json"
|
||||
],
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_CONNECTTIMEOUT => 10
|
||||
]);
|
||||
|
||||
$api_raw_response = curl_exec($curl);
|
||||
|
||||
if (curl_errno($curl)) {
|
||||
error_log("cURL Error [".curl_errno($curl)."]: " . curl_error($curl));
|
||||
curl_close($curl);
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_close($curl);
|
||||
$decoded_response = json_decode($api_raw_response, true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
error_log("Invalid JSON response from SMS API.");
|
||||
return false;
|
||||
}
|
||||
|
||||
error_log("SMS API response: " . print_r($decoded_response, true));
|
||||
return $decoded_response;
|
||||
}
|
||||
?>
|
||||
44
auth/captin/updateAccountBank.php
Normal file
44
auth/captin/updateAccountBank.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$id = filterRequest("id");
|
||||
$columnValues = [];
|
||||
|
||||
// الحقول التي تحتاج تشفير
|
||||
$fieldsToEncrypt = [
|
||||
"phone", "email", "gender", "birthdate", "site",
|
||||
"first_name", "last_name", "accountBank", "education",
|
||||
"employmentType", "maritalStatus"
|
||||
];
|
||||
|
||||
// الحقول غير المشفرة
|
||||
$plainFields = ["status", "bankCode", "updated_at"];
|
||||
|
||||
foreach ($_POST as $key => $value) {
|
||||
$filtered = filterRequest($key);
|
||||
|
||||
if ($key === "password") {
|
||||
// هاش لكلمة المرور
|
||||
$hashed = password_hash($filtered, PASSWORD_DEFAULT);
|
||||
$columnValues[] = "`password` = '$hashed'";
|
||||
} elseif (in_array($key, $fieldsToEncrypt)) {
|
||||
$encrypted = $encryptionHelper->encryptData($filtered);
|
||||
$columnValues[] = "`$key` = '$encrypted'";
|
||||
} elseif (in_array($key, $plainFields)) {
|
||||
$columnValues[] = "`$key` = '$filtered'";
|
||||
}
|
||||
}
|
||||
|
||||
// بناء جملة التحديث
|
||||
$setClause = implode(", ", $columnValues);
|
||||
$sql = "UPDATE `driver` SET $setClause WHERE `id` = '$id'";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess(null, "Driver data updated successfully");
|
||||
} else {
|
||||
jsonError("Failed to update driver data");
|
||||
}
|
||||
?>
|
||||
38
auth/captin/updateDriverClaim.php
Executable file
38
auth/captin/updateDriverClaim.php
Executable file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// Sanitize and validate input
|
||||
$driverId = filterRequest("driverId");
|
||||
|
||||
// SQL query to check if a gift already exists for the driver (unclaimed)
|
||||
$checkSql = "SELECT COUNT(*) FROM driver_gifts WHERE driver_id = :driverId -- AND is_claimed = 0";
|
||||
|
||||
try {
|
||||
$checkStmt = $con->prepare($checkSql);
|
||||
$checkStmt->bindParam(':driverId', $driverId, PDO::PARAM_INT);
|
||||
$checkStmt->execute();
|
||||
$giftExists = $checkStmt->fetchColumn();
|
||||
|
||||
if ($giftExists > 0) {
|
||||
jsonError("Gift already exists for this driver");
|
||||
exit;
|
||||
}
|
||||
|
||||
// Insert a new claimed gift
|
||||
$sql = "INSERT INTO driver_gifts (driver_id, gift_description, is_claimed)
|
||||
VALUES (:driverId, 'new account 300 le', 1)";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':driverId', $driverId, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
jsonSuccess(null, "Gift data saved successfully");
|
||||
} else {
|
||||
jsonError("Failed to save gift data");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
error_log("Database Error: " . $e->getMessage());
|
||||
jsonError("An error occurred while saving the data");
|
||||
}
|
||||
?>
|
||||
56
auth/captin/updateDriverSecure.php
Normal file
56
auth/captin/updateDriverSecure.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$id = filterRequest("id");
|
||||
|
||||
// تحقق من وجود بيانات
|
||||
if (empty($_POST)) {
|
||||
jsonError("No passenger data provided for update.");
|
||||
exit;
|
||||
}
|
||||
|
||||
// الحقول الحساسة التي يجب تشفيرها
|
||||
$fieldsToEncrypt = ["phone", "email", "gender", "birthdate", "site", "first_name", "last_name", "sosPhone"];
|
||||
|
||||
// بناء الحقول والمعاملات
|
||||
$columnValues = [];
|
||||
$params = [];
|
||||
|
||||
foreach ($fieldsToEncrypt as $field) {
|
||||
if (isset($_POST[$field])) {
|
||||
$value = filterRequest($field);
|
||||
$encryptedValue = $encryptionHelper->encryptData($value);
|
||||
$columnValues[] = "`$field` = ?";
|
||||
$params[] = $encryptedValue;
|
||||
}
|
||||
}
|
||||
|
||||
// تحقق من أن هناك حقول للتحديث
|
||||
if (empty($columnValues)) {
|
||||
jsonError("No valid encrypted passenger data provided for update.");
|
||||
exit;
|
||||
}
|
||||
|
||||
// تركيب جملة SQL
|
||||
$setClause = implode(", ", $columnValues);
|
||||
$params[] = $id;
|
||||
|
||||
$sql = "UPDATE `passengers` SET $setClause WHERE `id` = ?";
|
||||
|
||||
try {
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
foreach ($params as $index => $value) {
|
||||
$stmt->bindValue($index + 1, $value);
|
||||
}
|
||||
|
||||
if ($stmt->execute()) {
|
||||
jsonSuccess(null, "Passenger data updated successfully with encryption");
|
||||
} else {
|
||||
jsonError("Failed to update passenger data");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
jsonError("Database error: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
39
auth/captin/updateShamCashDriver.php
Executable file
39
auth/captin/updateShamCashDriver.php
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
// استقبال معرف السائق
|
||||
$id = filterRequest("id");
|
||||
|
||||
// استقبال بيانات شام كاش من التطبيق
|
||||
$accountBank = filterRequest("accountBank"); // الاسم (مثال: intaleq)
|
||||
$bankCode = filterRequest("bankCode"); // الكود الطويل (مثال: 80f23afe...)
|
||||
|
||||
// التحقق من وصول البيانات المطلوبة
|
||||
if ($id && $accountBank && $bankCode) {
|
||||
|
||||
try {
|
||||
// 1. تشفير اسم الحساب (حسب القواعد في السكربت السابق accountBank مشفر)
|
||||
$encryptedAccountBank = $encryptionHelper->encryptData($accountBank);
|
||||
|
||||
// 2. كود المحفظة يبقى كما هو (حسب القواعد bankCode غير مشفر)
|
||||
$plainBankCode = $encryptionHelper->encryptData($bankCode);
|
||||
|
||||
// 3. جملة التحديث
|
||||
$stmt = $con->prepare("UPDATE `driver` SET `accountBank` = ?, `bankCode` = ? WHERE `id` = ?");
|
||||
|
||||
$stmt->execute(array($encryptedAccountBank, $plainBankCode, $id));
|
||||
|
||||
// التحقق من نجاح العملية
|
||||
// rowCount > 0 يعني تم التحديث، أحياناً يعطي 0 إذا كانت البيانات هي نفسها لم تتغير
|
||||
// لذا نرسل نجاح في كلتا الحالتين طالما لم يحدث Error
|
||||
jsonSuccess(null, "ShamCash info updated successfully");
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// في حال وجود خطأ في قاعدة البيانات
|
||||
jsonError("Database Error: " . $e->getMessage());
|
||||
}
|
||||
|
||||
} else {
|
||||
jsonError("Missing required fields: id, accountBank, or bankCode");
|
||||
}
|
||||
?>
|
||||
0
auth/captin/verifyEmail.php
Normal file
0
auth/captin/verifyEmail.php
Normal file
39
auth/captin/verifyOtpDriver.php
Executable file
39
auth/captin/verifyOtpDriver.php
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$phone_number = filterRequest("phone_number");
|
||||
$token_code = filterRequest("token_code");
|
||||
|
||||
$encryptedPhone = $encryptionHelper->encryptData($phone_number);
|
||||
$encryptedToken = $encryptionHelper->encryptData($token_code);
|
||||
|
||||
// Check if the phone number and token code match
|
||||
$sql = "SELECT
|
||||
`id`,
|
||||
`phone_number`,
|
||||
`token_code`,
|
||||
`expiration_time`,
|
||||
`is_verified`,
|
||||
`created_at`
|
||||
FROM
|
||||
`phone_verification`
|
||||
WHERE
|
||||
`phone_number` = :phone_number AND `token_code` = :token_code -- AND `expiration_time` > NOW()";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':phone_number', $encryptedPhone, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':token_code', $encryptedToken, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetch();
|
||||
|
||||
if ($result) {
|
||||
// $id = $result["id"];
|
||||
$sql = "UPDATE `phone_verification` SET `is_verified` = 1 WHERE `phone_number` = :phone_number";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':phone_number', $phone_number, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
|
||||
jsonSuccess($message = "Your phone number has been verified.");
|
||||
} else {
|
||||
jsonError($message = "Your phone number could not be verified. Please try again.");
|
||||
}
|
||||
?>
|
||||
21
auth/checkPhoneNumberISVerfiedDriver.php
Normal file
21
auth/checkPhoneNumberISVerfiedDriver.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
// استقبال وتشفير رقم الهاتف
|
||||
$phoneNumber = filterRequest("phone_number");
|
||||
$phoneNumber = $encryptionHelper->encryptData($phoneNumber);
|
||||
|
||||
// تجهيز الاستعلام باستخدام bindParam للحماية
|
||||
$sql = "SELECT * FROM `phone_verification` WHERE `phone_number` = :phone_number";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(":phone_number", $phoneNumber);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
jsonSuccess($rows);
|
||||
} else {
|
||||
jsonError("No phone verified yet found");
|
||||
}
|
||||
?>
|
||||
39
auth/checkPhoneNumberISVerfiedPassenger.php
Executable file
39
auth/checkPhoneNumberISVerfiedPassenger.php
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
// استقبال القيم
|
||||
$phoneNumber = filterRequest("phone_number");
|
||||
$email = filterRequest("email");
|
||||
|
||||
// تشفير القيم المطلوبة للمقارنة داخل SQL
|
||||
$phoneNumber = $encryptionHelper->encryptData($phoneNumber);
|
||||
$email = $encryptionHelper->encryptData($email);
|
||||
|
||||
// تنفيذ الاستعلام
|
||||
$sql = "
|
||||
SELECT
|
||||
pv.*,
|
||||
p.email
|
||||
FROM
|
||||
`phone_verification_passenger` pv
|
||||
INNER JOIN
|
||||
`passengers` p ON pv.phone_number = p.phone
|
||||
WHERE
|
||||
pv.phone_number = :phoneNumber AND p.email = :email
|
||||
";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':phoneNumber', $phoneNumber, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// يمكنك هنا لاحقًا تفكيك تشفير أي حقل إذا كنت ترجع phone/email مثلاً للمستخدم، لكن في حالتنا ما في حاجة.
|
||||
|
||||
jsonSuccess($rows);
|
||||
} else {
|
||||
jsonError("No Phone verified or related email found");
|
||||
}
|
||||
?>
|
||||
23
auth/cnMap.php
Normal file
23
auth/cnMap.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
// Import the map
|
||||
$cn = array(
|
||||
"0" => "3",
|
||||
"1" => "7",
|
||||
"2" => "1",
|
||||
"3" => "9",
|
||||
"4" => "0",
|
||||
"5" => "5",
|
||||
"6" => "2",
|
||||
"7" => "6",
|
||||
"8" => "4",
|
||||
"9" => "8"
|
||||
);
|
||||
|
||||
// Convert the map to a JSON string with JSON_FORCE_OBJECT option
|
||||
$jsonString = json_encode($cn, JSON_FORCE_OBJECT);
|
||||
|
||||
// Send the JSON string to the Flutter app
|
||||
echo $jsonString;
|
||||
?>
|
||||
1
auth/cn_map.json
Normal file
1
auth/cn_map.json
Normal file
@@ -0,0 +1 @@
|
||||
["3","7","1","9","0","5","2","6","4","8"]
|
||||
245
auth/document_syria/ai_document.php
Executable file
245
auth/document_syria/ai_document.php
Executable file
@@ -0,0 +1,245 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$driverId = filterRequest("driver_id");
|
||||
$type = filterRequest("type");
|
||||
|
||||
// 🔒 Validate image
|
||||
if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
|
||||
error_log("Upload error: Image not provided or upload failed.");
|
||||
jsonError("Image upload failed");
|
||||
exit;
|
||||
}
|
||||
|
||||
$file = $_FILES['image'];
|
||||
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
$allowed = ['jpg', 'jpeg', 'png'];
|
||||
|
||||
if (!in_array($extension, $allowed)) {
|
||||
error_log("Unsupported file type: $extension");
|
||||
jsonError("Unsupported file type");
|
||||
exit;
|
||||
}
|
||||
|
||||
$uniqueName = "driver_" . $type . "_" . $driverId . ".$extension";
|
||||
$uploadDir = "../uploads/documents/";
|
||||
$uploadPath = $uploadDir . $uniqueName;
|
||||
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
if (!move_uploaded_file($file['tmp_name'], $uploadPath)) {
|
||||
error_log("Failed to move uploaded file.");
|
||||
jsonError("Failed to move uploaded image");
|
||||
exit;
|
||||
}
|
||||
|
||||
$imageUrl = "https://intaleq.xyz/intaleq/auth/uploads/documents/" . $uniqueName ;
|
||||
$imageData = file_get_contents($uploadPath);
|
||||
$imageBase64 = base64_encode($imageData);
|
||||
|
||||
$mimeType = match ($extension) {
|
||||
'jpg', 'jpeg' => 'image/jpeg',
|
||||
'png' => 'image/png',
|
||||
default => 'application/octet-stream',
|
||||
};
|
||||
|
||||
$prompts = [
|
||||
"id_front_sy" => <<<EOT
|
||||
You are an OCR expert for Syrian national ID cards (green card).
|
||||
|
||||
### TASK
|
||||
Analyse the **front side** of the ID and return **raw JSON only** with exactly these keys:
|
||||
|
||||
{
|
||||
"full_name": "", // الاسم الثلاثي أو الرباعي
|
||||
"national_number": "", // الرقم الوطني (LATIN digits only)
|
||||
"dob": "YYYY-MM-DD", // تاريخ الميلاد
|
||||
"address": "" // العنوان
|
||||
}
|
||||
|
||||
### RULES
|
||||
* Read the red number on the bottom of the card.
|
||||
* Convert any Eastern-Arabic digits (٠١٢٣٤٥٦٧٨٩) to Western-Arabic digits (0-9).
|
||||
* `national_number` must contain **Latin digits only, no spaces or other characters**.
|
||||
* If a field is missing, set it to **null**.
|
||||
* Convert the birth date to ISO `YYYY-MM-DD`.
|
||||
* Return valid JSON only — no extra keys, no markdown.
|
||||
EOT,
|
||||
"id_back_sy" => <<<EOT
|
||||
أنت خبير OCR مختص ببطاقات الهوية السورية (الوجه الخلفي).
|
||||
|
||||
### المطلوب
|
||||
حلّل صورة الوجه الخلفي للهوية السورية وأعد **JSON صِرف** يحتوي المفاتيح التالية فقط:
|
||||
|
||||
{
|
||||
"governorate": "", // المحافظة (مثال: دمشق)
|
||||
"address": "", // العنوان التفصيلي (حيّ، بلدة …)
|
||||
"gender": "", //Male or Female
|
||||
"issue_date": "YYYY-MM-DD"// تاريخ الإصدار بصيغة ISO
|
||||
}
|
||||
|
||||
### القواعد
|
||||
1. حوّل أي أرقام عربية شرقية (٠١٢٣٤٥٦٧٨٩) إلى أرقام لاتينية (0-9).
|
||||
2. أعدّ تاريخ الإصدار بالتقويم الميلادي بصيغة `YYYY-MM-DD`.
|
||||
3. استخدم أحرف لاتينية كبيرة لزمرة الدم مع رمز `+` أو `-` فقط.
|
||||
4. إذا كان أحد الحقول غير موجود مطلقًا، أعد قيمته **null**.
|
||||
5. لا تُرجع أي مفاتيح إضافية أو شروح أو Markdown — JSON صالح فقط.
|
||||
EOT,
|
||||
"driving_license_sy_front" => <<<EOT
|
||||
You are an OCR expert for Syrian documents.
|
||||
|
||||
### TASK
|
||||
Analyse the **front side of a Syrian driving licence** and return **clean JSON only** with the following keys (no extra keys, no markdown):
|
||||
|
||||
{
|
||||
"name_arabic": "", // الاسم الثلاثي أو الرباعي بالعربية
|
||||
"birth_place": "", // المحافظة أو المنطقة المكتوبة بعد كلمة الولادة
|
||||
"birth_year": "", // سنة الميلاد فقط (أربعة أرقام)
|
||||
"national_number": ""
|
||||
"civil_registry": "", // سطر "القيد" (مثال: سهوة 3)
|
||||
"blood_type": "" // زمرة الدم بالشكل: A+ , A- , B+ , B- , AB+ , AB- , O+ , O-
|
||||
}
|
||||
|
||||
### RULES
|
||||
* إذا كانت القيمة مفقودة تمامًا اكتب **null**.
|
||||
* لا تُغيّر ترتيب المفاتيح.
|
||||
* لا تُرسل أى شرح أو أسطر إضافية – JSON خالص فقط.
|
||||
EOT,
|
||||
|
||||
"driving_license_sy_back" => <<<EOT
|
||||
You are an OCR expert for Syrian driving licences.
|
||||
|
||||
### TASK
|
||||
Analyse the **back side** of a Syrian driving licence and return **raw JSON only** with exactly these keys:
|
||||
|
||||
{
|
||||
"issue_date": "YYYY-MM-DD", // تاريخ المنح
|
||||
"expiry_date": "YYYY-MM-DD", // صالحة لغاية
|
||||
"license_number": "", // رقم الإجازة
|
||||
"license_category": "" // D1, D2, D3 … (as printed after "UNIVERSAL DRIVING LICENCE")
|
||||
}
|
||||
|
||||
### RULES
|
||||
* If a value is totally absent, set it to **null**.
|
||||
* Convert all dates to ISO `YYYY-MM-DD` (Gregorian).
|
||||
* Do **NOT** add extra keys, comments, or markdown — return valid JSON only.
|
||||
EOT,
|
||||
"vehicle_license_sy_front" => <<<EOT
|
||||
You are an OCR expert specialized in analyzing Syrian vehicle registration cards (الرخصة البرتقالية).
|
||||
|
||||
Your task is to extract structured data from the **front side** of the Syrian orange vehicle card and return **raw JSON only** with the following exact fields:
|
||||
|
||||
{
|
||||
"car_plate": "", // رقم المركبة الكامل مع اسم المحافظة، مأخوذ من الجهة اليسرى في السطر الأول (مثال: "155186 درعا")
|
||||
"owner": "", // اسم المالك الكامل
|
||||
"vin": "", // رقم الهيكل
|
||||
"color": "", // اللون بالعربية أو الإنجليزية (مثال: "أبيض" أو "White")
|
||||
"color_hex": "", // كود اللون بصيغة Hex (مثال: "#FFFFFF") أو #27332F إن تعذّر
|
||||
"issue_date": "YYYY-MM-DD", // تاريخ المنح بصيغة ISO
|
||||
"inspection_date": "YYYY-MM-DD" // تاريخ الفحص القادم بصيغة ISO
|
||||
}
|
||||
|
||||
### Instructions & Rules:
|
||||
|
||||
1. Do **not** extract the "رمز المركبة" (on the right side of the first line) — use only the **left side** of the first line for `car_plate`.
|
||||
2. Convert any Arabic dates (like `2024/05/13`) into ISO format `YYYY-MM-DD`.
|
||||
3. If any value is missing or unreadable, return `null` for it.
|
||||
4. Maintain Arabic encoding (e.g., owner name, city name, color).
|
||||
5. Never guess — extract only what's visually found on the card.
|
||||
6. Never include any explanation or extra output — return the JSON only.
|
||||
|
||||
Example of valid `car_plate`:
|
||||
- "155186 درعا"
|
||||
- "45291 دمشق"
|
||||
- "122334 حمص"
|
||||
EOT,
|
||||
"vehicle_license_sy_back" => <<<EOT
|
||||
You are an OCR expert for Syrian vehicle registration cards (orange card).
|
||||
|
||||
### TASK
|
||||
Analyse the **back side** of the card and return **raw JSON only** with exactly these keys (no more, no less):
|
||||
|
||||
{
|
||||
"make": "", // الصانع (Hyundai …)
|
||||
"model": "", // الطراز (H1 …)
|
||||
"year": "", // سنة الصنع بالأرقام اللاتينية (e.g. "2019")
|
||||
"fuel": "", // نوع الوقود (بنزين، ديزل …) أو بالإنجليزية (Petrol, Diesel,electric)
|
||||
"chassis": "" // رقم الهيكل (VIN)
|
||||
}
|
||||
|
||||
### RULES
|
||||
* Convert any Eastern-Arabic digits (٠١٢٣٤٥٦٧٨٩) to Western digits (0-9).
|
||||
* Normalise color names to standard English if possible, then map to a common Hex code
|
||||
• "أبيض / White" → **#FFFFFF**
|
||||
• "أسود / Black" → **#000000**
|
||||
• "أحمر / Red" → **#FF0000**
|
||||
• "أزرق / Blue" → **#0000FF**
|
||||
• … (use the closest basic colour); if no match, set **color_hex = null**.
|
||||
* If any field is unreadable or absent, set its value to **null**.
|
||||
* Do **NOT** include extra keys, comments, or markdown — output valid JSON only.
|
||||
EOT
|
||||
];
|
||||
|
||||
$prompt = $prompts[$type] ?? $prompts["id_front_sy"];
|
||||
|
||||
$apiKey = getenv("GEMINI_API_KEY");
|
||||
$apiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key=$apiKey";
|
||||
|
||||
$headers = ["Content-Type: application/json"];
|
||||
$payload = [
|
||||
"contents" => [
|
||||
["role" => "user", "parts" => [["text" => $prompt]]],
|
||||
["role" => "user", "parts" => [["inlineData" => ["mimeType" => $mimeType, "data" => $imageBase64]]]]
|
||||
]
|
||||
];
|
||||
|
||||
$ch = curl_init($apiURL);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
|
||||
if (curl_errno($ch)) {
|
||||
$error_msg = curl_error($ch);
|
||||
error_log("CURL error: $error_msg");
|
||||
jsonError("AI Error: $error_msg");
|
||||
curl_close($ch);
|
||||
exit;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
error_log("AI raw response: $response");
|
||||
|
||||
$data = json_decode($response, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
error_log("JSON decode error: " . json_last_error_msg());
|
||||
jsonError("Failed to parse AI response");
|
||||
exit;
|
||||
}
|
||||
|
||||
$textRaw = $data['candidates'][0]['content']['parts'][0]['text'] ?? '';
|
||||
$textRaw = trim(preg_replace('/```json|```/', '', $textRaw));
|
||||
$json = json_decode($textRaw, true);
|
||||
|
||||
$requiredKey = match ($type) {
|
||||
'id_front_sy' => 'national_number',
|
||||
'id_back_sy' => 'gender',
|
||||
'driving_license_sy' => 'license_type',
|
||||
'vehicle_license_sy' => 'chassis',
|
||||
default => null,
|
||||
};
|
||||
|
||||
if (!$json || ($requiredKey && !isset($json[$requiredKey]))) {
|
||||
error_log("AI response missing required key '$requiredKey': $textRaw");
|
||||
jsonError("AI failed to extract required information");
|
||||
exit;
|
||||
}
|
||||
|
||||
printSuccess([
|
||||
"image_url" => $imageUrl,
|
||||
"data" => $json
|
||||
]);
|
||||
97
auth/document_syria/uploadDocSyria.php
Executable file
97
auth/document_syria/uploadDocSyria.php
Executable file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* upload_document.php
|
||||
* الغرض: رفع صورة وثيقة فقط وإرجاع رابطها (بدون ذكاء صناعي)
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$driverId = trim((string) filterRequest("driver_id"));
|
||||
$type = trim((string) filterRequest("type"));
|
||||
|
||||
// ✅ التحقق من الحقول الاختيارية
|
||||
if ($driverId === "") { $driverId = "unknown"; }
|
||||
if ($type === "") { $type = "generic"; }
|
||||
|
||||
// ✅ التحقق من ملف الصورة
|
||||
if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
|
||||
error_log("Upload error: Image not provided or upload failed.");
|
||||
jsonError("Image upload failed");
|
||||
exit;
|
||||
}
|
||||
|
||||
$file = $_FILES['image'];
|
||||
|
||||
// ✅ السماح بالامتدادات الشائعة + فحص MIME الحقيقي
|
||||
$allowedExt = ['jpg', 'jpeg', 'png'];
|
||||
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
if (!in_array($extension, $allowedExt, true)) {
|
||||
error_log("Unsupported file extension: $extension");
|
||||
jsonError("Unsupported file type");
|
||||
exit;
|
||||
}
|
||||
|
||||
// فحص نوع المحتوى الفعلي (أكثر أماناً)
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mime = $finfo->file($file['tmp_name']) ?: 'application/octet-stream';
|
||||
$allowedMime = ['image/jpeg', 'image/png'];
|
||||
if (!in_array($mime, $allowedMime, true)) {
|
||||
error_log("Unsupported MIME type: $mime");
|
||||
jsonError("Unsupported image MIME type");
|
||||
exit;
|
||||
}
|
||||
|
||||
// (اختياري) حد أقصى للحجم 10MB
|
||||
$maxBytes = 10 * 1024 * 1024;
|
||||
if ($file['size'] > $maxBytes) {
|
||||
error_log("Image too large: {$file['size']} bytes");
|
||||
jsonError("Image too large (max 10MB)");
|
||||
exit;
|
||||
}
|
||||
|
||||
// 📁 مسارات الحفظ
|
||||
$uploadDir = "../uploads/documents/";
|
||||
if (!is_dir($uploadDir)) {
|
||||
if (!mkdir($uploadDir, 0755, true) && !is_dir($uploadDir)) {
|
||||
error_log("Failed to create upload directory: $uploadDir");
|
||||
jsonError("Server error: cannot create upload directory");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$baseName = "driver_{$type}_{$driverId}";
|
||||
$uniqueName = $baseName . "." . $extension;
|
||||
$uploadPath = $uploadDir . $uniqueName;
|
||||
|
||||
// ⬆️ نقل الملف
|
||||
if (!move_uploaded_file($file['tmp_name'], $uploadPath)) {
|
||||
error_log("Failed to move uploaded file to $uploadPath");
|
||||
jsonError("Failed to move uploaded image");
|
||||
exit;
|
||||
}
|
||||
|
||||
// 🔒 منع التنفيذ لو رُفع PHP بالخطأ
|
||||
@chmod($uploadPath, 0644);
|
||||
|
||||
// 🌐 توليد BASE_URL آمن (يدعم ENV أو يعتمد على المضيف الحالي)
|
||||
if (!defined('BASE_URL')) {
|
||||
$APP_BASE_URL = rtrim(getenv('APP_BASE_URL') ?: '', '/');
|
||||
if ($APP_BASE_URL === '') {
|
||||
$scheme = isset($_SERVER['REQUEST_SCHEME']) ? $_SERVER['REQUEST_SCHEME'] : ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http');
|
||||
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
|
||||
define('BASE_URL', $scheme . '://' . $host);
|
||||
} else {
|
||||
define('BASE_URL', $APP_BASE_URL);
|
||||
}
|
||||
}
|
||||
|
||||
// ⚙️ مسار الرابط العام (عدّل المسار حسب نشر مشروعك)
|
||||
$publicPath = "/intaleq/auth/uploads/documents/" . $uniqueName;
|
||||
$imageUrl = rtrim(BASE_URL, '/') . $publicPath;
|
||||
|
||||
// ✅ نتيجة نهائية: فقط رابط الصورة وبعض البيانات المفيدة
|
||||
printSuccess([
|
||||
$imageUrl,
|
||||
|
||||
]);
|
||||
0
auth/error_log
Normal file
0
auth/error_log
Normal file
64
auth/google_auth/callback.php
Executable file
64
auth/google_auth/callback.php
Executable file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
// File: callback.php
|
||||
// هذا الملف يستقبل الرد من جوجل بعد تسجيل المستخدم دخوله.
|
||||
// يقوم بتحديث حالة الجلسة بالبيانات الصحيحة.
|
||||
|
||||
// 1. الإعدادات
|
||||
$clientID = '1086900987150-j8brn0i5s97315kh1ej9jr72grkfqgh5.apps.googleusercontent.com';
|
||||
$clientSecret = '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';
|
||||
$redirectUri = 'https://api.tripz-egypt.com/tripz/auth/google_auth/callback.php';
|
||||
|
||||
// 2. التحقق من وجود 'code' و 'state' من جوجل
|
||||
if (!isset($_GET['code']) || !isset($_GET['state'])) {
|
||||
die('Invalid callback request.');
|
||||
}
|
||||
$authCode = $_GET['code'];
|
||||
$loginToken = basename($_GET['state']); // الحماية من Path Traversal
|
||||
|
||||
$pollDir = __DIR__ . '/polls';
|
||||
$sessionFile = $pollDir . '/' . $loginToken . '.json';
|
||||
|
||||
// التحقق من أن ملف الجلسة موجود
|
||||
if (!file_exists($sessionFile)) {
|
||||
die('Invalid or expired session.');
|
||||
}
|
||||
|
||||
// 3. تبديل الـ code بـ access token
|
||||
$tokenUrl = 'https://oauth2.googleapis.com/token';
|
||||
$postData = [
|
||||
'code' => $authCode,
|
||||
'client_id' => $clientID,
|
||||
'client_secret' => $clientSecret,
|
||||
'redirect_uri' => $redirectUri,
|
||||
'grant_type' => 'authorization_code'
|
||||
];
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $tokenUrl);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
$tokenData = json_decode($response, true);
|
||||
|
||||
if (isset($tokenData['access_token'])) {
|
||||
// 4. جلب بيانات المستخدم
|
||||
$userInfoUrl = 'https://www.googleapis.com/oauth2/v2/userinfo?access_token=' . $tokenData['access_token'];
|
||||
$userInfoResponse = file_get_contents($userInfoUrl);
|
||||
$userData = json_decode($userInfoResponse, true);
|
||||
|
||||
if (isset($userData['id'])) {
|
||||
// 5. تحديث ملف الجلسة بالبيانات الجديدة
|
||||
$finalData = [
|
||||
'status' => 'success',
|
||||
'userData' => $userData
|
||||
];
|
||||
file_put_contents($sessionFile, json_encode($finalData));
|
||||
}
|
||||
}
|
||||
|
||||
// 6. عرض صفحة نجاح للمستخدم في المتصفح
|
||||
echo '<!DOCTYPE html><html><head><title>Success</title><meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body style="font-family: sans-serif; text-align: center; padding-top: 50px;"><h1>Authentication Successful</h1><p>You can now return to the Tripz app.</p></body></html>';
|
||||
exit();
|
||||
?>
|
||||
38
auth/google_auth/check_status.php
Executable file
38
auth/google_auth/check_status.php
Executable file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
// File: check_status.php
|
||||
// هذا الملف الذي سيقوم التطبيق بالاتصال به بشكل دوري.
|
||||
// يتحقق من حالة الجلسة ويرجع البيانات عند نجاحها.
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// 1. استقبال الـ loginToken من التطبيق
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
if (!isset($input['loginToken'])) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Login token is missing.']);
|
||||
exit();
|
||||
}
|
||||
$loginToken = basename($input['loginToken']); // حماية
|
||||
|
||||
// 2. التحقق من ملف الجلسة
|
||||
$pollDir = __DIR__ . '/polls';
|
||||
$sessionFile = $pollDir . '/' . $loginToken . '.json';
|
||||
|
||||
if (file_exists($sessionFile)) {
|
||||
$sessionData = json_decode(file_get_contents($sessionFile), true);
|
||||
|
||||
// إذا نجحت العملية، أرجع البيانات واحذف الملف
|
||||
if ($sessionData['status'] === 'success') {
|
||||
echo json_encode($sessionData);
|
||||
unlink($sessionFile); // حذف الملف بعد النجاح
|
||||
} else {
|
||||
// إذا كانت لا تزال معلقة
|
||||
echo json_encode(['status' => 'pending']);
|
||||
}
|
||||
} else {
|
||||
// إذا انتهت المهلة أو حدث خطأ
|
||||
http_response_code(404);
|
||||
echo json_encode(['status' => 'expired', 'message' => 'Session not found or expired.']);
|
||||
}
|
||||
exit();
|
||||
?>
|
||||
55
auth/google_auth/google_auth.php
Executable file
55
auth/google_auth/google_auth.php
Executable file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
$redirectUri = 'https://api.tripz-egypt.com/tripz/auth/google_auth/callback.php';
|
||||
|
||||
// google_auth.php
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use Google\Client;
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$response = [
|
||||
'success' => false,
|
||||
'error' => null,
|
||||
'data' => null,
|
||||
];
|
||||
|
||||
try {
|
||||
if (!isset($_POST['code'])) {
|
||||
throw new Exception("Missing authorization code.");
|
||||
}
|
||||
|
||||
$code = $_POST['code'];
|
||||
|
||||
$client = new Client();
|
||||
$client->setClientId('1086900987150-j8brn0i5s97315kh1ej9jr72grkfqgh5.apps.googleusercontent.com');
|
||||
$client->setClientSecret('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');
|
||||
$client->setRedirectUri('postmessage');
|
||||
$client->addScope('email');
|
||||
$client->addScope('profile');
|
||||
|
||||
$token = $client->fetchAccessTokenWithAuthCode($code);
|
||||
|
||||
if (isset($token['error'])) {
|
||||
throw new Exception("Access token error: " . $token['error']);
|
||||
}
|
||||
|
||||
$client->setAccessToken($token['access_token']);
|
||||
|
||||
$oauth2 = new Google_Service_Oauth2($client);
|
||||
$userinfo = $oauth2->userinfo->get();
|
||||
|
||||
$response['success'] = true;
|
||||
$response['data'] = [
|
||||
'id' => $userinfo->id,
|
||||
'email' => $userinfo->email,
|
||||
'name' => $userinfo->name,
|
||||
'picture' => $userinfo->picture,
|
||||
];
|
||||
|
||||
} catch (Exception $e) {
|
||||
$response['error'] = $e->getMessage();
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
41
auth/google_auth/login.php
Executable file
41
auth/google_auth/login.php
Executable file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// File: start_login.php
|
||||
// هذا الملف يبدأ عملية تسجيل الدخول.
|
||||
// يقوم بإنشاء معرف فريد ورابط تسجيل الدخول وإرسالهم للتطبيق.
|
||||
|
||||
// 1. الإعدادات
|
||||
$clientID = '1086900987150-j8brn0i5s97315kh1ej9jr72grkfqgh5.apps.googleusercontent.com';
|
||||
$redirectUri = 'https://api.tripz-egypt.com/tripz/auth/google_auth/callback.php';
|
||||
$scopes = 'email profile';
|
||||
|
||||
// 2. إنشاء معرف فريد للجلسة (login token)
|
||||
$loginToken = bin2hex(random_bytes(24));
|
||||
|
||||
// 3. إنشاء مجلد لتخزين الجلسات المؤقتة إذا لم يكن موجوداً
|
||||
$pollDir = __DIR__ . '/polls';
|
||||
if (!is_dir($pollDir)) {
|
||||
mkdir($pollDir, 0775, true);
|
||||
}
|
||||
|
||||
// 4. إنشاء ملف مؤقت لهذه الجلسة
|
||||
$sessionFile = $pollDir . '/' . $loginToken . '.json';
|
||||
file_put_contents($sessionFile, json_encode(['status' => 'pending']));
|
||||
|
||||
// 5. بناء رابط جوجل مع تمرير المعرف الفريد في متغير 'state'
|
||||
$authUrl = 'https://accounts.google.com/o/oauth2/v2/auth?' . http_build_query([
|
||||
'client_id' => $clientID,
|
||||
'redirect_uri' => $redirectUri,
|
||||
'response_type' => 'code',
|
||||
'scope' => $scopes,
|
||||
'access_type' => 'offline',
|
||||
'state' => $loginToken // مهم جداً
|
||||
]);
|
||||
|
||||
// 6. إرجاع الرابط والمعرف للتطبيق
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'authUrl' => $authUrl,
|
||||
'loginToken' => $loginToken
|
||||
]);
|
||||
exit();
|
||||
?>
|
||||
67
auth/login.php
Normal file
67
auth/login.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
$email = filterRequest('email');
|
||||
$phone = filterRequest('phone');
|
||||
$password = filterRequest('password');
|
||||
|
||||
// Hash the password
|
||||
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
||||
|
||||
$sql = "SELECT
|
||||
passengers.`id`,
|
||||
passengers.`phone`,
|
||||
passengers.`email`,
|
||||
passengers.`password`,
|
||||
passengers.`gender`,
|
||||
passengers.`birthdate`,
|
||||
passengers.`site`,
|
||||
passengers.`first_name`,
|
||||
passengers.`last_name`,
|
||||
passengers.`education`,
|
||||
passengers.`employmentType`,
|
||||
passengers.`maritalStatus`,
|
||||
passengers.`created_at`,
|
||||
passengers.`updated_at`,
|
||||
email_verifications.verified
|
||||
FROM
|
||||
`passengers`
|
||||
LEFT JOIN email_verifications ON email_verifications.email = passengers.email
|
||||
WHERE
|
||||
passengers.phone = :phone AND passengers.email = :email ";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':email', $email);
|
||||
$stmt->bindParam(':phone', $phone);
|
||||
$stmt->execute();
|
||||
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$count = $stmt->rowCount();
|
||||
|
||||
if ($count > 0) {
|
||||
$stored_password = $data[0]['password'];
|
||||
if (password_verify($password, $stored_password)) {
|
||||
unset($data[0]['password']);
|
||||
echo json_encode([
|
||||
"status" => "success",
|
||||
"count" => $count,
|
||||
"data" => $data
|
||||
]);
|
||||
} else {
|
||||
// The password is incorrect
|
||||
echo json_encode([
|
||||
"status" => "Failure",
|
||||
"data" => "Incorrect password."
|
||||
]);
|
||||
// jsonError("Incorrect password.");
|
||||
}
|
||||
} else {
|
||||
// The user does not exist
|
||||
echo json_encode([
|
||||
"status" => "Failure",
|
||||
"data" => "User does not exist."
|
||||
]);
|
||||
// jsonError("User does not exist.");
|
||||
}
|
||||
$conn->close();
|
||||
|
||||
?>
|
||||
104
auth/loginFromGooglePassenger.php
Executable file
104
auth/loginFromGooglePassenger.php
Executable file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
// استدعاء المعاملات
|
||||
$email = filterRequest('email');
|
||||
$id = filterRequest('id');
|
||||
$platform = filterRequest("platform") ?: 'unknown';
|
||||
$appName = filterRequest("appName") ?: 'unknown';
|
||||
|
||||
// تشفير الإيميل لأنه يُرسل من التطبيق غير مشفّر
|
||||
$email = $encryptionHelper->encryptData($email);
|
||||
|
||||
// تجهيز الاستعلام
|
||||
$sql = "SELECT
|
||||
p.`id`,
|
||||
p.`phone`,
|
||||
p.`email`,
|
||||
p.`gender`,
|
||||
p.`status`,
|
||||
p.`birthdate`,
|
||||
p.`site`,
|
||||
p.`first_name`,
|
||||
p.`last_name`,
|
||||
p.`sosPhone`,
|
||||
p.`education`,
|
||||
p.`employmentType`,
|
||||
p.`maritalStatus`,
|
||||
p.`created_at`,
|
||||
p.`updated_at`,
|
||||
phone_verification_passenger.verified,
|
||||
invitesToPassengers.isInstall,
|
||||
invitesToPassengers.inviteCode,
|
||||
invitesToPassengers.isGiftToken,
|
||||
(SELECT `version` FROM `packageInfo` WHERE platform = :platform AND appName = :appName) AS package,
|
||||
promos.promo_code AS promo,
|
||||
promos.amount AS discount,
|
||||
promos.validity_end_date AS validity,
|
||||
t.token AS fcm_token,
|
||||
t.fingerPrint AS fcm_fingerprint
|
||||
FROM passengers p
|
||||
LEFT JOIN phone_verification_passenger
|
||||
ON phone_verification_passenger.phone_number = p.phone
|
||||
LEFT JOIN invitesToPassengers
|
||||
ON invitesToPassengers.inviterPassengerPhone = p.phone
|
||||
LEFT JOIN promos
|
||||
ON promos.passengerID = p.id
|
||||
LEFT JOIN tokens t
|
||||
ON t.passengerID = p.id
|
||||
WHERE p.email = :email AND p.id = :id AND phone_verification_passenger.verified = '1'
|
||||
LIMIT 1";
|
||||
|
||||
// تنفيذ الاستعلام
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':email', $email);
|
||||
$stmt->bindParam(':id', $id);
|
||||
$stmt->bindParam(':appName', $appName);
|
||||
$stmt->bindParam(':platform', $platform);
|
||||
$stmt->execute();
|
||||
|
||||
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$count = $stmt->rowCount();
|
||||
|
||||
// تجهيز الرد
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if ($count > 0) {
|
||||
foreach ($data as &$row) {
|
||||
// فك تشفير الحقول الحساسة
|
||||
$row['phone'] = $encryptionHelper->decryptData($row['phone']);
|
||||
$row['email'] = $encryptionHelper->decryptData($row['email']);
|
||||
$row['gender'] = $encryptionHelper->decryptData($row['gender']);
|
||||
$row['birthdate'] = $encryptionHelper->decryptData($row['birthdate']);
|
||||
$row['site'] = $encryptionHelper->decryptData($row['site']);
|
||||
$row['first_name'] = $encryptionHelper->decryptData($row['first_name']);
|
||||
$row['last_name'] = $encryptionHelper->decryptData($row['last_name']);
|
||||
$row['sosPhone'] = $encryptionHelper->decryptData($row['sosPhone']);
|
||||
$row['education'] = $encryptionHelper->decryptData($row['education']);
|
||||
$row['employmentType'] = $encryptionHelper->decryptData($row['employmentType']);
|
||||
$row['maritalStatus'] = $encryptionHelper->decryptData($row['maritalStatus']);
|
||||
|
||||
// فك تشفير توكن FCM إذا وجد
|
||||
if (!empty($row['fcm_token'])) {
|
||||
$row['fcm_token'] = $encryptionHelper->decryptData($row['fcm_token']);
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"status" => "success",
|
||||
"count" => $count,
|
||||
"data" => $data
|
||||
]);
|
||||
} else {
|
||||
error_log("User does not exist: " . $email);
|
||||
echo json_encode([
|
||||
"status" => "Failure",
|
||||
"data" => "User does not exist."
|
||||
]);
|
||||
}
|
||||
|
||||
// تنظيف الموارد
|
||||
$stmt = null;
|
||||
$con = null;
|
||||
exit();
|
||||
88
auth/otpmessage.php
Executable file
88
auth/otpmessage.php
Executable file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../connect.php'; // Contains DB connection, filterRequest, printSuccess/Failure, encryptionHelper
|
||||
|
||||
$receiver = filterRequest("phone_number"); // رقم الهاتف
|
||||
|
||||
if (empty($receiver)) {
|
||||
jsonError("Receiver phone number is required.");
|
||||
exit;
|
||||
}
|
||||
|
||||
$username = getenv('SMS_USERNAME');
|
||||
$password = getenv('SMS_PASSWORD_EGYPT'); // Make sure this is the correct variable name for Egypt
|
||||
$sender = getenv('SMS_SENDER');
|
||||
|
||||
|
||||
if (!$username || !$password || !$sender) {
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
$otp = rand(10000, 99999);
|
||||
$message = "Tripz app code is " . $otp;
|
||||
|
||||
$apiUrl = 'https://sms.kazumi.me/api/sms/send-sms';
|
||||
$payload = [
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'language' => 'e' , // Assuming 'e' is for English as per original
|
||||
'sender' => $sender,
|
||||
'receiver' => $receiver,
|
||||
'message' => $message
|
||||
];
|
||||
$jsonPayload = json_encode($payload);
|
||||
$response = callAPI("POST", $apiUrl, $jsonPayload);
|
||||
|
||||
if ($response && isset($response->message) && $response->message == 'Success') {
|
||||
// 3. تخزين في Redis بدلاً من MySQL (أسرع وأكثر أماناً مع TTL تلقائي)
|
||||
if ($redis) {
|
||||
try {
|
||||
$redis->setex("otp:passenger:$receiver", 300, $otp); // صلاحية 5 دقائق
|
||||
jsonSuccess(null, "OTP sent and saved to Redis successfully");
|
||||
} catch (Exception $e) {
|
||||
error_log("Redis Error (OTP): " . $e->getMessage());
|
||||
jsonError("OTP sent but failed to save in Redis");
|
||||
}
|
||||
} else {
|
||||
jsonError("Redis service unavailable");
|
||||
}
|
||||
} else {
|
||||
jsonError("OTP not sent (SMS API failed or invalid response)");
|
||||
}
|
||||
|
||||
// دالة الاتصال بالـ API
|
||||
function callAPI($method, $url, $data) {
|
||||
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_POSTFIELDS => $data,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
"Content-Type: application/json",
|
||||
"Accept: application/json" // Often good to add
|
||||
],
|
||||
CURLOPT_TIMEOUT => 30, // Set a timeout
|
||||
CURLOPT_CONNECTTIMEOUT => 10 // Set a connection timeout
|
||||
]);
|
||||
$api_raw_response = curl_exec($curl);
|
||||
|
||||
if (curl_errno($curl)) {
|
||||
$curl_error_msg = curl_error($curl);
|
||||
$curl_error_no = curl_errno($curl);
|
||||
error_log("cURL Error (callAPI): [{$curl_error_no}] " . $curl_error_msg);
|
||||
curl_close($curl);
|
||||
return false; // Indicate cURL failure clearly
|
||||
}
|
||||
curl_close($curl);
|
||||
|
||||
$decoded_response = json_decode($api_raw_response);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
return null; // Indicate JSON decode failure
|
||||
}
|
||||
error_log("callAPI: Decoded response: " . print_r($decoded_response, true));
|
||||
return $decoded_response;
|
||||
}
|
||||
?>
|
||||
30
auth/packageInfo.php
Normal file
30
auth/packageInfo.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../connect.php';
|
||||
|
||||
$platform = filterRequest("platform");
|
||||
$appName = filterRequest("appName");
|
||||
|
||||
$sql = "SELECT
|
||||
`id`,
|
||||
`platform`,
|
||||
`appName`,
|
||||
`createdAt`,
|
||||
`version`
|
||||
FROM
|
||||
`packageInfo`
|
||||
WHERE
|
||||
platform='$platform' and appName='$appName';";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Print all the records
|
||||
// printData($result);
|
||||
jsonSuccess($data = $result);
|
||||
} else {
|
||||
// Print a failure message
|
||||
jsonError($message = "No records found");
|
||||
}
|
||||
?>
|
||||
0
auth/passengerOTP/error_log
Normal file
0
auth/passengerOTP/error_log
Normal file
42
auth/passengerOTP/sendOtpPassenger.php
Normal file
42
auth/passengerOTP/sendOtpPassenger.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../connect.php';
|
||||
|
||||
$phone_number = filterRequest("phone_number");
|
||||
$token_code = filterRequest("token_code");
|
||||
$expiration_time = filterRequest("expiration_time"); // Assuming this is a timestamp
|
||||
|
||||
// Check if the phone number already exists
|
||||
$sql = "SELECT * FROM `phone_verification_passenger` WHERE `phone_number` = '$phone_number'";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
$rowCount = $stmt->rowCount();
|
||||
|
||||
if ($rowCount > 0) {
|
||||
// The phone number already exists, so update the data
|
||||
$sql = "UPDATE `phone_verification_passenger` SET `token_code` = '$token_code', `expiration_time` = DATE_ADD(NOW(), INTERVAL 5 MINUTE) WHERE `phone_number` = '$phone_number'";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// The update was successful
|
||||
jsonSuccess($message = "Phone verification data updated successfully");
|
||||
} else {
|
||||
// The update was unsuccessful
|
||||
jsonError($message = "Failed to update phone verification data");
|
||||
}
|
||||
} else {
|
||||
// The phone number does not exist, so insert the data
|
||||
$sql = "INSERT INTO `phone_verification_passenger` (`phone_number`, `token_code`, `expiration_time`, `is_verified`, `created_at`) VALUES ('$phone_number', '$token_code', DATE_ADD(NOW(), INTERVAL 5 MINUTE), 0, NOW())";
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// The insertion was successful
|
||||
jsonSuccess($message = "Phone verification data saved successfully");
|
||||
} else {
|
||||
// The insertion was unsuccessful
|
||||
jsonError($message = "Failed to save phone verification data");
|
||||
}
|
||||
}
|
||||
?>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user