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, ]); } } } }