Files
gamelog/app/Console/Commands/ImportGamesCommand.php
T
2026-05-30 18:56:17 +03:00

161 lines
5.7 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Company;
use App\Models\Game;
use App\Models\GameScreenshot;
use App\Models\Genre;
use App\Models\Platform;
use App\Services\IgdbService;
use Illuminate\Console\Command;
class ImportGamesCommand extends Command
{
protected $signature = 'games:import {--limit=100} {--offset=0} {--popular} {--new} {--year=} {--platform=}';
protected $description = 'Import games from IGDB into the local database';
public function handle(IgdbService $igdb): int
{
$limit = (int) $this->option('limit');
$offset = (int) $this->option('offset');
$year = $this->option('year') ? (int) $this->option('year') : null;
$platform = $this->option('platform') ? (int) $this->option('platform') : null;
if ($year && $platform) {
$this->error('Use --year or --platform, not both.');
return self::FAILURE;
}
$label = match (true) {
$year !== null => "year {$year}",
$platform !== null => "platform IGDB ID {$platform}",
$this->option('new') => 'new releases',
default => "popular (offset: {$offset})",
};
$this->info("Fetching {$limit} games from IGDB ({$label})…");
try {
$results = match (true) {
$year !== null => $igdb->getGamesByYear($year, $limit, $offset),
$platform !== null => $igdb->getGamesByPlatform($platform, $limit, $offset),
$this->option('new') => $igdb->getNewReleases($limit),
default => $igdb->getPopularGames($limit, $offset),
};
} catch (\Exception $e) {
$this->error('IGDB request failed: ' . $e->getMessage());
return self::FAILURE;
}
if (empty($results)) {
$this->warn('No games returned from IGDB.');
return self::SUCCESS;
}
$imported = 0;
$bar = $this->output->createProgressBar(count($results));
$bar->start();
foreach ($results as $data) {
try {
$this->upsertGame($data, $igdb);
$imported++;
} catch (\Exception $e) {
$this->newLine();
$this->warn("Skipped game (igdb_id={$data['id']}): " . $e->getMessage());
}
$bar->advance();
}
$bar->finish();
$this->newLine(2);
$this->info("Done. Imported/updated {$imported} games.");
return self::SUCCESS;
}
private function upsertGame(array $data, IgdbService $igdb): void
{
$igdbId = $data['id'];
$title = $data['name'] ?? 'Unknown';
$releaseDate = isset($data['first_release_date'])
? date('Y-m-d', $data['first_release_date'])
: null;
$releaseYear = $releaseDate ? substr($releaseDate, 0, 4) : null;
$coverUrl = null;
$coverThumbUrl = null;
if (!empty($data['cover']['image_id'])) {
$coverUrl = $igdb::coverUrl($data['cover']['image_id'], 'cover_big');
$coverThumbUrl = $igdb::coverUrl($data['cover']['image_id'], 'cover_small');
}
$game = Game::updateOrCreate(
['igdb_id' => $igdbId],
[
'title' => $title,
'summary' => $data['summary'] ?? null,
'cover_url' => $coverUrl,
'cover_thumb_url'=> $coverThumbUrl,
'release_date' => $releaseDate,
'release_year' => $releaseYear,
'status' => 'published',
]
);
// Genres
if (!empty($data['genres'])) {
$genreIds = [];
foreach ($data['genres'] as $g) {
$genre = Genre::firstOrCreate(
['igdb_id' => $g['id']],
['name' => $g['name'], 'slug' => \Str::slug($g['name'])]
);
$genreIds[] = $genre->id;
}
$game->genres()->sync($genreIds);
}
// Platforms
if (!empty($data['platforms'])) {
$platformIds = [];
foreach ($data['platforms'] as $p) {
$platform = Platform::firstOrCreate(
['igdb_id' => $p['id']],
['name' => $p['name'], 'slug' => \Str::slug($p['name'])]
);
$platformIds[] = $platform->id;
}
$game->platforms()->sync($platformIds);
}
// Companies (involved_companies)
if (!empty($data['involved_companies'])) {
$companyPivot = [];
foreach ($data['involved_companies'] as $ic) {
if (empty($ic['company']['name'])) continue;
$company = Company::firstOrCreate(
['igdb_id' => $ic['company']['id']],
['name' => $ic['company']['name'], 'slug' => \Str::slug($ic['company']['name'])]
);
$role = $ic['developer'] ? 'developer' : ($ic['publisher'] ? 'publisher' : 'other');
$companyPivot[$company->id] = ['role' => $role];
}
$game->companies()->sync($companyPivot);
}
// Screenshots
if (!empty($data['screenshots'])) {
GameScreenshot::where('game_id', $game->id)->delete();
foreach ($data['screenshots'] as $i => $shot) {
GameScreenshot::create([
'game_id' => $game->id,
'url' => $igdb::screenshotUrl($shot['image_id'], 'screenshot_big'),
'thumb_url' => $igdb::screenshotUrl($shot['image_id'], 'screenshot_med'),
'order' => $i,
]);
}
}
}
}