From d20e0410093b7c5128fe92795e7ecdfb21014ca7 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Sat, 25 Apr 2026 21:52:03 +0300 Subject: [PATCH] Allplmmpliedl manual JWT check and restored all driver fields68j2 --- .../Api/PaymentTokenController.php | 9 +- app/Http/Controllers/RatingController.php | 42 ++++++--- app/Http/Controllers/RideController.php | 92 +++++++++++++++++++ routes/api.php | 1 + 4 files changed, 127 insertions(+), 17 deletions(-) diff --git a/app/Http/Controllers/Api/PaymentTokenController.php b/app/Http/Controllers/Api/PaymentTokenController.php index 185a95f..c3eccf0 100644 --- a/app/Http/Controllers/Api/PaymentTokenController.php +++ b/app/Http/Controllers/Api/PaymentTokenController.php @@ -12,22 +12,25 @@ class PaymentTokenController extends Controller // 1. مسار الراكب public function generatePassengerToken(Request $request) { + $userId = $request->attributes->get('_jwt_user_id'); // تحقق خاص بالراكب (لا يوجد بصمة سيارة مثلاً) - return $this->buildToken($request->user()->id, 'android/ios_passenger', $request->input('fingerPrint')); + return $this->buildToken($userId, 'android/ios_passenger', $request->input('fingerPrint')); } // 2. مسار السائق public function generateDriverToken(Request $request) { + $userId = $request->attributes->get('_jwt_user_id'); // تحقق خاص بالسائق (ضرورة وجود بصمة جهاز قوية) - return $this->buildToken($request->user()->id, 'android/ios_driver', $request->input('fingerPrint')); + return $this->buildToken($userId, 'android/ios_driver', $request->input('fingerPrint')); } // 3. مسار المدير public function generateAdminToken(Request $request) { + $userId = $request->attributes->get('_jwt_user_id'); // المدراء لديهم صلاحيات أوسع، قد يكون الـ aud مختلفاً - return $this->buildToken($request->user()->id, 'web_admin', 'admin_secure_context'); + return $this->buildToken($userId, 'web_admin', 'admin_secure_context'); } // 4. دالة البناء المركزية (Private) diff --git a/app/Http/Controllers/RatingController.php b/app/Http/Controllers/RatingController.php index 095ca85..8c132bf 100644 --- a/app/Http/Controllers/RatingController.php +++ b/app/Http/Controllers/RatingController.php @@ -112,23 +112,37 @@ class RatingController extends Controller if (!$id) { return response()->json(['status' => 'failure', 'message' => 'Driver ID required'], 400); } - $ratings = DB::connection('primary')->table('ratingDriver') - ->where('driver_id', $id) - ->orderBy('created_at', 'desc') - ->limit(50) - ->get(); - $avg = DB::connection('primary')->table('ratingDriver') - ->where('driver_id', $id)->avg('rating'); + $summaryOnly = $request->input('summary_only', true); - return response()->json([ - 'status' => 'success', - 'message' => [ + // Cache rating summary for 1 hour + $cacheKey = "driver_rating_summary:{$id}"; + $summary = \Illuminate\Support\Facades\Cache::remember($cacheKey, 3600, function () use ($id) { + $avg = DB::connection('primary')->table('ratingDriver') + ->where('driver_id', $id)->avg('rating'); + $count = DB::connection('primary')->table('ratingDriver') + ->where('driver_id', $id)->count(); + + return [ 'average' => round($avg ?? 5.0, 2), - 'count' => $ratings->count(), - 'ratings' => $ratings, - ], - ]); + 'count' => $count, + ]; + }); + + $response = [ + 'status' => 'success', + 'message' => $summary, + ]; + + if (!$summaryOnly) { + $response['message']['ratings'] = DB::connection('primary')->table('ratingDriver') + ->where('driver_id', $id) + ->orderBy('created_at', 'desc') + ->limit(50) + ->get(); + } + + return response()->json($response); } /** GET /v2/ratings/passenger/{id} */ diff --git a/app/Http/Controllers/RideController.php b/app/Http/Controllers/RideController.php index 17b0ab4..581086e 100644 --- a/app/Http/Controllers/RideController.php +++ b/app/Http/Controllers/RideController.php @@ -118,6 +118,29 @@ class RideController extends Controller $priceForDriver = (float) $request->input('price_for_driver', $price); $kazan = $price - $priceForDriver; + // Sync with waitingRides table (Marketplace visibility) + DB::connection('primary')->table('waitingRides')->insert([ + 'id' => (string)$insertedId, + 'start_location' => $request->input('start_name', 'Pickup point'), + 'end_location' => $request->input('end_name', 'Destination'), + 'date' => $rideData['date'], + 'time' => $rideData['time'], + 'price' => $rideData['price'], + 'passenger_id' => $passengerId, + 'status' => 'waiting', + 'carType' => $rideData['carType'], + 'passengerRate' => $request->input('passenger_rating', '5.0'), + 'distance' => $rideData['distance'], + 'duration' => $request->input('duration_text', '0'), + 'start_lat' => $startLat, + 'start_lng' => $startLng, + 'end_lat' => $endLat, + 'end_lng' => $endLng, + 'payment_method' => $request->input('is_wallet', '0') == '1' ? 'wallet' : 'cash', + 'passenger_wallet' => $request->input('passenger_wallet', '0'), + 'created_at' => now(), + ]); + $payloadTemplate = []; $payloadTemplate[0] = (string)$startLat; $payloadTemplate[1] = (string)$startLng; @@ -636,4 +659,73 @@ class RideController extends Controller return response()->json(['status' => 'success', 'message' => $rides]); } + public function availableRides(Request $request): JsonResponse + { + $lat = (float) $request->input('lat'); + $lng = (float) $request->input('lng'); + $radius = (float) $request->input('radius', 50); // km + + $driverId = $request->attributes->get('_jwt_user_id'); + + // Get driver car type for hierarchical matching + $driverCarType = DB::connection('primary')->table('driver as d') + ->leftJoin('CarRegistration as c', 'c.driverID', '=', 'd.id') + ->where('d.id', $driverId) + ->value('c.make') ?? 'Speed'; + + $rides = DB::connection('primary')->table('waitingRides as wr') + ->select([ + 'wr.id', 'wr.start_location as startName', 'wr.end_location as endName', + 'wr.date', 'wr.time', 'wr.price', 'wr.passenger_id', 'wr.status', 'wr.carType', + 'wr.passengerRate', 'wr.created_at', 'wr.price_for_passenger', + 'wr.distance', 'wr.duration', 'wr.start_lat', 'wr.start_lng', + 'wr.end_lat', 'wr.end_lng', 'wr.payment_method', 'wr.passenger_wallet', + 'p.email', 'p.first_name', 'p.phone', 'p.id as passengerId', 't.token as passengerToken', + DB::raw("( 6371 * acos( cos( radians($lat) ) * cos( radians( wr.start_lat ) ) * cos( radians( wr.start_lng ) - radians($lng) ) + sin( radians($lat) ) * sin( radians( wr.start_lat ) ) ) ) AS driver_distance_km") + ]) + ->join('passengers as p', 'p.id', '=', 'wr.passenger_id') + ->leftJoin('tokens as t', 't.passengerID', '=', 'wr.passenger_id') + ->whereIn('wr.status', ['wait', 'waiting']) + ->where('wr.created_at', '>=', now()->subHours(24)) + ->having('driver_distance_km', '<=', $radius) + ->orderBy('driver_distance_km') + ->get() + ->filter(function($ride) use ($driverCarType) { + return $this->isCarTypeMatch($driverCarType, $ride->carType); + }) + ->map(function($ride) { + $ride->first_name = !empty($ride->first_name) ? $this->encryption->decrypt($ride->first_name) : 'Passenger'; + $ride->phone = !empty($ride->phone) ? $this->encryption->decrypt($ride->phone) : ''; + $ride->email = !empty($ride->email) ? $this->encryption->decrypt($ride->email) : ''; + $ride->passengerToken = !empty($ride->passengerToken) ? $this->encryption->decrypt($ride->passengerToken) : ''; + + $ride->start_location = $ride->start_lat . ',' . $ride->start_lng; + $ride->end_location = (!empty($ride->end_lat)) + ? $ride->end_lat . ',' . $ride->end_lng + : $ride->endName; + + $ride->id = (string)$ride->id; + $ride->driver_distance_km = number_format((float)$ride->driver_distance_km, 1); + + return $ride; + }) + ->values(); + + return response()->json([ + 'status' => 'success', + 'message' => $rides + ]); + } + + private function isCarTypeMatch(string $driverType, ?string $rideType): bool + { + if (!$rideType) return true; + + return match ($driverType) { + 'Comfort' => in_array($rideType, ['Speed', 'Comfort', 'Fixed Price']), + 'Lady' => in_array($rideType, ['Comfort', 'Speed', 'Lady']), + 'Speed', 'Scooter', 'Awfar Car' => $rideType === $driverType, + default => true, + }; + } } diff --git a/routes/api.php b/routes/api.php index 769e0dd..b8689f7 100644 --- a/routes/api.php +++ b/routes/api.php @@ -110,6 +110,7 @@ Route::prefix('v2')->middleware(['hmac.auth', 'jwt.auth'])->group(function () { Route::post('/rides/{id}/cancel/passenger', [RideController::class, 'cancelByPassenger']); Route::post('/rides/{id}/cancel/driver', [RideController::class, 'cancelByDriver']); Route::post('/rides/{id}/retry', [RideController::class, 'retrySearch']); + Route::get('/rides/available', [RideController::class, 'availableRides']); Route::put('/rides/{id}', [RideController::class, 'update']); // ── Tracking ──