mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
298 lines
9.5 KiB
PHP
298 lines
9.5 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);
|
|
|
|
$features = $queryParams['features'] ?? [];
|
|
if (!is_array($features)) {
|
|
$features = [$features];
|
|
}
|
|
$features = array_filter($features);
|
|
|
|
$playtimeFilter = $queryParams['playtime'] ?? '';
|
|
|
|
// 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, $features, $playtimeFilter, $sort);
|
|
|
|
// Get total count for pagination
|
|
$totalCount = Game::getTotalCount($this->pdo, $search, $genres, $platforms, $features, $playtimeFilter);
|
|
|
|
// Get available filter options
|
|
$availableGenres = Game::getAvailableGenres($this->pdo);
|
|
$availablePlatforms = Game::getAvailablePlatforms($this->pdo);
|
|
$availableFeatures = Game::getAvailableFeatures($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,
|
|
'features' => $features,
|
|
'playtime' => $playtimeFilter
|
|
],
|
|
'available_filters' => [
|
|
'genres' => $availableGenres,
|
|
'platforms' => $availablePlatforms,
|
|
'features' => $availableFeatures
|
|
],
|
|
'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
|
|
]);
|
|
}
|
|
}
|