Files
MediaCollectorLibary/app/Controllers/GameController.php
Lars Behrends 7a7977d8b0 yay
2025-11-01 22:00:30 +01:00

286 lines
9.1 KiB
PHP

<?php
namespace App\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use App\Models\Game;
use App\Services\SteamGridDbService;
use Slim\Views\Twig;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
class GameController extends Controller
{
private \PDO $pdo;
private SteamGridDbService $steamGridDb;
public function __construct(\PDO $pdo, Twig $view)
{
parent::__construct($view);
$this->pdo = $pdo;
$this->steamGridDb = new SteamGridDbService();
}
/**
* Search for games on SteamGridDB
*/
public function searchSteamGridDb(Request $request, Response $response, array $args): Response
{
$query = $request->getQueryParams()['q'] ?? '';
$results = [];
if (!empty($query)) {
$results = $this->steamGridDb->searchGames($query);
}
return $this->json($response, [
'success' => true,
'data' => $results
]);
}
/**
* Get media from SteamGridDB
*/
public function getSteamGridDbMedia(Request $request, Response $response, array $args): Response
{
$gameId = $args['gameId'] ?? null;
$type = $args['type'] ?? 'grids';
$media = [];
if ($gameId) {
switch ($type) {
case 'grids':
$media = $this->steamGridDb->getGrids($gameId, [
'styles' => ['alternate', 'blurred', 'white_logo', 'material', 'no_logo'],
'dimensions' => ['600x900', '920x430', '460x215', '920x430']
]);
break;
case 'heroes':
$media = $this->steamGridDb->getHeroes($gameId, [
'dimensions' => ['1920x620', '3840x1240']
]);
break;
case 'icons':
$media = $this->steamGridDb->getIcons($gameId, [
'dimensions' => ['32x32', '64x64', '128x128', '256x256', '512x512']
]);
break;
case 'logos':
$media = $this->steamGridDb->getLogos($gameId);
break;
}
}
return $this->json($response, [
'success' => true,
'data' => $media
]);
}
/**
* Download and set media from SteamGridDB
*/
public function setSteamGridDbMedia(Request $request, Response $response, array $args): Response
{
$gameId = $args['id'] ?? null;
$data = $request->getParsedBody();
$type = $data['type'] ?? '';
$url = $data['url'] ?? '';
$field = '';
if (!$gameId || !$type || !$url) {
return $this->json($response, [
'success' => false,
'message' => 'Missing required parameters'
], 400);
}
// Map media type to database field
switch ($type) {
case 'grid':
$field = 'image_url';
break;
case 'hero':
$field = 'banner_url';
break;
case 'icon':
$field = 'icon';
break;
case 'logo':
$field = 'logo_url';
break;
default:
return $this->json($response, [
'success' => false,
'message' => 'Invalid media type'
], 400);
}
// Download the media file
$tempFile = $this->steamGridDb->downloadMedia($url);
if (!$tempFile) {
return $this->json($response, [
'success' => false,
'message' => 'Failed to download media'
], 500);
}
// Move the file to the appropriate location
$uploadDir = __DIR__ . '/../../public/uploads/games/' . $gameId;
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$filename = $type . '_' . uniqid() . '.' . pathinfo($url, PATHINFO_EXTENSION);
$filepath = $uploadDir . '/' . $filename;
$publicPath = '/uploads/games/' . $gameId . '/' . $filename;
if (!rename($tempFile, $filepath)) {
return $this->json($response, [
'success' => false,
'message' => 'Failed to save media file'
], 500);
}
// Update the game record
$game = Game::find($this->pdo, $gameId);
if (!$game) {
return $this->json($response, [
'success' => false,
'message' => 'Game not found'
], 404);
}
$game->{$field} = $publicPath;
$game->save($this->pdo);
return $this->json($response, [
'success' => true,
'data' => [
'url' => $publicPath,
'field' => $field
]
]);
}
public function index(Request $request, Response $response, $args)
{
$queryParams = $request->getQueryParams();
// Get pagination parameters
$page = max(1, (int)($queryParams['page'] ?? 1));
$perPage = max(12, min(100, (int)($queryParams['per_page'] ?? 24)));
// Get search parameters
$search = trim($queryParams['search'] ?? '');
// Get filter parameters
$genres = $queryParams['genres'] ?? [];
if (!is_array($genres)) {
$genres = [$genres];
}
$genres = array_filter($genres);
$platforms = $queryParams['platforms'] ?? [];
if (!is_array($platforms)) {
$platforms = [$platforms];
}
$platforms = array_filter($platforms);
// Get view mode
$viewMode = $queryParams['view'] ?? 'grid'; // grid, list, covers
// Get sort parameter
$sort = $queryParams['sort'] ?? 'title_asc';
// Get games with pagination, filters, and sorting
$games = Game::getGroupedGamesWithPagination($this->pdo, $page, $perPage, $search, $genres, $platforms, $sort);
// Get total count for pagination
$totalCount = Game::getTotalCount($this->pdo, $search, $genres, $platforms);
// Get available filter options
$availableGenres = Game::getAvailableGenres($this->pdo);
$availablePlatforms = Game::getAvailablePlatforms($this->pdo);
// Calculate pagination info
$totalPages = ceil($totalCount / $perPage);
$hasNextPage = $page < $totalPages;
$hasPrevPage = $page > 1;
return $this->view->render($response, 'games/index.twig', [
'title' => 'Games',
'games' => $games,
'pagination' => [
'current_page' => $page,
'per_page' => $perPage,
'total_pages' => $totalPages,
'total_items' => $totalCount,
'has_next' => $hasNextPage,
'has_prev' => $hasPrevPage,
'next_page' => $page + 1,
'prev_page' => $page - 1
],
'search' => $search,
'view_mode' => $viewMode,
'view_modes' => ['grid', 'list', 'covers'],
'filters' => [
'genres' => $genres,
'platforms' => $platforms
],
'available_filters' => [
'genres' => $availableGenres,
'platforms' => $availablePlatforms
],
'sort' => $sort,
'sort_options' => [
'title_asc' => 'Title (A-Z)',
'title_desc' => 'Title (Z-A)',
'year_asc' => 'Release Year (Oldest First)',
'year_desc' => 'Release Year (Newest First)',
'playtime_desc' => 'Most Played',
'completion_desc' => 'Highest Completion',
'added_desc' => 'Recently Added',
'last_played_desc' => 'Last Played',
'platforms_desc' => 'Most Platforms',
'platforms_asc' => 'Fewest Platforms'
]
]);
}
public function show(Request $request, Response $response, $args)
{
$gameKey = $args['game_key'];
// Find the main game entry (could be any platform version)
$stmt = $this->pdo->prepare("
SELECT g.*, g.platform as source_name
FROM games g
WHERE g.game_key = :game_key
LIMIT 1
");
$stmt->execute(['game_key' => $gameKey]);
$mainGame = $stmt->fetch(\PDO::FETCH_ASSOC);
if (!$mainGame) {
return $response->withStatus(404);
}
// Get all platform versions
$gameModel = new Game($this->pdo);
$gameModel->id = $mainGame['id'];
$gameModel->game_key = $mainGame['game_key'];
$platformVersions = $gameModel->getPlatformVersions();
return $this->view->render($response, 'games/show.twig', [
'title' => $mainGame['title'],
'main_game' => $mainGame,
'platform_versions' => $platformVersions
]);
}
}