111 lines
3.8 KiB
PHP
111 lines
3.8 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../../connect.php';
|
|
|
|
$type = isset($_POST['type']) ? filterRequest("type") : 'trips';
|
|
|
|
try {
|
|
global $redis;
|
|
$redisKey = "gamification_leaderboard:{$type}";
|
|
|
|
// 1. Try to read from Redis first
|
|
if (isset($redis)) {
|
|
try {
|
|
$cached = $redis->get($redisKey);
|
|
if ($cached) {
|
|
$data = json_decode($cached, true);
|
|
if ($data !== null) {
|
|
jsonSuccess($data);
|
|
exit;
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
error_log("Redis read error in getLeaderboard: " . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
// 2. Fallback to Database
|
|
if ($type === 'earnings') {
|
|
$sql = "
|
|
SELECT
|
|
d.id as driver_id,
|
|
-- الأعمدة الفعلية في جدول driver. الاستعلام السابق كان
|
|
-- يطلب name / nameArabic / firstName / personal_photo وأيٌّ
|
|
-- منها غير موجود، فكان كل طلب يسقط بخطأ قاعدة بيانات.
|
|
d.first_name as first_name,
|
|
d.last_name as last_name,
|
|
COALESCE(SUM(r.price_for_driver), 0) as value
|
|
FROM `driver` d
|
|
JOIN `ride` r ON d.id = r.driver_id
|
|
WHERE r.status = 'Finished'
|
|
AND r.created_at >= DATE(NOW() - INTERVAL WEEKDAY(NOW()) DAY)
|
|
GROUP BY d.id, d.first_name, d.last_name
|
|
ORDER BY value DESC
|
|
LIMIT 10
|
|
";
|
|
} else {
|
|
// Default to trips
|
|
$sql = "
|
|
SELECT
|
|
d.id as driver_id,
|
|
-- الأعمدة الفعلية في جدول driver. الاستعلام السابق كان
|
|
-- يطلب name / nameArabic / firstName / personal_photo وأيٌّ
|
|
-- منها غير موجود، فكان كل طلب يسقط بخطأ قاعدة بيانات.
|
|
d.first_name as first_name,
|
|
d.last_name as last_name,
|
|
COUNT(r.id) as value
|
|
FROM `driver` d
|
|
JOIN `ride` r ON d.id = r.driver_id
|
|
WHERE r.status = 'Finished'
|
|
AND r.created_at >= DATE(NOW() - INTERVAL WEEKDAY(NOW()) DAY)
|
|
GROUP BY d.id, d.first_name, d.last_name
|
|
ORDER BY value DESC
|
|
LIMIT 10
|
|
";
|
|
}
|
|
|
|
$stmt = $con->prepare($sql);
|
|
$stmt->execute();
|
|
} catch (PDOException $e) {
|
|
error_log("getLeaderboard Error: " . $e->getMessage());
|
|
jsonError("Database error occurred");
|
|
}
|
|
|
|
if ($stmt->rowCount() > 0) {
|
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Add Rank manually to support older MySQL versions
|
|
$rank = 1;
|
|
foreach ($rows as &$row) {
|
|
$row['rank'] = $rank++;
|
|
|
|
// الأسماء مخزّنة مشفّرة في driver — بلا فكّ تشفير تظهر اللوحة
|
|
// صفوفاً من النص المشفّر. نعرض الاسم الأول فقط: لوحة صدارة
|
|
// عامة لا داعي لأن تكشف الاسم الكامل لكل سائق.
|
|
$first = !empty($row['first_name'])
|
|
? (string) $encryptionHelper->decryptData($row['first_name'])
|
|
: '';
|
|
unset($row['first_name'], $row['last_name']);
|
|
|
|
$row['name'] = $first !== '' ? $first : 'Driver';
|
|
$row['photoUrl'] = null;
|
|
}
|
|
unset($row);
|
|
|
|
$responseData = $rows;
|
|
} else {
|
|
$responseData = [];
|
|
}
|
|
|
|
// 3. Save the DB result into Redis for future reads
|
|
if (isset($redis)) {
|
|
try {
|
|
// Cache leaderboard for 1 hour (3600 seconds)
|
|
$redis->setex($redisKey, 3600, json_encode($responseData));
|
|
} catch (Exception $e) {
|
|
error_log("Redis write error in getLeaderboard: " . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
jsonSuccess($responseData);
|
|
?>
|