'https://api.igdb.com/v4/games', 'genres' => 'https://api.igdb.com/v4/genres', 'platforms' => 'https://api.igdb.com/v4/platforms', ]; private const FIELDS = [ 'games' => 'id,name,summary,cover.url,slug,genres,platforms,first_release_date,rating,rating_count,category,status,url,version_title,artworks.url,artworks.width,artworks.height,artworks.image_id,screenshots.url,screenshots.width,screenshots.height,screenshots.image_id,videos.name,videos.video_id,videos.url,videos.checksum,bundles.id,collections.id,dlcs.id,expanded_games.id,franchises.id,ports.id,remakes.id,similar_games.id', 'genres' => 'id,name,slug', 'platforms' => 'id,name,slug,abbreviation', ]; public function handle(IgdbAuthService $authService): int { $type = $this->option('type'); $limit = (int) $this->option('limit'); $offset = (int) $this->option('offset'); $outputDir = $this->option('output'); if (!isset(self::ENDPOINTS[$type])) { $this->error("Invalid type: {$type}"); return Command::FAILURE; } if (!is_dir($outputDir)) { if (!mkdir($outputDir, 0755, true)) { $this->error("Failed to create output directory: {$outputDir}"); return Command::FAILURE; } } $this->info("Fetching {$type} dumps from IGDB API"); $this->info("Output directory: {$outputDir}"); try { $this->fetchDumps($type, $limit, $offset, $outputDir, $authService); } catch (\Exception $e) { $this->error("Error fetching dumps: {$e->getMessage()}"); Log::error('Error fetching IGDB dumps', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return Command::FAILURE; } $this->info('Dump fetching completed successfully'); return Command::SUCCESS; } private function fetchDumps(string $type, int $limit, int $offset, string $outputDir, IgdbAuthService $authService): void { $endpoint = self::ENDPOINTS[$type]; $fields = self::FIELDS[$type]; $totalFetched = 0; $fileCount = 1; do { $this->info("Fetching batch {$fileCount} (offset: {$offset})"); $accessToken = $authService->getAccessToken(); $response = Http::withHeaders([ 'Client-ID' => config('services.igdb.credentials.client_id'), 'Authorization' => 'Bearer ' . $accessToken, ])->post($endpoint, [ 'fields' => $fields, 'limit' => $limit, 'offset' => $offset, 'where' => 'rating_count > 0', ]); if (!$response->successful()) { throw new \Exception("API request failed: " . $response->body()); } $data = $response->json(); $count = count($data); if ($count === 0) { break; } $filename = "{$type}_{$fileCount}.json"; $filepath = "{$outputDir}/{$filename}"; if (!file_put_contents($filepath, json_encode($data, JSON_PRETTY_PRINT))) { throw new \Exception("Failed to write to file: {$filepath}"); } $this->info("Saved {$count} items to {$filename}"); $totalFetched += $count; $offset += $limit; $fileCount++; // Sleep to avoid rate limiting sleep(1); } while ($count === $limit); $this->info("Total items fetched: {$totalFetched}"); } }