Update: 2026-06-29 23:09:43
This commit is contained in:
80
loction_server/siro/ride/location/add.php
Executable file
80
loction_server/siro/ride/location/add.php
Executable file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
//https://location.intaleq.xyz/intaleq/ride/location/add.php
|
||||
try {
|
||||
$driver_id = filterRequest("driver_id");
|
||||
$latitude = filterRequest("latitude");
|
||||
$longitude = filterRequest("longitude");
|
||||
$status = filterRequest("status");
|
||||
$heading = filterRequest("heading");
|
||||
$speed = filterRequest("speed");
|
||||
|
||||
// ملاحظة: قمنا بتجاهل device_timestamp هنا لضمان دقة الترتيب الزمني في السيرفر
|
||||
// إذا كنت تحتاج وقت الهاتف لأغراض الترتيب في حالة انقطاع النت، يفضل إضافته في عمود منفصل مستقبلاً
|
||||
|
||||
// distance قد تأتي باسم totalDistance من التطبيق
|
||||
$distanceRaw = filterRequest("distance");
|
||||
if ($distanceRaw === null || $distanceRaw === '') {
|
||||
$distanceRaw = filterRequest("totalDistance");
|
||||
}
|
||||
|
||||
// تطبيع القيم الرقمية (كما هي في كودك الأصلي)
|
||||
$norm = function($v, $default = 0.0) {
|
||||
if ($v === null) return $default;
|
||||
$v = str_replace(',', '.', trim((string)$v));
|
||||
return is_numeric($v) ? (float)$v : $default;
|
||||
};
|
||||
|
||||
$lat = $norm($latitude, 0.0);
|
||||
$lng = $norm($longitude, 0.0);
|
||||
$head = $norm($heading, 0.0);
|
||||
$spd = $norm($speed, 0.0);
|
||||
$dist = round($norm($distanceRaw, 0.0), 2);
|
||||
|
||||
if ($dist > 99999999.99) { $dist = 99999999.99; }
|
||||
if ($dist < -99999999.99){ $dist = -99999999.99; }
|
||||
|
||||
if (empty($driver_id) || ($lat == 0.0 && $lng == 0.0)) {
|
||||
printFailure("Invalid payload");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// التعديل الجوهري هنا:
|
||||
// ---------------------------------------------------------
|
||||
// تم حذف منطق حساب الوقت بواسطة PHP أو الهاتف.
|
||||
// سنستخدم NOW() داخل جملة SQL مباشرة لضمان توقيت UTC موحد.
|
||||
|
||||
$sql = "INSERT INTO `car_tracks`
|
||||
(`driver_id`,`latitude`,`longitude`,`heading`,`speed`,`distance`,`status`,`created_at`)
|
||||
VALUES
|
||||
(:driver_id, :latitude, :longitude, :heading, :speed, :distance, :status, NOW())";
|
||||
// 👆 استخدمنا NOW() بدلاً من المتغير
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$ok = $stmt->execute([
|
||||
':driver_id' => $driver_id,
|
||||
':latitude' => $lat,
|
||||
':longitude' => $lng,
|
||||
':heading' => $head,
|
||||
':speed' => $spd,
|
||||
':distance' => $dist,
|
||||
':status' => (string)($status ?? 'on'),
|
||||
// ':created_at' => $created_at_to_use, // 👈 تم حذف هذا السطر لأنه لم يعد مطلوباً
|
||||
]);
|
||||
|
||||
if ($ok) {
|
||||
printSuccess("car_tracks saved successfully");
|
||||
} else {
|
||||
printFailure("Failed to save car track");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
// يفضل عدم طباعة تفاصيل الخطأ للمستخدم النهائي في الإنتاج، لكن لا بأس للـ Debug
|
||||
error_log("car_tracks insert error: " . $e->getMessage());
|
||||
printFailure("Database error");
|
||||
} catch (Throwable $e) {
|
||||
error_log("car_tracks insert fatal: " . $e->getMessage());
|
||||
printFailure("Server error");
|
||||
}
|
||||
?>
|
||||
129
loction_server/siro/ride/location/add_batch.php
Executable file
129
loction_server/siro/ride/location/add_batch.php
Executable file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
// add_batch.php
|
||||
include "../../connect.php";
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
try {
|
||||
// 1. استقبال البيانات
|
||||
$driver_id = filterRequest("driver_id");
|
||||
$json_batch = $_POST['batch_data'];
|
||||
|
||||
if (empty($driver_id) || empty($json_batch)) {
|
||||
printFailure("No data received");
|
||||
exit;
|
||||
}
|
||||
|
||||
$points = json_decode($json_batch, true);
|
||||
if (!is_array($points) || count($points) === 0) {
|
||||
printFailure("Invalid JSON");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// الجزء الأول: حساب مدة العمل الإضافية (PHP Calculation)
|
||||
// ---------------------------------------------------------
|
||||
|
||||
// أ. ترتيب النقاط زمنياً للتأكد (احتياطاً)
|
||||
usort($points, function($a, $b) {
|
||||
return strtotime($a['ts']) - strtotime($b['ts']);
|
||||
});
|
||||
|
||||
$batch_added_seconds = 0;
|
||||
$first_point_time = strtotime($points[0]['ts']);
|
||||
|
||||
// ب. جلب آخر وقت مسجل لهذا السائق من قاعدة البيانات
|
||||
// (لحساب الزمن الضائع بين الباتش السابق وأول نقطة في هذا الباتش)
|
||||
$stmtLast = $con->prepare("SELECT created_at FROM car_tracks WHERE driver_id = ? ORDER BY created_at DESC LIMIT 1");
|
||||
$stmtLast->execute([$driver_id]);
|
||||
$lastRow = $stmtLast->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($lastRow) {
|
||||
$last_db_time = strtotime($lastRow['created_at']);
|
||||
$diff_from_db = $first_point_time - $last_db_time;
|
||||
|
||||
// إذا كان الفرق منطقياً (أقل من 5 دقائق) وموجباً، نحسبه
|
||||
if ($diff_from_db > 0 && $diff_from_db < 300) {
|
||||
$batch_added_seconds += $diff_from_db;
|
||||
}
|
||||
}
|
||||
|
||||
// ج. حساب الفروقات داخل الباتش نفسه
|
||||
$prev_time = $first_point_time;
|
||||
|
||||
// نحدد تاريخ هذا الباتش (لنعرف أي يوم نحدث في الجدول اليومي)
|
||||
$batch_date = date('Y-m-d', $first_point_time);
|
||||
|
||||
foreach ($points as $key => $point) {
|
||||
if ($key === 0) continue; // تخطي النقطة الأولى لأننا قارناها مع الداتابيز
|
||||
|
||||
$current_time = strtotime($point['ts']);
|
||||
$diff = $current_time - $prev_time;
|
||||
|
||||
// تجاهل القفزات الكبيرة (أكثر من 5 دقائق)
|
||||
if ($diff > 0 && $diff < 300) {
|
||||
$batch_added_seconds += $diff;
|
||||
}
|
||||
$prev_time = $current_time;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// الجزء الثاني: إدخال التراكات (Bulk Insert) - كودك الأصلي
|
||||
// ---------------------------------------------------------
|
||||
|
||||
$values = [];
|
||||
$placeholders = [];
|
||||
|
||||
foreach ($points as $point) {
|
||||
$lat = $point['lat'] ?? 0;
|
||||
$lng = $point['lng'] ?? 0;
|
||||
$spd = $point['spd'] ?? 0;
|
||||
$head = $point['head'] ?? 0;
|
||||
$dist = $point['dst'] ?? 0;
|
||||
$stat = $point['st'] ?? 'off';
|
||||
$time = $point['ts'] ?? date('Y-m-d H:i:s');
|
||||
|
||||
$placeholders[] = "(?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
array_push($values, $driver_id, $lat, $lng, $head, $spd, $dist, $stat, $time);
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO `car_tracks`
|
||||
(`driver_id`, `latitude`, `longitude`, `heading`, `speed`, `distance`, `status`, `created_at`)
|
||||
VALUES " . implode(', ', $placeholders);
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$ok = $stmt->execute($values);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// الجزء الثالث: تحديث جدول الملخص اليومي (The Smart Update)
|
||||
// ---------------------------------------------------------
|
||||
|
||||
if ($ok && $batch_added_seconds > 0) {
|
||||
// نستخدم ON DUPLICATE KEY UPDATE:
|
||||
// إذا كان السائق موجوداً لهذا اليوم، أضف الثواني للرصيد الموجود
|
||||
// إذا لم يكن موجوداً، أنشئ سجلاً جديداً
|
||||
|
||||
$sqlSummary = "INSERT INTO `driver_daily_summary` (`driver_id`, `date`, `total_seconds`)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE `total_seconds` = `total_seconds` + VALUES(`total_seconds`)";
|
||||
|
||||
$stmtSum = $con->prepare($sqlSummary);
|
||||
$stmtSum->execute([$driver_id, $batch_date, $batch_added_seconds]);
|
||||
}
|
||||
|
||||
if ($ok) {
|
||||
echo json_encode(array(
|
||||
"status" => "success",
|
||||
"count" => count($points),
|
||||
"added_seconds" => $batch_added_seconds // للتتبع فقط
|
||||
));
|
||||
} else {
|
||||
printFailure("Failed to insert batch");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
error_log("Batch insert error: " . $e->getMessage());
|
||||
printFailure("Database error");
|
||||
} catch (Throwable $e) {
|
||||
printFailure("Server error");
|
||||
}
|
||||
?>
|
||||
34
loction_server/siro/ride/location/addpassengerLocation.php
Executable file
34
loction_server/siro/ride/location/addpassengerLocation.php
Executable file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
$passengerId = filterRequest("passengerId");
|
||||
$lat = filterRequest("lat");
|
||||
$lng = filterRequest("lng");
|
||||
$rideId = filterRequest("rideId");
|
||||
|
||||
// Validate the latitude and longitude
|
||||
if ($lat === '' || $lng === '') {
|
||||
printFailure("Latitude and longitude cannot be empty");
|
||||
exit;
|
||||
}
|
||||
|
||||
// Prepare an SQL statement with placeholders
|
||||
$sql = "INSERT INTO `passengerlocation`( `passengerId`, `lat`, `lng`, `rideId`) VALUES (:passengerId, :lat, :lng, :rideId)";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// Bind the parameters to the SQL query
|
||||
$stmt->bindParam(':passengerId', $passengerId);
|
||||
$stmt->bindParam(':lat', $lat);
|
||||
$stmt->bindParam(':lng', $lng);
|
||||
$stmt->bindParam(':rideId', $rideId);
|
||||
|
||||
// Execute the statement
|
||||
if ($stmt->execute()) {
|
||||
// Print a success message
|
||||
printSuccess("Passenger location saved successfully");
|
||||
} else {
|
||||
// Print a failure message
|
||||
printFailure("Failed to save passenger location");
|
||||
}
|
||||
?>
|
||||
20
loction_server/siro/ride/location/delete.php
Normal file
20
loction_server/siro/ride/location/delete.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?
|
||||
|
||||
include "../../connect.php";
|
||||
|
||||
$driver_id = filterRequest("driver_id");
|
||||
|
||||
$sql = "DELETE FROM `car_locations` WHERE `driver_id` = $driver_id";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Print a success message
|
||||
printSuccess($message = "Car location deleted successfully");
|
||||
} else {
|
||||
// Print a failure message
|
||||
printFailure($message = "Failed to delete car location");
|
||||
}
|
||||
|
||||
?>
|
||||
146
loction_server/siro/ride/location/get.php
Executable file
146
loction_server/siro/ride/location/get.php
Executable file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
// Set timezone for PHP logs only (Keep DB on UTC)
|
||||
date_default_timezone_set('Asia/Amman');
|
||||
|
||||
try {
|
||||
// 1) Read and validate coordinates
|
||||
$southwestLat = filterRequest("southwestLat");
|
||||
$southwestLon = filterRequest("southwestLon");
|
||||
$northeastLat = filterRequest("northeastLat");
|
||||
$northeastLon = filterRequest("northeastLon");
|
||||
|
||||
if ($southwestLat === false || $southwestLon === false ||
|
||||
$northeastLat === false || $northeastLon === false) {
|
||||
printFailure("Invalid coordinates provided");
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fixed time window in seconds
|
||||
$freshSeconds = 180; // 3 minutes
|
||||
|
||||
// =================================================================
|
||||
// OPTIMIZATION: Create a Bounding Box Polygon in WKT format
|
||||
// We create a geometric shape (a rectangle) that represents the map area.
|
||||
// The SQL query will now find all points *inside* this shape.
|
||||
// The format is POLYGON((lon lat, lon lat, ...))
|
||||
// =================================================================
|
||||
$boundingBoxWKT = sprintf(
|
||||
'POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))',
|
||||
$southwestLon, $southwestLat,
|
||||
$northeastLon, $southwestLat,
|
||||
$northeastLon, $northeastLat,
|
||||
$southwestLon, $northeastLat,
|
||||
$southwestLon, $southwestLat
|
||||
);
|
||||
|
||||
// =================================================================
|
||||
// OPTIMIZATION: Modified SQL Query
|
||||
// - We replaced the two `BETWEEN` clauses with a single, highly efficient
|
||||
// `ST_CONTAINS` function.
|
||||
// - `ST_GeomFromText` converts our text polygon into a geometry object.
|
||||
// - `ST_CONTAINS` uses the SPATIAL INDEX to rapidly find all `location_point`s
|
||||
// that are within our bounding box.
|
||||
// =================================================================
|
||||
$sql = "
|
||||
SELECT
|
||||
NOW() AS serverNow,
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.phone,
|
||||
d.email,
|
||||
d.birthdate,
|
||||
d.first_name,
|
||||
d.last_name,
|
||||
d.gender,
|
||||
d.maritalStatus,
|
||||
cr.make AS make,
|
||||
cr.car_plate AS car_plate,
|
||||
cr.model AS model,
|
||||
cr.color AS color,
|
||||
cr.vin AS vin,
|
||||
cr.color_hex AS color_hex,
|
||||
cr.year AS year,
|
||||
dt.token AS token,
|
||||
COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver
|
||||
FROM car_locations cl
|
||||
JOIN driver d ON d.id = cl.driver_id
|
||||
LEFT JOIN CarRegistration cr ON cr.driverID = cl.driver_id
|
||||
LEFT JOIN driverToken dt ON dt.captain_id = cl.driver_id
|
||||
LEFT JOIN (
|
||||
SELECT driver_id, AVG(rating) AS ratingDriver
|
||||
FROM ratingDriver
|
||||
GROUP BY driver_id
|
||||
) rdAvg ON rdAvg.driver_id = cl.driver_id
|
||||
WHERE
|
||||
-- This is the optimized spatial condition
|
||||
ST_CONTAINS(ST_GeomFromText(:boundingBox, 4326), cl.location_point)
|
||||
AND cl.status = 'off'
|
||||
AND cl.updated_at >= NOW() - INTERVAL :freshSeconds SECOND
|
||||
AND COALESCE(cr.year, 0) > 2000
|
||||
AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%')
|
||||
ORDER BY cl.updated_at DESC, ratingDriver DESC
|
||||
LIMIT 5
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// Bind the new bounding box parameter
|
||||
$stmt->bindValue(':boundingBox', $boundingBoxWKT);
|
||||
$stmt->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$rows) {
|
||||
printFailure("No car locations found");
|
||||
exit;
|
||||
}
|
||||
|
||||
// Decryption and age calculation logic remains the same
|
||||
$fieldsToDecrypt = [
|
||||
'phone','email','gender','birthdate',
|
||||
'first_name','last_name','maritalStatus',
|
||||
'token','make','car_plate','vin'
|
||||
];
|
||||
|
||||
foreach ($rows as &$row) {
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null && $row[$field] !== '') {
|
||||
try { $row[$field] = $encryptionHelper->decryptData($row[$field]); }
|
||||
catch (Exception $e) { $row[$field] = null; }
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($row['birthdate'])) {
|
||||
try {
|
||||
$birthdate = new DateTime($row['birthdate']);
|
||||
$today = new DateTime();
|
||||
$row['age'] = $today->diff($birthdate)->y;
|
||||
} catch (Exception $e) { $row['age'] = null; }
|
||||
} else {
|
||||
$row['age'] = null;
|
||||
}
|
||||
|
||||
if (isset($row['serverNow'], $row['updated_at'])) {
|
||||
error_log('PHP Now: '.date('Y-m-d H:i:s')
|
||||
.' | MySQL Now: '.$row['serverNow']
|
||||
.' | updated_at: '.$row['updated_at']);
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
printSuccess($rows);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
} catch (Throwable $e) {
|
||||
printFailure("Internal error: " . $e->getMessage());
|
||||
}
|
||||
120
loction_server/siro/ride/location/getBalash.php
Executable file
120
loction_server/siro/ride/location/getBalash.php
Executable file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
try {
|
||||
// 1) قراءة والتحقق من الإحداثيات
|
||||
$southwestLat = filterRequest("southwestLat");
|
||||
$southwestLon = filterRequest("southwestLon");
|
||||
$northeastLat = filterRequest("northeastLat");
|
||||
$northeastLon = filterRequest("northeastLon");
|
||||
|
||||
if ($southwestLat === false || $southwestLon === false ||
|
||||
$northeastLat === false || $northeastLon === false) {
|
||||
printFailure("Invalid coordinates provided");
|
||||
exit;
|
||||
}
|
||||
|
||||
// نافذة زمنية ثابتة (بدون توسيع)
|
||||
$freshSeconds = 180; // 3 دقائق
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.phone,
|
||||
d.email,
|
||||
d.birthdate,
|
||||
d.first_name,
|
||||
d.last_name,
|
||||
d.gender,
|
||||
d.maritalStatus,
|
||||
cr.make,
|
||||
cr.car_plate,
|
||||
cr.model,
|
||||
cr.color,
|
||||
cr.vin,
|
||||
cr.color_hex,
|
||||
cr.year,
|
||||
dt.token,
|
||||
COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver,
|
||||
COALESCE(rdAvg.ratingCount, 0) AS ratingCount
|
||||
FROM car_locations cl
|
||||
LEFT JOIN driver d ON d.id = cl.driver_id
|
||||
LEFT JOIN CarRegistration cr ON cr.driverID = cl.driver_id
|
||||
LEFT JOIN driverToken dt ON dt.captain_id = cl.driver_id
|
||||
LEFT JOIN (
|
||||
SELECT driver_id, AVG(rating) AS ratingDriver, COUNT(id) AS ratingCount
|
||||
FROM ratingDriver
|
||||
GROUP BY driver_id
|
||||
) rdAvg ON rdAvg.driver_id = cl.driver_id
|
||||
WHERE
|
||||
cl.latitude BETWEEN :southwestLat AND :northeastLat
|
||||
AND cl.longitude BETWEEN :southwestLon AND :northeastLon
|
||||
AND cl.status = 'off'
|
||||
AND cl.updated_at >= NOW() - INTERVAL :freshSeconds SECOND
|
||||
AND COALESCE(cr.year, 0) < 2000
|
||||
AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%')
|
||||
ORDER BY
|
||||
ratingDriver DESC, -- ⭐ الأولوية للتقييم
|
||||
ratingCount DESC, -- ثم الأكثر حصولاً على تقييمات
|
||||
cl.updated_at DESC -- ثم الأحدث تحديثًا كفاصل
|
||||
LIMIT 5
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindValue(':southwestLat', $southwestLat);
|
||||
$stmt->bindValue(':southwestLon', $southwestLon);
|
||||
$stmt->bindValue(':northeastLat', $northeastLat);
|
||||
$stmt->bindValue(':northeastLon', $northeastLon);
|
||||
$stmt->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$rows) {
|
||||
printFailure("No car locations found");
|
||||
exit;
|
||||
}
|
||||
|
||||
// تفكيك التشفير + حساب العمر
|
||||
$fieldsToDecrypt = [
|
||||
'phone','email','gender','birthdate',
|
||||
'first_name','last_name','maritalStatus',
|
||||
'token','make','car_plate','vin'
|
||||
];
|
||||
|
||||
foreach ($rows as &$row) {
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null && $row[$field] !== '') {
|
||||
try { $row[$field] = $encryptionHelper->decryptData($row[$field]); }
|
||||
catch (Exception $e) { $row[$field] = null; }
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($row['birthdate'])) {
|
||||
try {
|
||||
$birthDate = new DateTime($row['birthdate']);
|
||||
$today = new DateTime();
|
||||
$row['age'] = $today->diff($birthDate)->y;
|
||||
} catch (Exception $e) {
|
||||
$row['age'] = null;
|
||||
}
|
||||
} else {
|
||||
$row['age'] = null;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
printSuccess($rows);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
} catch (Throwable $e) {
|
||||
printFailure("Internal error: " . $e->getMessage());
|
||||
}
|
||||
124
loction_server/siro/ride/location/getComfort.php
Executable file
124
loction_server/siro/ride/location/getComfort.php
Executable file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
try {
|
||||
// ✅ قراءة والتحقق من الإحداثيات
|
||||
$southwestLat = filterRequest("southwestLat");
|
||||
$southwestLon = filterRequest("southwestLon");
|
||||
$northeastLat = filterRequest("northeastLat");
|
||||
$northeastLon = filterRequest("northeastLon");
|
||||
|
||||
if ($southwestLat === false || $southwestLon === false ||
|
||||
$northeastLat === false || $northeastLon === false) {
|
||||
printFailure("Invalid coordinates provided");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ⏱️ نافذة زمنية ثابتة بالثواني (بدّلها عند الحاجة)
|
||||
$freshSeconds = 180; // 3 دقائق
|
||||
|
||||
// ✅ الاستعلام الآمن والمهيأ
|
||||
$sql = "
|
||||
SELECT
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.phone,
|
||||
d.email,
|
||||
d.birthdate,
|
||||
d.first_name,
|
||||
d.last_name,
|
||||
d.gender,
|
||||
d.maritalStatus,
|
||||
cr.make,
|
||||
cr.car_plate,
|
||||
cr.model,
|
||||
cr.color,
|
||||
cr.vin,
|
||||
cr.color_hex,
|
||||
cr.year,
|
||||
dt.token,
|
||||
COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver,
|
||||
COALESCE(rdAvg.ratingCount, 0) AS ratingCount
|
||||
FROM car_locations cl
|
||||
LEFT JOIN driver d ON d.id = cl.driver_id
|
||||
LEFT JOIN CarRegistration cr ON cr.driverID = cl.driver_id
|
||||
LEFT JOIN driverToken dt ON dt.captain_id = cl.driver_id
|
||||
LEFT JOIN (
|
||||
SELECT driver_id, AVG(rating) AS ratingDriver, COUNT(*) AS ratingCount
|
||||
FROM ratingDriver
|
||||
GROUP BY driver_id
|
||||
) rdAvg ON rdAvg.driver_id = cl.driver_id
|
||||
WHERE
|
||||
cl.latitude BETWEEN :southwestLat AND :northeastLat
|
||||
AND cl.longitude BETWEEN :southwestLon AND :northeastLon
|
||||
AND cl.status = 'off'
|
||||
AND cl.updated_at >= NOW() - INTERVAL :freshSeconds SECOND
|
||||
AND COALESCE(cr.year, 0) > 2017
|
||||
AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%')
|
||||
ORDER BY
|
||||
ratingDriver DESC, -- ⭐ الأولوية للأعلى تقييماً
|
||||
ratingCount DESC, -- ثم الأكثر حصولاً على تقييمات
|
||||
cl.updated_at DESC -- ثم الأحدث تحديثاً كفاصل
|
||||
LIMIT 5
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindValue(':southwestLat', $southwestLat);
|
||||
$stmt->bindValue(':southwestLon', $southwestLon);
|
||||
$stmt->bindValue(':northeastLat', $northeastLat);
|
||||
$stmt->bindValue(':northeastLon', $northeastLon);
|
||||
$stmt->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($car_locations) {
|
||||
// ✅ فك التشفير (مع حماية الأخطاء)
|
||||
$fieldsToDecrypt = [
|
||||
'phone','email','gender','birthdate',
|
||||
'first_name','last_name','maritalStatus',
|
||||
'token','make','car_plate','vin'
|
||||
];
|
||||
|
||||
foreach ($car_locations as &$row) {
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null && $row[$field] !== '') {
|
||||
try {
|
||||
$row[$field] = $encryptionHelper->decryptData($row[$field]);
|
||||
} catch (Exception $e) {
|
||||
$row[$field] = null; // تجاهل الفشل وأكمل
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ حساب العمر بعد فك التشفير
|
||||
if (!empty($row['birthdate'])) {
|
||||
try {
|
||||
$birthDate = new DateTime($row['birthdate']);
|
||||
$today = new DateTime();
|
||||
$row['age'] = $today->diff($birthDate)->y;
|
||||
} catch (Exception $e) {
|
||||
$row['age'] = null;
|
||||
}
|
||||
} else {
|
||||
$row['age'] = null;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
printSuccess($car_locations);
|
||||
} else {
|
||||
printFailure("No car locations found");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
} catch (Throwable $e) {
|
||||
printFailure("Internal error: " . $e->getMessage());
|
||||
}
|
||||
125
loction_server/siro/ride/location/getDelivery.php
Executable file
125
loction_server/siro/ride/location/getDelivery.php
Executable file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
try {
|
||||
// ✅ قراءة والتحقق من الإحداثيات
|
||||
$southwestLat = filterRequest("southwestLat");
|
||||
$southwestLon = filterRequest("southwestLon");
|
||||
$northeastLat = filterRequest("northeastLat");
|
||||
$northeastLon = filterRequest("northeastLon");
|
||||
|
||||
if ($southwestLat === false || $southwestLon === false ||
|
||||
$northeastLat === false || $northeastLon === false) {
|
||||
printFailure("Invalid coordinates provided");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ⏱️ نافذة زمنية ثابتة (ثواني)
|
||||
$freshSeconds = 180; // 3 دقائق — عدّلها إذا لزم
|
||||
|
||||
// ✅ الاستعلام الآمن والمهيأ
|
||||
$sql = "
|
||||
SELECT
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.phone,
|
||||
d.email,
|
||||
d.birthdate,
|
||||
d.first_name,
|
||||
d.last_name,
|
||||
d.gender,
|
||||
d.maritalStatus,
|
||||
cr.make,
|
||||
cr.car_plate,
|
||||
cr.model,
|
||||
cr.color,
|
||||
cr.vin,
|
||||
cr.color_hex,
|
||||
cr.year,
|
||||
dt.token,
|
||||
COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver,
|
||||
COALESCE(rdAvg.ratingCount, 0) AS ratingCount
|
||||
FROM car_locations cl
|
||||
LEFT JOIN driver d ON d.id = cl.driver_id
|
||||
LEFT JOIN CarRegistration cr ON cr.driverID = cl.driver_id
|
||||
LEFT JOIN driverToken dt ON dt.captain_id = cl.driver_id
|
||||
LEFT JOIN (
|
||||
SELECT driver_id, AVG(rating) AS ratingDriver, COUNT(*) AS ratingCount
|
||||
FROM ratingDriver
|
||||
GROUP BY driver_id
|
||||
) rdAvg ON rdAvg.driver_id = cl.driver_id
|
||||
WHERE
|
||||
cl.latitude BETWEEN :southwestLat AND :northeastLat
|
||||
AND cl.longitude BETWEEN :southwestLon AND :northeastLon
|
||||
AND cl.status = 'off'
|
||||
AND cl.updated_at >= NOW() - INTERVAL :freshSeconds SECOND
|
||||
-- ⛓️ اختيار فقط الدراجات
|
||||
AND (cr.make LIKE '%دراج%' OR cr.model LIKE '%دراج%')
|
||||
ORDER BY
|
||||
ratingDriver DESC, -- ⭐ أولاً الأعلى تقييماً
|
||||
ratingCount DESC, -- ثم الأكثر حصولاً على تقييمات
|
||||
cl.updated_at DESC -- ثم الأحدث تحديثاً كفاصل
|
||||
LIMIT 10
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindValue(':southwestLat', $southwestLat);
|
||||
$stmt->bindValue(':southwestLon', $southwestLon);
|
||||
$stmt->bindValue(':northeastLat', $northeastLat);
|
||||
$stmt->bindValue(':northeastLon', $northeastLon);
|
||||
$stmt->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$car_locations) {
|
||||
printFailure("No car locations found");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ✅ فك التشفير (مع حماية الأخطاء)
|
||||
$fieldsToDecrypt = [
|
||||
'phone','email','gender','birthdate',
|
||||
'first_name','last_name','maritalStatus',
|
||||
'token','make','car_plate','vin'
|
||||
];
|
||||
|
||||
foreach ($car_locations as &$row) {
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null && $row[$field] !== '') {
|
||||
try {
|
||||
$row[$field] = $encryptionHelper->decryptData($row[$field]);
|
||||
} catch (Exception $e) {
|
||||
$row[$field] = null; // تجاهل فشل فك التشفير
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ حساب العمر بعد فك التشفير
|
||||
if (!empty($row['birthdate'])) {
|
||||
try {
|
||||
$birthDate = new DateTime($row['birthdate']);
|
||||
$today = new DateTime();
|
||||
$row['age'] = $today->diff($birthDate)->y;
|
||||
} catch (Exception $e) {
|
||||
$row['age'] = null;
|
||||
}
|
||||
} else {
|
||||
$row['age'] = null;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
printSuccess($car_locations);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
} catch (Throwable $e) {
|
||||
printFailure("Internal error: " . $e->getMessage());
|
||||
}
|
||||
70
loction_server/siro/ride/location/getDrirversLocationsTrack.php
Executable file
70
loction_server/siro/ride/location/getDrirversLocationsTrack.php
Executable file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* Real-time Driver Location Tracker (Last 10 Days - Full Records)
|
||||
*/
|
||||
|
||||
include_once("../../jwtconnect.php");
|
||||
|
||||
header('Content-Type: application/json');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
|
||||
// API Key
|
||||
$expected_api_key = getenv('LOCATION_SERVER_API_KEY');
|
||||
|
||||
function get_api_key()
|
||||
{
|
||||
$headers = getallheaders();
|
||||
if (isset($headers['x-api-key']))
|
||||
return $headers['x-api-key'];
|
||||
if (isset($headers['X-API-KEY']))
|
||||
return $headers['X-API-KEY'];
|
||||
if (isset($_SERVER['HTTP_X_API_KEY']))
|
||||
return $_SERVER['HTTP_X_API_KEY'];
|
||||
return '';
|
||||
}
|
||||
|
||||
$provided_api_key = get_api_key();
|
||||
|
||||
if ($provided_api_key !== $expected_api_key) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Unauthorized access']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// 3. API Input (Optional days parameter, default 1)
|
||||
$days = isset($_GET['days']) ? (int)$_GET['days'] : 1;
|
||||
//if ($days < 1 || $days > 30) $days = 1;
|
||||
if ($days < 1 || $days > 10) $days = 1;
|
||||
|
||||
|
||||
// SQL
|
||||
$sql = "
|
||||
SELECT *
|
||||
FROM car_tracks
|
||||
WHERE created_at >= NOW() - INTERVAL $days DAY
|
||||
ORDER BY created_at DESC
|
||||
";
|
||||
|
||||
try {
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
// جلب كل النتائج دفعة واحدة
|
||||
$records = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'total_records' => count($records),
|
||||
'from' => date('Y-m-d H:i:s', strtotime("-$days days")),
|
||||
'to' => date('Y-m-d H:i:s'),
|
||||
'data' => $records
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'error' => 'Database error',
|
||||
'details' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
$driver_id = filterRequest("driver_id");
|
||||
|
||||
$sql = "SELECT
|
||||
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.gender,
|
||||
cr.model
|
||||
FROM
|
||||
car_locations cl
|
||||
LEFT JOIN driver d ON
|
||||
cl.driver_id = d.id
|
||||
LEFT JOIN CarRegistration cr ON
|
||||
cl.driver_id = cr.driverID
|
||||
WHERE
|
||||
cl.driver_id = '$driver_id'
|
||||
ORDER BY
|
||||
created_at
|
||||
DESC
|
||||
LIMIT 1;";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($car_locations) {
|
||||
// Print the car location data as JSON
|
||||
printSuccess($data = $car_locations);
|
||||
} else {
|
||||
// Print a failure message
|
||||
printFailure($message = "No car locations found");
|
||||
}
|
||||
|
||||
?>
|
||||
126
loction_server/siro/ride/location/getElectric.php
Executable file
126
loction_server/siro/ride/location/getElectric.php
Executable file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
try {
|
||||
// ✅ قراءة والتحقق من الإحداثيات
|
||||
$southwestLat = filterRequest("southwestLat");
|
||||
$southwestLon = filterRequest("southwestLon");
|
||||
$northeastLat = filterRequest("northeastLat");
|
||||
$northeastLon = filterRequest("northeastLon");
|
||||
|
||||
if ($southwestLat === false || $southwestLon === false ||
|
||||
$northeastLat === false || $northeastLon === false) {
|
||||
printFailure("Invalid coordinates provided");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ⏱️ نافذة زمنية ثابتة
|
||||
$freshSeconds = 180; // 3 دقائق
|
||||
|
||||
// ✅ الاستعلام
|
||||
$sql = "
|
||||
SELECT
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.phone,
|
||||
d.email,
|
||||
d.birthdate,
|
||||
d.first_name,
|
||||
d.last_name,
|
||||
d.gender,
|
||||
d.maritalStatus,
|
||||
cr.make,
|
||||
cr.car_plate,
|
||||
cr.model,
|
||||
cr.color,
|
||||
cr.vin,
|
||||
cr.color_hex,
|
||||
cr.year,
|
||||
cr.fuel,
|
||||
dt.token,
|
||||
COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver,
|
||||
COALESCE(rdAvg.ratingCount, 0) AS ratingCount
|
||||
FROM car_locations cl
|
||||
LEFT JOIN driver d ON d.id = cl.driver_id
|
||||
LEFT JOIN CarRegistration cr ON cr.driverID = cl.driver_id
|
||||
LEFT JOIN driverToken dt ON dt.captain_id = cl.driver_id
|
||||
LEFT JOIN (
|
||||
SELECT driver_id, AVG(rating) AS ratingDriver, COUNT(*) AS ratingCount
|
||||
FROM ratingDriver
|
||||
GROUP BY driver_id
|
||||
) rdAvg ON rdAvg.driver_id = cl.driver_id
|
||||
WHERE
|
||||
cl.latitude BETWEEN :southwestLat AND :northeastLat
|
||||
AND cl.longitude BETWEEN :southwestLon AND :northeastLon
|
||||
AND cl.status = 'off'
|
||||
AND cl.updated_at >= NOW() - INTERVAL :freshSeconds SECOND
|
||||
AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%')
|
||||
AND cr.fuel = 'كهربائي'
|
||||
ORDER BY
|
||||
ratingDriver DESC, -- ⭐ الأعلى تقييماً
|
||||
ratingCount DESC, -- ثم الأكثر حصولاً على تقييمات
|
||||
cl.updated_at DESC -- ثم الأحدث تحديثاً
|
||||
LIMIT 10
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindValue(':southwestLat', $southwestLat);
|
||||
$stmt->bindValue(':southwestLon', $southwestLon);
|
||||
$stmt->bindValue(':northeastLat', $northeastLat);
|
||||
$stmt->bindValue(':northeastLon', $northeastLon);
|
||||
$stmt->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$car_locations) {
|
||||
printFailure("No electric car locations found");
|
||||
exit;
|
||||
}
|
||||
|
||||
// ✅ فك التشفير + حساب العمر
|
||||
$fieldsToDecrypt = [
|
||||
'phone','email','gender','birthdate',
|
||||
'first_name','last_name','maritalStatus',
|
||||
'token','make','car_plate','vin'
|
||||
];
|
||||
|
||||
foreach ($car_locations as &$row) {
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null && $row[$field] !== '') {
|
||||
try {
|
||||
$row[$field] = $encryptionHelper->decryptData($row[$field]);
|
||||
} catch (Exception $e) {
|
||||
$row[$field] = null; // تجاهل أي خطأ بفك التشفير
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// حساب العمر
|
||||
if (!empty($row['birthdate'])) {
|
||||
try {
|
||||
$birthDate = new DateTime($row['birthdate']);
|
||||
$today = new DateTime();
|
||||
$row['age'] = $today->diff($birthDate)->y;
|
||||
} catch (Exception $e) {
|
||||
$row['age'] = null;
|
||||
}
|
||||
} else {
|
||||
$row['age'] = null;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
printSuccess($car_locations);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
} catch (Throwable $e) {
|
||||
printFailure("Internal error: " . $e->getMessage());
|
||||
}
|
||||
111
loction_server/siro/ride/location/getFemalDriver.php
Executable file
111
loction_server/siro/ride/location/getFemalDriver.php
Executable file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
try {
|
||||
$southwestLat = filterRequest("southwestLat");
|
||||
$southwestLon = filterRequest("southwestLon");
|
||||
$northeastLat = filterRequest("northeastLat");
|
||||
$northeastLon = filterRequest("northeastLon");
|
||||
|
||||
if ($southwestLat === false || $southwestLon === false ||
|
||||
$northeastLat === false || $northeastLon === false) {
|
||||
printFailure("Invalid coordinates provided");
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.phone,
|
||||
d.email,
|
||||
d.birthdate,
|
||||
d.first_name,
|
||||
d.last_name,
|
||||
d.gender,
|
||||
d.maritalStatus,
|
||||
cr.make,
|
||||
cr.car_plate,
|
||||
cr.model,
|
||||
cr.color,
|
||||
cr.vin,
|
||||
cr.color_hex,
|
||||
cr.year,
|
||||
dt.token,
|
||||
COALESCE(AVG(rd.rating), 0) AS ratingDriver,
|
||||
COUNT(rd.id) AS ratingCount,
|
||||
'' AS age
|
||||
FROM car_locations cl
|
||||
LEFT JOIN driver d ON d.id = cl.driver_id
|
||||
LEFT JOIN CarRegistration cr ON cr.driverID = cl.driver_id
|
||||
LEFT JOIN driverToken dt ON dt.captain_id = cl.driver_id
|
||||
LEFT JOIN ratingDriver rd ON rd.driver_id = cl.driver_id
|
||||
WHERE
|
||||
cl.latitude BETWEEN :southwestLat AND :northeastLat
|
||||
AND cl.longitude BETWEEN :southwestLon AND :northeastLon
|
||||
AND cl.status = 'off'
|
||||
AND cl.updated_at >= NOW() - INTERVAL 180 SECOND
|
||||
AND (cr.make NOT LIKE '%دراجة%' AND cr.model NOT LIKE '%دراجة%')
|
||||
AND d.gender = 'Female'
|
||||
GROUP BY cl.driver_id
|
||||
ORDER BY ratingDriver DESC, ratingCount DESC, cl.updated_at DESC
|
||||
LIMIT 10;
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':southwestLat', $southwestLat);
|
||||
$stmt->bindParam(':southwestLon', $southwestLon);
|
||||
$stmt->bindParam(':northeastLat', $northeastLat);
|
||||
$stmt->bindParam(':northeastLon', $northeastLon);
|
||||
$stmt->execute();
|
||||
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($rows) {
|
||||
$fieldsToDecrypt = [
|
||||
'phone','email','gender','birthdate',
|
||||
'first_name','last_name','token',
|
||||
'make','car_plate','vin','maritalStatus'
|
||||
];
|
||||
|
||||
foreach ($rows as &$row) {
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null && $row[$field] !== '') {
|
||||
try {
|
||||
$row[$field] = $encryptionHelper->decryptData($row[$field]);
|
||||
} catch (Exception $e) {
|
||||
$row[$field] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// حساب العمر
|
||||
if (!empty($row['birthdate'])) {
|
||||
try {
|
||||
$birthDate = new DateTime($row['birthdate']);
|
||||
$today = new DateTime();
|
||||
$row['age'] = $today->diff($birthDate)->y;
|
||||
} catch (Exception $e) {
|
||||
$row['age'] = null;
|
||||
}
|
||||
} else {
|
||||
$row['age'] = null;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
printSuccess($rows);
|
||||
} else {
|
||||
printFailure("No car locations found");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
} catch (Throwable $e) {
|
||||
printFailure("Internal error: " . $e->getMessage());
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
$rideId = filterRequest("rideId");
|
||||
|
||||
$sql = "SELECT
|
||||
*
|
||||
FROM
|
||||
`passengerlocation` pl
|
||||
WHERE
|
||||
pl.rideId = '$rideId'
|
||||
ORDER BY
|
||||
pl.createdAt
|
||||
DESC
|
||||
LIMIT 1";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($car_locations) {
|
||||
// Print the car location data as JSON
|
||||
printSuccess($data = $car_locations);
|
||||
} else {
|
||||
// Print a failure message
|
||||
printFailure($message = "No car locations found");
|
||||
}
|
||||
|
||||
?>
|
||||
42
loction_server/siro/ride/location/getLocationParents.php
Normal file
42
loction_server/siro/ride/location/getLocationParents.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
$driver_id = filterRequest("driver_id");
|
||||
|
||||
$sql = "SELECT
|
||||
car_locations.id,
|
||||
car_locations.driver_id,
|
||||
car_locations.latitude,
|
||||
car_locations.longitude,
|
||||
car_locations.heading,
|
||||
car_locations.speed,
|
||||
car_locations.`status`,
|
||||
car_locations.created_at,
|
||||
car_locations.updated_at,
|
||||
`driver`.`gender`,
|
||||
CarRegistration.model
|
||||
FROM
|
||||
car_locations
|
||||
LEFT JOIN `driver` ON `driver`.`id` = car_locations.driver_id
|
||||
LEFT JOIN `CarRegistration`
|
||||
ON `CarRegistration`.`driverID` = CarRegistration.driverID
|
||||
WHERE
|
||||
driver_id = '$driver_id'
|
||||
ORDER BY
|
||||
created_at
|
||||
DESC
|
||||
LIMIT 1;";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute();
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($car_locations) {
|
||||
// Print the car location data as JSON
|
||||
printSuccess($data = $car_locations);
|
||||
} else {
|
||||
// Print a failure message
|
||||
printFailure($message = "No car locations found");
|
||||
}
|
||||
|
||||
?>
|
||||
112
loction_server/siro/ride/location/getPinkBike.php
Executable file
112
loction_server/siro/ride/location/getPinkBike.php
Executable file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
try {
|
||||
$southwestLat = filterRequest("southwestLat");
|
||||
$southwestLon = filterRequest("southwestLon");
|
||||
$northeastLat = filterRequest("northeastLat");
|
||||
$northeastLon = filterRequest("northeastLon");
|
||||
|
||||
if ($southwestLat === false || $southwestLon === false || $northeastLat === false || $northeastLon === false) {
|
||||
printFailure("Invalid coordinates provided");
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.phone,
|
||||
d.email,
|
||||
d.birthdate,
|
||||
d.first_name,
|
||||
d.last_name,
|
||||
d.gender,
|
||||
d.maritalStatus,
|
||||
cr.make,
|
||||
cr.car_plate,
|
||||
cr.model,
|
||||
cr.color,
|
||||
cr.vin,
|
||||
cr.color_hex,
|
||||
cr.year,
|
||||
dt.token,
|
||||
'' AS age,
|
||||
COALESCE(rdAvg.ratingDriver, 0) AS ratingDriver,
|
||||
rdAvg.ratingCount
|
||||
FROM
|
||||
car_locations cl
|
||||
LEFT JOIN driver d ON d.id = cl.driver_id
|
||||
LEFT JOIN CarRegistration cr ON cr.driverID = cl.driver_id
|
||||
LEFT JOIN driverToken dt ON dt.captain_id = cl.driver_id
|
||||
LEFT JOIN (
|
||||
SELECT driver_id, AVG(rating) AS ratingDriver, COUNT(id) AS ratingCount
|
||||
FROM ratingDriver
|
||||
GROUP BY driver_id
|
||||
) rdAvg ON rdAvg.driver_id = cl.driver_id
|
||||
WHERE
|
||||
cl.latitude BETWEEN :southwestLat AND :northeastLat
|
||||
AND cl.longitude BETWEEN :southwestLon AND :northeastLon
|
||||
AND cl.status = 'off'
|
||||
AND cl.updated_at >= NOW() - INTERVAL 5 SECOND
|
||||
AND (cr.make LIKE '%دراجة%' OR cr.model LIKE '%دراجة%')
|
||||
GROUP BY cl.driver_id
|
||||
ORDER BY ratingDriver DESC, cl.updated_at DESC
|
||||
LIMIT 10;
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':southwestLat', $southwestLat);
|
||||
$stmt->bindParam(':southwestLon', $southwestLon);
|
||||
$stmt->bindParam(':northeastLat', $northeastLat);
|
||||
$stmt->bindParam(':northeastLon', $northeastLon);
|
||||
$stmt->execute();
|
||||
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($rows) {
|
||||
$fieldsToDecrypt = [
|
||||
'phone', 'email', 'gender', 'birthdate',
|
||||
'first_name', 'last_name', 'maritalStatus', 'token',
|
||||
'make', 'car_plate', 'vin'
|
||||
];
|
||||
|
||||
$filteredRows = [];
|
||||
|
||||
foreach ($rows as &$row) {
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field])) {
|
||||
$row[$field] = $encryptionHelper->decryptData($row[$field]);
|
||||
}
|
||||
}
|
||||
|
||||
// فلترة حسب الجنس
|
||||
if (strtolower($row['gender']) !== 'female') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// حساب العمر
|
||||
if (!empty($row['birthdate'])) {
|
||||
$birthDate = new DateTime($row['birthdate']);
|
||||
$today = new DateTime();
|
||||
$row['age'] = $today->diff($birthDate)->y;
|
||||
} else {
|
||||
$row['age'] = null;
|
||||
}
|
||||
|
||||
$filteredRows[] = $row;
|
||||
}
|
||||
|
||||
printSuccess($filteredRows);
|
||||
} else {
|
||||
printFailure("No car locations found");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
}
|
||||
66
loction_server/siro/ride/location/getRidesDriverByDay.php
Executable file
66
loction_server/siro/ride/location/getRidesDriverByDay.php
Executable file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
$driver_id = filterRequest("driver_id");
|
||||
$current_month = date('m');
|
||||
$current_year = date('Y');
|
||||
|
||||
// Get the first and last days of the current month.
|
||||
$first_day_of_month = date('Y-m-d', strtotime($current_year . '-' . $current_month . '-01'));
|
||||
$last_day_of_month = date('Y-m-d', strtotime($current_year . '-' . $current_month . '-' . cal_days_in_month(CAL_GREGORIAN, $current_month, $current_year)));
|
||||
|
||||
// Create a SQL query to select the total duration for the driver for each day in the current month.
|
||||
$sql = "SELECT
|
||||
DATE(`ride`.created_at) AS day,
|
||||
COUNT(`ride`.`id`) AS countRide,
|
||||
SUM(`ride`.`price`) AS pricePerDay,
|
||||
(
|
||||
SELECT
|
||||
SUM(`ride`.`price`)
|
||||
FROM
|
||||
`ride`
|
||||
WHERE
|
||||
`ride`.`driver_id` = :driver_id_total AND `ride`.`created_at` >= :first_day_total AND `ride`.created_at < :last_day_total AND `ride`.`status` = 'Finished'
|
||||
) AS totalPrice,
|
||||
(
|
||||
SELECT
|
||||
COUNT(`ride`.`id`)
|
||||
FROM
|
||||
`ride`
|
||||
WHERE
|
||||
`ride`.`driver_id` = :driver_id_count AND `ride`.`created_at` >= :first_day_count AND `ride`.created_at < :last_day_count AND `ride`.`status` = 'Finished'
|
||||
) AS totalCount
|
||||
FROM
|
||||
`ride`
|
||||
WHERE
|
||||
`ride`.`driver_id` = :driver_id_main AND `ride`.`created_at` >= :first_day_main AND `ride`.created_at < :last_day_main AND `ride`.`status` = 'Finished'
|
||||
GROUP BY
|
||||
day
|
||||
ORDER BY
|
||||
day ASC;";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// Bind each parameter uniquely
|
||||
$stmt->bindParam(':driver_id_total', $driver_id, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':first_day_total', $first_day_of_month, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':last_day_total', $last_day_of_month, PDO::PARAM_STR);
|
||||
|
||||
$stmt->bindParam(':driver_id_count', $driver_id, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':first_day_count', $first_day_of_month, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':last_day_count', $last_day_of_month, PDO::PARAM_STR);
|
||||
|
||||
$stmt->bindParam(':driver_id_main', $driver_id, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':first_day_main', $first_day_of_month, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':last_day_main', $last_day_of_month, PDO::PARAM_STR);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if ($car_locations) {
|
||||
// Print the car location data as JSON
|
||||
printSuccess($data = $car_locations);
|
||||
} else {
|
||||
// Print a failure message
|
||||
printFailure($message = "No car locations found");
|
||||
}
|
||||
?>
|
||||
119
loction_server/siro/ride/location/getSpeed.php
Executable file
119
loction_server/siro/ride/location/getSpeed.php
Executable file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
// Get and filter input
|
||||
$southwestLat = filterRequest("southwestLat");
|
||||
$southwestLon = filterRequest("southwestLon");
|
||||
$northeastLat = filterRequest("northeastLat");
|
||||
$northeastLon = filterRequest("northeastLon");
|
||||
|
||||
// Validate input
|
||||
if (is_null($southwestLat) || is_null($southwestLon) || is_null($northeastLat) || is_null($northeastLon)) {
|
||||
echo json_encode(['status' => 'failure', 'message' => 'Missing required parameters']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// نافذة زمنية مناسبة (3 دقائق)
|
||||
$freshSeconds = 180;
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.phone,
|
||||
d.email,
|
||||
d.birthdate,
|
||||
d.first_name,
|
||||
d.last_name,
|
||||
d.gender,
|
||||
d.maritalStatus,
|
||||
cr.make,
|
||||
cr.car_plate,
|
||||
cr.model,
|
||||
cr.color,
|
||||
cr.vin,
|
||||
cr.color_hex,
|
||||
cr.year,
|
||||
dt.token,
|
||||
COALESCE(rd.ratingDriver, 0) AS ratingDriver,
|
||||
COALESCE(rd.ratingCount, 0) AS ratingCount
|
||||
FROM car_locations cl
|
||||
LEFT JOIN driver d ON d.id = cl.driver_id
|
||||
LEFT JOIN CarRegistration cr ON cr.driverID = cl.driver_id
|
||||
LEFT JOIN driverToken dt ON dt.captain_id = cl.driver_id
|
||||
LEFT JOIN (
|
||||
SELECT driver_id, AVG(rating) AS ratingDriver, COUNT(id) AS ratingCount
|
||||
FROM ratingDriver
|
||||
GROUP BY driver_id
|
||||
) rd ON rd.driver_id = cl.driver_id
|
||||
WHERE
|
||||
cl.latitude BETWEEN :southwestLat AND :northeastLat
|
||||
AND cl.longitude BETWEEN :southwestLon AND :northeastLon
|
||||
AND cl.status = 'off'
|
||||
AND cl.updated_at >= NOW() - INTERVAL :freshSeconds SECOND
|
||||
AND COALESCE(cr.year, 0) > 2000
|
||||
AND (cr.make NOT LIKE '%دراج%' AND cr.model NOT LIKE '%دراج%')
|
||||
ORDER BY
|
||||
ratingDriver DESC,
|
||||
ratingCount DESC,
|
||||
cl.updated_at DESC
|
||||
LIMIT 10;
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':southwestLat', $southwestLat);
|
||||
$stmt->bindParam(':southwestLon', $southwestLon);
|
||||
$stmt->bindParam(':northeastLat', $northeastLat);
|
||||
$stmt->bindParam(':northeastLon', $northeastLon);
|
||||
$stmt->bindValue(':freshSeconds', $freshSeconds, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($car_locations) {
|
||||
$fieldsToDecrypt = [
|
||||
'phone','email','gender','birthdate',
|
||||
'first_name','last_name','token',
|
||||
'make','car_plate','vin','maritalStatus'
|
||||
];
|
||||
|
||||
foreach ($car_locations as &$row) {
|
||||
foreach ($fieldsToDecrypt as $field) {
|
||||
if (isset($row[$field]) && $row[$field] !== null && $row[$field] !== '') {
|
||||
try {
|
||||
$row[$field] = $encryptionHelper->decryptData($row[$field]);
|
||||
} catch (Exception $e) {
|
||||
$row[$field] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ احسب العمر
|
||||
if (!empty($row['birthdate'])) {
|
||||
try {
|
||||
$birthdate = new DateTime($row['birthdate']);
|
||||
$now = new DateTime();
|
||||
$row['age'] = $now->diff($birthdate)->y;
|
||||
} catch (Exception $e) {
|
||||
$row['age'] = null;
|
||||
}
|
||||
} else {
|
||||
$row['age'] = null;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
printSuccess($car_locations);
|
||||
} else {
|
||||
printFailure("No car locations found");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
}
|
||||
44
loction_server/siro/ride/location/getTotalDriverDuration.php
Executable file
44
loction_server/siro/ride/location/getTotalDriverDuration.php
Executable file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
$driver_id = filterRequest("driver_id");
|
||||
|
||||
$current_month = date('m');
|
||||
$current_year = date('Y');
|
||||
|
||||
// Get the first and last days of the current month.
|
||||
$first_day_of_month = date('Y-m-d', strtotime($current_year . '-' . $current_month . '-01'));
|
||||
$last_day_of_month = date('Y-m-d', strtotime($current_year . '-' . $current_month . '-' . cal_days_in_month(CAL_GREGORIAN, $current_month, $current_year)));
|
||||
|
||||
// Create a SQL query to select the total duration for the driver for each day in the current month.
|
||||
$sql = "SELECT
|
||||
DATE(created_at) AS day,
|
||||
SEC_TO_TIME(COUNT(*) * 60) AS total_duration
|
||||
FROM
|
||||
car_tracks
|
||||
WHERE
|
||||
car_tracks.driver_id = :driver_id
|
||||
AND car_tracks.created_at >= :first_day_of_month
|
||||
AND car_tracks.created_at < :last_day_of_month
|
||||
GROUP BY
|
||||
day
|
||||
ORDER BY
|
||||
day ASC;";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':driver_id', $driver_id, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':first_day_of_month', $first_day_of_month, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':last_day_of_month', $last_day_of_month, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($car_locations) {
|
||||
// Print the car location data as JSON
|
||||
printSuccess($data = $car_locations);
|
||||
} else {
|
||||
// Print a failure message
|
||||
printFailure($message = "No car locations found");
|
||||
}
|
||||
|
||||
?>
|
||||
70
loction_server/siro/ride/location/getTotalDriverDurationToday.php
Executable file
70
loction_server/siro/ride/location/getTotalDriverDurationToday.php
Executable file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
// 1. إعدادات التصحيح (Debug) - ضرورية جداً الآن
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, Access-Control-Allow-Origin");
|
||||
header("Access-Control-Allow-Methods: POST, OPTIONS , GET");
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
// 2. تضمين ملف الاتصال
|
||||
if (file_exists("../../connect.php")) {
|
||||
include "../../connect.php";
|
||||
} else {
|
||||
// في حال عدم وجود الملف، ننهي التنفيذ ونطبع السبب
|
||||
die(json_encode(array("status" => "failure", "message" => "Connect file not found")));
|
||||
}
|
||||
|
||||
// 3. التقاط البيانات بذكاء (لحل مشكلة Flutter JSON)
|
||||
// هذا الجزء يفحص: هل البيانات في POST؟ أم في JSON Body؟
|
||||
$driver_id = null;
|
||||
|
||||
if (isset($_POST['driver_id'])) {
|
||||
$driver_id = filterRequest("driver_id");
|
||||
} else {
|
||||
// محاولة قراءة JSON Body (لأن فلاتر يرسل البيانات هكذا غالباً)
|
||||
$jsonInput = json_decode(file_get_contents("php://input"), true);
|
||||
if (isset($jsonInput['driver_id'])) {
|
||||
$driver_id = htmlspecialchars(strip_tags($jsonInput['driver_id']));
|
||||
}
|
||||
}
|
||||
|
||||
// التحقق النهائي
|
||||
if (!$driver_id) {
|
||||
// طباعة الخطأ بوضوح
|
||||
echo json_encode(array("status" => "failure", "message" => "driver_id is missing or empty"));
|
||||
exit;
|
||||
}
|
||||
|
||||
// 4. التنفيذ
|
||||
try {
|
||||
$date = date('Y-m-d');
|
||||
|
||||
$sql = "SELECT total_seconds FROM driver_daily_summary
|
||||
WHERE driver_id = ? AND date = ?";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->execute([$driver_id, $date]);
|
||||
$data = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$duration = "00:00:00";
|
||||
if ($data) {
|
||||
$seconds = $data['total_seconds'];
|
||||
$duration = gmdate("H:i:s", $seconds);
|
||||
}
|
||||
|
||||
// 5. بناء الاستجابة يدوياً لتطابق كود Flutter 100%
|
||||
// الهيكل المطلوب: data['message'][0]['total_duration']
|
||||
$response = array(
|
||||
"status" => "success",
|
||||
"message" => array(
|
||||
array("total_duration" => $duration)
|
||||
)
|
||||
);
|
||||
|
||||
echo json_encode($response);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(array("status" => "failure", "message" => "DB Error: " . $e->getMessage()));
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
|
||||
// Use prepared statement to prevent SQL injection
|
||||
$sql = "
|
||||
SELECT * FROM `server_locations`
|
||||
";
|
||||
|
||||
try {
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($car_locations) {
|
||||
printSuccess($car_locations);
|
||||
} else {
|
||||
printFailure("No car locations found");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
}
|
||||
86
loction_server/siro/ride/location/getfemalbehavior.php
Normal file
86
loction_server/siro/ride/location/getfemalbehavior.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
try {
|
||||
$southwestLat = filterRequest("southwestLat");
|
||||
$southwestLon = filterRequest("southwestLon");
|
||||
$northeastLat = filterRequest("northeastLat");
|
||||
$northeastLon = filterRequest("northeastLon");
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
cl.driver_id,
|
||||
cl.latitude,
|
||||
cl.longitude,
|
||||
cl.heading,
|
||||
cl.speed,
|
||||
cl.status,
|
||||
cl.created_at,
|
||||
cl.updated_at,
|
||||
d.phone,
|
||||
d.email,
|
||||
d.birthdate,
|
||||
d.first_name,
|
||||
d.last_name,
|
||||
d.gender,
|
||||
d.maritalStatus,
|
||||
cr.make,
|
||||
cr.car_plate,
|
||||
cr.model,
|
||||
cr.color,
|
||||
cr.vin,
|
||||
cr.color_hex,
|
||||
cr.year,
|
||||
dt.token,
|
||||
COALESCE(AVG(rd.rating), 0) AS ratingDriver,
|
||||
COUNT(rd.id) AS ratingCount,
|
||||
TIMESTAMPDIFF(YEAR, d.birthdate, CURDATE()) AS age,
|
||||
(
|
||||
SELECT COALESCE(AVG(sub.behavior_score), 100)
|
||||
FROM (
|
||||
SELECT behavior_score
|
||||
FROM driver_behavior db
|
||||
WHERE db.driver_id = cl.driver_id
|
||||
ORDER BY db.id DESC
|
||||
LIMIT 5
|
||||
) AS sub
|
||||
) AS ai_behavior_score
|
||||
FROM
|
||||
car_locations cl
|
||||
LEFT JOIN driver d ON
|
||||
d.id = cl.driver_id
|
||||
LEFT JOIN CarRegistration cr ON
|
||||
cr.driverID = cl.driver_id
|
||||
LEFT JOIN driverToken dt ON
|
||||
dt.captain_id = cl.driver_id
|
||||
LEFT JOIN ratingDriver rd ON
|
||||
rd.driver_id = cl.driver_id
|
||||
WHERE
|
||||
cl.latitude >= :southwestLat AND cl.latitude <= :northeastLat
|
||||
AND cl.longitude >= :southwestLon AND cl.longitude <= :northeastLon
|
||||
AND cl.status = 'off'
|
||||
AND cl.updated_at >= NOW() - INTERVAL 5 SECOND
|
||||
AND (cr.make NOT LIKE '%دراجة%' OR cr.model NOT LIKE '%دراجة%')
|
||||
AND d.gender = 'Female'
|
||||
GROUP BY cl.driver_id
|
||||
ORDER BY ratingDriver DESC, cl.updated_at DESC
|
||||
LIMIT 10;
|
||||
";
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
$stmt->bindParam(':southwestLat', $southwestLat);
|
||||
$stmt->bindParam(':southwestLon', $southwestLon);
|
||||
$stmt->bindParam(':northeastLat', $northeastLat);
|
||||
$stmt->bindParam(':northeastLon', $northeastLon);
|
||||
|
||||
$stmt->execute();
|
||||
$car_locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($car_locations) {
|
||||
printSuccess($car_locations);
|
||||
} else {
|
||||
printFailure("No car locations found");
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
printFailure("Database error: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
59
loction_server/siro/ride/location/save_behavior.php
Normal file
59
loction_server/siro/ride/location/save_behavior.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
// استلام البيانات من Flutter
|
||||
$driver_id = filterRequest("driver_id");
|
||||
$trip_id = filterRequest("trip_id");
|
||||
$max_speed = filterRequest("max_speed");
|
||||
$avg_speed = filterRequest("avg_speed");
|
||||
$hard_brakes = filterRequest("hard_brakes");
|
||||
$total_distance = filterRequest("total_distance");
|
||||
$behavior_score = filterRequest("behavior_score");
|
||||
|
||||
// تحقق من القيم الأساسية
|
||||
if (empty($driver_id) || empty($trip_id)) {
|
||||
// Log the validation error
|
||||
error_log("Driver Behavior Error: Missing driver_id ($driver_id) or trip_id ($trip_id)");
|
||||
printFailure("Missing driver_id or trip_id");
|
||||
exit();
|
||||
}
|
||||
|
||||
try {
|
||||
// إدخال البيانات في جدول driver_behavior
|
||||
$stmt = $con->prepare("
|
||||
INSERT INTO driver_behavior (
|
||||
driver_id, trip_id, max_speed, avg_speed,
|
||||
hard_brakes, total_distance, behavior_score
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
|
||||
$stmt->execute([
|
||||
$driver_id,
|
||||
$trip_id,
|
||||
$max_speed,
|
||||
$avg_speed,
|
||||
$hard_brakes,
|
||||
$total_distance,
|
||||
$behavior_score
|
||||
]);
|
||||
|
||||
// التحقق من نجاح العملية
|
||||
if ($stmt->rowCount() > 0) {
|
||||
printSuccess("Behavior data saved");
|
||||
} else {
|
||||
// Log that the query ran but no rows were inserted
|
||||
error_log("Driver Behavior Warning: Insert executed but 0 rows affected for driver $driver_id");
|
||||
printFailure("Failed to save data");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// --- THIS IS THE TYPE ERROR LOG YOU ASKED FOR ---
|
||||
// This records the exact SQL error (e.g., duplicate entry, foreign key fail) to your server log
|
||||
error_log("Driver Behavior SQL Error: " . $e->getMessage());
|
||||
|
||||
// Return a generic error to the app (or $e->getMessage() if debugging)
|
||||
printFailure("Database Error");
|
||||
}
|
||||
|
||||
exit();
|
||||
?>
|
||||
65
loction_server/siro/ride/location/update.php
Normal file
65
loction_server/siro/ride/location/update.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
include "../../connect.php";
|
||||
|
||||
$driver_id = filterRequest("driver_id");
|
||||
$latitude = filterRequest("latitude");
|
||||
$longitude = filterRequest("longitude");
|
||||
$status = filterRequest("status");
|
||||
$heading = filterRequest("heading");
|
||||
$speed = filterRequest("speed");
|
||||
$distance = filterRequest("distance");
|
||||
|
||||
// 1. قمنا بحذف السطر التالي لأنه مصدر المشكلة
|
||||
// $updated_at = date("Y-m-d H:i:s");
|
||||
|
||||
// Basic validation
|
||||
if (!$driver_id || !$latitude || !$longitude || $status === null) {
|
||||
http_response_code(400);
|
||||
printFailure('Missing required fields');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Secure SQL using prepared statement
|
||||
// 2. لاحظ التغيير داخل جملة SQL
|
||||
// بدلنا :updated_at بكلمة NOW() وهي دالة في قاعدة البيانات
|
||||
$sql = "INSERT INTO `car_locations` (
|
||||
`driver_id`, `latitude`, `longitude`, `heading`, `speed`, `distance`, `status`, `updated_at`
|
||||
) VALUES (
|
||||
:driver_id, :latitude, :longitude, :heading, :speed, :distance, :status, NOW()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`latitude` = VALUES(`latitude`),
|
||||
`longitude` = VALUES(`longitude`),
|
||||
`heading` = VALUES(`heading`),
|
||||
`speed` = VALUES(`speed`),
|
||||
`distance` = VALUES(`distance`),
|
||||
`status` = VALUES(`status`),
|
||||
`updated_at` = NOW()"; // وهنا أيضاً جعلنا التحديث يأخذ وقت السيرفر مباشرة
|
||||
|
||||
try {
|
||||
$stmt = $con->prepare($sql);
|
||||
|
||||
// The execute method returns true on success and false on failure.
|
||||
$success = $stmt->execute([
|
||||
':latitude' => $latitude,
|
||||
':longitude' => $longitude,
|
||||
':heading' => $heading,
|
||||
':speed' => $speed,
|
||||
':distance' => $distance,
|
||||
':status' => $status,
|
||||
// ':updated_at' => $updated_at, <-- قمنا بحذف هذا السطر من المصفوفة لأنه لم يعد موجوداً في الاستعلام
|
||||
':driver_id' => $driver_id
|
||||
]);
|
||||
|
||||
if ($success) {
|
||||
printSuccess("Car location updated successfully");
|
||||
} else {
|
||||
printFailure("Failed to update car location");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
http_response_code(500);
|
||||
printFailure('Database error occurred');
|
||||
}
|
||||
?>
|
||||
48
loction_server/siro/ride/location/update_location.php
Executable file
48
loction_server/siro/ride/location/update_location.php
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
include "../../connect.php";
|
||||
|
||||
// استقبال البيانات من تطبيق السائق
|
||||
$driver_id = filterRequest("driver_id");
|
||||
$lat = filterRequest("lat");
|
||||
$lng = filterRequest("lng");
|
||||
$heading = filterRequest("heading"); // اتجاه السيارة
|
||||
$speed = filterRequest("speed");
|
||||
$status = filterRequest("status"); // 'on' (متاح) أو 'off' (مشغول/غير متاح)
|
||||
|
||||
if (!$driver_id || !$lat || !$lng) {
|
||||
printFailure("Missing Data");
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// استخدام ON DUPLICATE KEY UPDATE لضمان وجود صف واحد فقط لكل سائق
|
||||
// الجدول: car_locations
|
||||
$sql = "INSERT INTO car_locations (driver_id, latitude, longitude, heading, speed, status, updated_at)
|
||||
VALUES (:id, :lat, :lng, :head, :spd, :stat, NOW())
|
||||
ON DUPLICATE KEY UPDATE
|
||||
latitude = :lat,
|
||||
longitude = :lng,
|
||||
heading = :head,
|
||||
speed = :spd,
|
||||
status = :stat,
|
||||
updated_at = NOW()";
|
||||
|
||||
$stmt = $con_tracking->prepare($sql);
|
||||
$stmt->execute([
|
||||
':id' => $driver_id,
|
||||
':lat' => $lat,
|
||||
':lng' => $lng,
|
||||
':head' => $heading,
|
||||
':spd' => $speed,
|
||||
':stat' => $status
|
||||
]);
|
||||
|
||||
// ملاحظة: لا نحتاج لإرسال socket notification هنا لأن هذا يحدث كل ثانية
|
||||
// الراكب يرى التحديث لأنه متصل بسوكيت اللوكيشن ويستمع لحدث 'update_driver_location'
|
||||
|
||||
printSuccess("Location Updated");
|
||||
|
||||
} catch (PDOException $e) {
|
||||
printFailure("DB Error: " . $e->getMessage());
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user