96 lines
3.0 KiB
PHP
96 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\Game;
|
|
use App\Services\IgdbService;
|
|
use Illuminate\Console\Command;
|
|
|
|
class BackfillExtendedDataCommand extends Command
|
|
{
|
|
protected $signature = 'igdb:backfill-extended
|
|
{--limit=100 : Max number of games to process}
|
|
{--offset=0 : Skip the first N games (ordered by id)}';
|
|
|
|
protected $description = 'Backfill extended IGDB data (collections, modes, themes, videos, etc.) for existing games';
|
|
|
|
public function handle(IgdbService $igdb): int
|
|
{
|
|
$limit = (int) $this->option('limit');
|
|
$offset = (int) $this->option('offset');
|
|
|
|
$games = Game::whereNotNull('igdb_id')
|
|
->orderBy('id')
|
|
->skip($offset)
|
|
->take($limit)
|
|
->get();
|
|
|
|
$total = $games->count();
|
|
|
|
if ($total === 0) {
|
|
$this->info('No games found to process.');
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$this->info("Processing {$total} games (offset: {$offset})…");
|
|
$this->newLine();
|
|
|
|
$n = 0;
|
|
foreach ($games->chunk(10) as $batch) {
|
|
$igdbIds = $batch->pluck('igdb_id')->all();
|
|
|
|
try {
|
|
$igdbResults = $igdb->getGamesByIds($igdbIds);
|
|
} catch (\Exception $e) {
|
|
$this->error('IGDB request failed: ' . $e->getMessage());
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$indexed = collect($igdbResults)->keyBy('id');
|
|
|
|
foreach ($batch as $game) {
|
|
$n++;
|
|
$igdbData = $indexed->get($game->igdb_id);
|
|
|
|
if (!$igdbData) {
|
|
$this->warn(" [{$n}/{$total}] No IGDB data for: {$game->title} (igdb_id={$game->igdb_id})");
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
$igdb->syncExtendedData($game, $igdbData);
|
|
$this->line(" [{$n}/{$total}] Processed: {$game->title}");
|
|
} catch (\Exception $e) {
|
|
$this->warn(" [{$n}/{$total}] Failed {$game->title}: " . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
usleep(250000); // 250ms between IGDB batches
|
|
}
|
|
|
|
$this->newLine();
|
|
$this->info('Extended data sync complete. Resolving similar_games pivot…');
|
|
|
|
$this->resolveSimilarGames();
|
|
|
|
$this->info('Done.');
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function resolveSimilarGames(): void
|
|
{
|
|
$resolved = 0;
|
|
Game::whereNotNull('similar_game_igdb_ids')->chunk(100, function ($games) use (&$resolved) {
|
|
foreach ($games as $game) {
|
|
$ids = $game->similar_game_igdb_ids;
|
|
if (empty($ids)) continue;
|
|
|
|
$similarIds = Game::whereIn('igdb_id', $ids)->pluck('id');
|
|
$game->similarGames()->sync($similarIds);
|
|
$resolved++;
|
|
}
|
|
});
|
|
$this->line(" Resolved similar_games for {$resolved} games.");
|
|
}
|
|
}
|