Files
Siro/backend/ride/rate/pending_rating.php
T

128 lines
5.7 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// ============================================================
// pending_rating.php — آخر رحلة منتهية لم تُقيَّم بعد
//
// ‏لماذا نقطة مستقلة:
// ‏شاشة التقييم لا تُفتح اليوم إلا عبر needsReview في
// ‏getRideStatusFromStartApp.php، وذاك محصور بنافذة ساعة واحدة — وهي
// ‏نافذة مقصودة لاستئناف رحلة **قائمة** لا للتقييم. النتيجة أن من يغلق
// ‏التطبيق فور نزوله (وهو السلوك الغالب) لا يُطلب منه تقييم أبداً.
//
// ‏توسيع تلك النافذة كان سيجعل التطبيق يفتح شاشة رحلة على رحلة انتهت.
// ‏لذلك: نقطة منفصلة تسأل سؤالاً واحداً — «هل عليّ تقييم متأخر؟» — بلا
// ‏أي علاقة بحالة الرحلة الجارية.
//
// ── قاعدتان لا واحدة ──
// ‏الرحلات في قاعدة ride والتقييمات في primary، وهما منفصلتان فيزيائياً
// ‏فلا انضمام ممكن. استعلامان: آخر الرحلات المنتهية من ride، ثم أيّها
// ‏مقيَّم في primary. الحد الصغير يبقي التكلفة ضئيلة.
// ============================================================
require_once __DIR__ . '/../../connect.php';
try {
$con_ride = Database::get('ride');
} catch (Exception $e) {
error_log("[pending_rating] Ride DB unavailable: " . $e->getMessage());
jsonError("Service unavailable", 503);
}
// ‏من يسأل: راكب يقيّم سائقه، أو سائق يقيّم راكبه.
$role_ = filterRequest("role") === 'driver' ? 'driver' : 'passenger';
// ‏الهوية من الـJWT لا من الطلب — وإلا قرأ أي أحد رحلات غيره.
$userId = $user_id ?? '';
if (empty($userId)) {
jsonError("Unauthorized", 401);
}
// ‏نافذة معقولة: تقييم رحلة نسيها صاحبها بلا قيمة، ويزعجه.
const PENDING_RATING_WINDOW_DAYS = 7;
// ‏عدد الرحلات التي نفحصها. آخر رحلة غير مقيّمة عملياً ضمن آخر قليل،
// ‏فلا داعي لمسح تاريخ المستخدم كله.
const PENDING_RATING_SCAN_LIMIT = 10;
try {
// ── ١) آخر الرحلات المنتهية من قاعدة الرحلات ──────────────
$col = $role_ === 'driver' ? 'driver_id' : 'passenger_id';
$stmt = $con_ride->prepare("
SELECT id, driver_id, passenger_id, price, carType,
start_location, end_location, rideTimeFinish
FROM ride
WHERE `$col` = ?
AND status = 'Finished'
AND rideTimeFinish >= NOW() - INTERVAL " . PENDING_RATING_WINDOW_DAYS . " DAY
ORDER BY rideTimeFinish DESC
LIMIT " . PENDING_RATING_SCAN_LIMIT
);
$stmt->execute([$userId]);
$rides = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($rides)) {
jsonSuccess(['pending' => false], "No pending rating");
}
// ── ٢) أيّها مقيَّم؟ استعلام واحد لكلها ───────────────────
$ids = array_column($rides, 'id');
$ph = implode(',', array_fill(0, count($ids), '?'));
// ‏الراكب يقيّم السائق في ratingDriver (العمود ride_id)،
// ‏والسائق يقيّم الراكب في ratingPassenger (العمود rideId).
$ratedSql = $role_ === 'driver'
? "SELECT rideId AS rid FROM ratingPassenger WHERE rideId IN ($ph)"
: "SELECT ride_id AS rid FROM ratingDriver WHERE ride_id IN ($ph)";
$stmtRated = $con->prepare($ratedSql);
$stmtRated->execute($ids);
$rated = array_flip($stmtRated->fetchAll(PDO::FETCH_COLUMN));
// ── ٣) أول رحلة غير مقيّمة (الأحدث أولاً) ─────────────────
$target = null;
foreach ($rides as $r) {
if (!isset($rated[$r['id']]) && !isset($rated[(string) $r['id']])) {
$target = $r;
break;
}
}
if (!$target) {
jsonSuccess(['pending' => false], "No pending rating");
}
// ── ٤) اسم الطرف الآخر ────────────────────────────────────
// ‏من primary: جداول driver/passengers تعيش هناك، والاسم مشفَّر.
$otherId = $role_ === 'driver' ? $target['passenger_id'] : $target['driver_id'];
$otherName = '';
try {
$table = $role_ === 'driver' ? 'passengers' : 'driver';
$stmtName = $con->prepare("SELECT first_name FROM `$table` WHERE id = ? LIMIT 1");
$stmtName->execute([$otherId]);
$raw = $stmtName->fetchColumn();
if ($raw && !empty($encryptionHelper)) {
$dec = $encryptionHelper->decryptData($raw);
$otherName = ($dec !== false && $dec !== '') ? $dec : '';
}
} catch (Throwable $e) {
// ‏الاسم تحسين لا شرط — الشاشة تعمل بدونه.
error_log("[pending_rating] تعذّر جلب اسم الطرف الآخر: " . $e->getMessage());
}
jsonSuccess([
'pending' => true,
'rideId' => (string) $target['id'],
'targetId' => (string) $otherId,
'targetName' => $otherName,
'price' => $target['price'],
'carType' => $target['carType'],
'finishedAt' => $target['rideTimeFinish'],
], "Pending rating found");
} catch (PDOException $e) {
error_log("[pending_rating] " . $e->getMessage());
jsonError("DB Error", 500);
}