validate([ 'igdb_id' => 'required|integer|unique:games', 'name' => 'required|string|max:255', 'summary' => 'nullable|string', 'storyline' => 'nullable|string', 'cover_url' => 'nullable|url', 'slug' => 'required|string|max:255|unique:games', 'first_release_date' => 'nullable|date', 'rating' => 'nullable|numeric|between:0,100', 'rating_count' => 'nullable|integer|min:0', 'category' => 'nullable|integer', 'status' => 'nullable|integer', 'url' => 'nullable|url', 'version_title' => 'nullable|string|max:255', ]); $game = Game::create($validated); return response()->json($game, 201); } public function index(Request $request) { $query = Game::query(); // Apply search if ($request->has('search')) { $search = $request->get('search'); $query->where(function($q) use ($search) { $q->where('name', 'like', "%{$search}%") ->orWhere('summary', 'like', "%{$search}%"); }); } // Apply sorting $sort = $request->get('sort', 'first_release_date'); $direction = $request->get('direction', 'desc'); if ($sort === 'rating') { $query->orderBy('rating', $direction); } elseif ($sort === 'rating_count') { $query->orderBy('rating_count', $direction); } else { $query->orderBy('first_release_date', $direction); } // Apply filters if ($request->has('platform')) { $query->whereHas('platforms', function ($q) use ($request) { $q->where('slug', $request->platform); }); } if ($request->has('genre')) { $query->whereHas('genres', function ($q) use ($request) { $q->where('slug', $request->genre); }); } if ($request->has('year')) { $query->whereYear('first_release_date', $request->year); } if ($request->has('rating_range')) { $range = explode('-', $request->rating_range); if (count($range) === 2) { $min = (float)$range[0]; $max = (float)$range[1]; $query->whereBetween('rating', [$min, $max]); } } $games = $query->paginate(36)->withQueryString(); // Get data for filter dropdowns $platforms = \App\Models\Platform::orderBy('name')->get(); $genres = \App\Models\Genre::orderBy('name')->get(); // Get unique years from games $years = Game::selectRaw('YEAR(first_release_date) as year') ->whereNotNull('first_release_date') ->distinct() ->orderBy('year', 'desc') ->pluck('year') ->filter() ->values(); return view('games.index', compact('games', 'platforms', 'genres', 'years')); } public function show(Game $game) { // Load game relationships except reviews $game->load(['platforms', 'genres', 'screenshots', 'videos', 'similar_games', 'dlcs']); // Load reviews with users separately (could be paginated if needed) $reviews = $game->reviews()->with('user')->get(); // Calculate rating distribution percentages $ratingDistribution = $this->calculateRatingDistribution($game); return view('games.show', compact('game', 'ratingDistribution', 'reviews')); } /** * Calculate the rating distribution percentages for a game * * @param Game $game * @return array */ private function calculateRatingDistribution(Game $game) { $distribution = []; // Get the total number of reviews for this game $totalReviews = $game->reviews()->count(); // If there are no reviews, return empty distribution if ($totalReviews === 0) { for ($i = 10; $i >= 1; $i--) { $distribution[] = [ 'range' => $i, 'count' => 0, 'percentage' => 0 ]; } return $distribution; } // Get the count of reviews for each rating range directly from the database $ratingCounts = $game->reviews() ->selectRaw(' CASE WHEN rating = 1 THEN 1 WHEN rating = 2 THEN 2 WHEN rating = 3 THEN 3 WHEN rating = 4 THEN 4 WHEN rating = 5 THEN 5 WHEN rating = 6 THEN 6 WHEN rating = 7 THEN 7 WHEN rating = 8 THEN 8 WHEN rating = 9 THEN 9 WHEN rating = 10 THEN 10 END as range_id, COUNT(*) as count ') ->groupBy('range_id') ->orderBy('range_id', 'desc') ->get() ->keyBy('range_id'); // Build the distribution array with percentages for ($i = 10; $i >= 1; $i--) { $count = $ratingCounts->get($i)->count ?? 0; $percentage = ($count / $totalReviews) * 100; $distribution[] = [ 'range' => $i, 'count' => $count, 'percentage' => $percentage ]; } return $distribution; } }