2026-05-29 09:37:07 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
|
|
|
|
use App\Models\Game;
|
2026-05-30 12:02:24 +03:00
|
|
|
use App\Models\GameComment;
|
2026-05-29 09:37:07 +03:00
|
|
|
use App\Models\Genre;
|
|
|
|
|
use App\Models\Platform;
|
|
|
|
|
use Illuminate\Http\Request;
|
2026-05-30 11:23:24 +03:00
|
|
|
use Illuminate\Support\Facades\Cache;
|
2026-05-29 09:37:07 +03:00
|
|
|
|
|
|
|
|
class GameController extends Controller
|
|
|
|
|
{
|
|
|
|
|
public function index(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$query = Game::published()->with(['genres', 'platforms']);
|
|
|
|
|
|
|
|
|
|
// Filters
|
|
|
|
|
if ($request->filled('genre')) {
|
|
|
|
|
$query->whereHas('genres', fn($q) => $q->where('genres.id', $request->genre));
|
|
|
|
|
}
|
|
|
|
|
if ($request->filled('platform')) {
|
|
|
|
|
$query->whereHas('platforms', fn($q) => $q->where('platforms.id', $request->platform));
|
|
|
|
|
}
|
|
|
|
|
if ($request->filled('year')) {
|
|
|
|
|
$query->where('release_year', $request->year);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sort
|
|
|
|
|
match ($request->get('sort', 'rating')) {
|
|
|
|
|
'rating' => $query->orderByDesc('rating_avg')->orderByDesc('rating_count'),
|
|
|
|
|
'release' => $query->orderByDesc('release_date'),
|
|
|
|
|
'title' => $query->orderBy('title'),
|
|
|
|
|
'popular' => $query->orderByDesc('library_count'),
|
|
|
|
|
default => $query->orderByDesc('rating_avg'),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$games = $query->paginate(24)->withQueryString();
|
|
|
|
|
$genres = Genre::orderBy('name')->get();
|
|
|
|
|
$platforms = Platform::orderBy('name')->get();
|
|
|
|
|
|
2026-05-31 03:02:12 +03:00
|
|
|
$shouldNoindex = ($request->get('page', 1) > 1) ||
|
|
|
|
|
(collect(['genre', 'platform', 'year', 'sort', 'q'])->filter(fn($k) => $request->filled($k))->count() >= 2);
|
|
|
|
|
|
|
|
|
|
return view('games.index', compact('games', 'genres', 'platforms', 'shouldNoindex'));
|
2026-05-29 09:37:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function show(Game $game)
|
|
|
|
|
{
|
|
|
|
|
$game->load(['genres', 'platforms', 'companies', 'screenshots', 'reviews.user']);
|
|
|
|
|
|
2026-05-30 02:50:34 +03:00
|
|
|
$userGame = null;
|
|
|
|
|
$userReview = null;
|
|
|
|
|
$userLists = collect();
|
2026-05-29 09:37:07 +03:00
|
|
|
if (auth()->check()) {
|
2026-05-30 02:50:34 +03:00
|
|
|
$userGame = $game->userGames()->where('user_id', auth()->id())->first();
|
|
|
|
|
$userReview = $game->reviews()->where('user_id', auth()->id())->first();
|
2026-05-30 18:56:17 +03:00
|
|
|
$userLists = auth()->user()->lists()->get(['id', 'slug', 'title']);
|
2026-05-29 09:37:07 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-30 12:02:24 +03:00
|
|
|
$comments = $game->comments()->whereNull('parent_id')
|
|
|
|
|
->with(['user', 'replies.user'])
|
|
|
|
|
->latest()
|
|
|
|
|
->limit(20)
|
|
|
|
|
->get();
|
|
|
|
|
|
2026-05-31 03:02:12 +03:00
|
|
|
$similarGames = collect();
|
|
|
|
|
if ($game->genres->isNotEmpty()) {
|
|
|
|
|
$similarGames = Game::published()
|
|
|
|
|
->whereHas('genres', fn($q) => $q->whereIn('genres.id', $game->genres->pluck('id')))
|
|
|
|
|
->where('id', '!=', $game->id)
|
|
|
|
|
->where('rating_count', '>=', 1)
|
|
|
|
|
->orderByDesc('rating_avg')
|
|
|
|
|
->limit(6)
|
|
|
|
|
->get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$response = view('games.show', compact('game', 'userGame', 'userReview', 'userLists', 'comments', 'similarGames'));
|
2026-05-30 11:23:24 +03:00
|
|
|
return auth()->check()
|
|
|
|
|
? $response
|
|
|
|
|
: response($response)->header('Cache-Control', 'public, max-age=300');
|
2026-05-29 09:37:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function search(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$q = $request->get('q', '');
|
|
|
|
|
$games = collect();
|
|
|
|
|
|
|
|
|
|
if (strlen($q) >= 2) {
|
2026-05-30 11:23:24 +03:00
|
|
|
$games = Game::search($q)->get()->filter(fn($g) => $g->status === 'published');
|
2026-05-29 09:37:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($request->expectsJson()) {
|
2026-05-30 11:23:24 +03:00
|
|
|
return response()->json($games->take(6)->map(fn($g) => [
|
|
|
|
|
'id' => $g->id,
|
|
|
|
|
'title' => $g->title,
|
|
|
|
|
'slug' => $g->slug,
|
|
|
|
|
'cover_thumb' => $g->cover_thumb_url,
|
|
|
|
|
'release_year' => $g->release_year,
|
|
|
|
|
'rating_avg' => $g->rating_avg,
|
|
|
|
|
'url' => route('games.show', $g),
|
|
|
|
|
])->values());
|
2026-05-29 09:37:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return view('games.search', compact('games', 'q'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function topRated(Request $request)
|
|
|
|
|
{
|
2026-05-30 11:23:24 +03:00
|
|
|
$page = $request->get('page', 1);
|
|
|
|
|
$games = Cache::remember("games.top_rated.{$page}", 300, fn() =>
|
|
|
|
|
Game::published()
|
|
|
|
|
->where('rating_count', '>=', 1)
|
|
|
|
|
->orderByDesc('rating_avg')
|
|
|
|
|
->orderByDesc('rating_count')
|
|
|
|
|
->paginate(24)
|
|
|
|
|
->withQueryString()
|
|
|
|
|
);
|
2026-05-29 09:37:07 +03:00
|
|
|
|
|
|
|
|
return view('games.top-rated', compact('games'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function newReleases(Request $request)
|
|
|
|
|
{
|
2026-05-30 11:23:24 +03:00
|
|
|
$page = $request->get('page', 1);
|
|
|
|
|
$games = Cache::remember("games.new_releases.{$page}", 300, fn() =>
|
|
|
|
|
Game::published()
|
|
|
|
|
->whereNotNull('release_date')
|
|
|
|
|
->where('release_date', '<=', now())
|
|
|
|
|
->orderByDesc('release_date')
|
|
|
|
|
->paginate(24)
|
|
|
|
|
->withQueryString()
|
|
|
|
|
);
|
2026-05-29 09:37:07 +03:00
|
|
|
|
|
|
|
|
return view('games.new-releases', compact('games'));
|
|
|
|
|
}
|
|
|
|
|
}
|