getExistingIds(); $queryBuilder = IgdbGame::select([ 'id', 'name', 'summary', 'cover', 'slug', 'genres', 'platforms', 'first_release_date', 'rating', 'rating_count' ]) // ->where('rating_count', '>', 0) // ->where('category', '=', 0) ; if ($startDate) { $queryBuilder->where('first_release_date', '>=', $startDate); } if ($endDate) { $queryBuilder->where('first_release_date', '<=', $endDate); } if (!empty($existingIds)) { // Convert array of quoted strings to array of integers // $existingIds = array_map(function($id) { // return (int)str_replace('"', '', $id); // }, $existingIds); $queryBuilder->whereNotIn('id', $existingIds); } $a = $queryBuilder ->orderBy('first_release_date', 'asc') ->limit($limit) ->get(); }catch (\Throwable $e) { dd( $e->getMessage(), $e->getTrace() ); } return $a; } private function getExistingIds(): ?array { $existingGames = Game::get(); if (empty($existingGames)) { return null; } $existingIds = []; /** @var Game $existingGame */ foreach ($existingGames as $existingGame) { $existingIds[] = (string)$existingGame->igdb_id; } return $existingIds; // return array_map(function($id) { // return '"'.$id.'"'; // }, $existingIds); } public function searchGames(string $query, int $limit = 10, ?int $startTimestamp = null, ?int $endTimestamp = null): array { try { $queryBuilder = IgdbGame::select([ 'id', 'name', 'summary', 'cover', 'slug', 'genres', 'platforms', 'first_release_date', 'rating', 'rating_count' ]) ->where('rating_count', '>', 0) ->where('category', '=', 0) // Only main games, no DLCs or expansions ->limit($limit) ->orderBy('rating', 'desc'); if ($startTimestamp && $endTimestamp) { $queryBuilder->where('first_release_date', '>=', $startTimestamp) ->where('first_release_date', '<=', $endTimestamp); } if ($query) { $queryBuilder->search($query); } return $queryBuilder->get()->toArray(); } catch (\Exception $e) { Log::error('Failed to search games', [ 'query' => $query, 'error' => $e->getMessage() ]); return []; } } public function getGameDetails(int $igdbId): ?array { try { $game = IgdbGame::select([ 'id', 'name', 'summary', 'storyline', 'cover.url', 'slug', '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' ]) ->where('id', $igdbId) ->first(); if (!$game) { return null; } return $game->toArray(); } catch (\Exception $e) { Log::error('Failed to fetch game details from IGDB', [ 'igdb_id' => $igdbId, 'error' => $e->getMessage() ]); return null; } } public function getGameCover(int $coverId): ?string { try { return Cover::select(['url']) ->where('id', $coverId) ->first() ?->url; } catch (\Exception $e) { Log::error('Failed to get game cover', [ 'id' => $coverId, 'error' => $e->getMessage() ]); return null; } } public function getGenreDetails(int $genreId): ?array { try { return IgdbGenre::select(['id', 'name', 'slug']) ->where('id', $genreId) ->first() ?->toArray(); } catch (\Exception $e) { Log::error('Failed to get genre details', [ 'id' => $genreId, 'error' => $e->getMessage() ]); return null; } } public function getPlatformDetails(int $platformId): ?array { try { return IgdbPlatform::select(['id', 'name', 'slug', 'abbreviation']) ->where('id', $platformId) ->first() ?->toArray(); } catch (\Exception $e) { Log::error('Failed to get platform details', [ 'id' => $platformId, 'error' => $e->getMessage() ]); return null; } } public function processGameData(IgdbGame $gameData): Game { // Process platforms $platforms = []; if (isset($gameData->platforms) && is_array($gameData->platforms)) { $platformData = IgdbPlatform::select(['id', 'name', 'slug', 'abbreviation']) ->whereIn('id', $gameData->platforms) ->get(); foreach ($platformData as $platformDetails) { $platform = Platform::updateOrCreate( ['igdb_id' => $platformDetails->id], [ 'name' => $platformDetails->name, 'slug' => $platformDetails->slug, 'abbreviation' => $platformDetails->abbreviation, ] ); $platforms[] = $platform->id; } } // Process genres $genres = []; if (isset($gameData->genres) && is_array($gameData->genres)) { $genreData = IgdbGenre::select(['id', 'name', 'slug']) ->whereIn('id', $gameData->genres) ->get(); foreach ($genreData as $genreDetails) { $genre = Genre::updateOrCreate( ['igdb_id' => $genreDetails->id], [ 'name' => $genreDetails->name, 'slug' => $genreDetails->slug, ] ); $genres[] = $genre->id; } } $cover = Cover::where('game', '=', $gameData->id)->first(); $coverUrl = null; if ($cover) { $coverUrl = 'https:'.$cover->url; $coverUrl = str_replace('t_thumb', 't_cover_big', $coverUrl); } // Create or update the game $game = Game::updateOrCreate( ['igdb_id' => $gameData->id], [ 'name' => $gameData->name, 'summary' => $gameData->summary ?? null, 'cover_url' => $coverUrl, 'slug' => $gameData->slug, 'first_release_date' => $gameData->first_release_date ?? null, 'rating' => $gameData->rating ?? null, 'rating_count' => $gameData->rating_count ?? null, ] ); // Sync platforms and genres if (!empty($platforms)) { $game->platforms()->sync($platforms); } if (!empty($genres)) { $game->genres()->sync($genres); } // Process artworks try { $artworks = \MarcReichel\IGDBLaravel\Models\Artwork::select([ 'id', 'url', 'width', 'height', 'image_id' ]) ->where('game', '=', $gameData->id) ->get(); foreach ($artworks as $artworkData) { Artwork::updateOrCreate( ['igdb_id' => $artworkData->id], [ 'game_id' => $game->id, 'url' => $artworkData->url, 'width' => $artworkData->width ?? null, 'height' => $artworkData->height ?? null, 'image_id' => $artworkData->image_id ?? null, ] ); } } catch (\Exception $e) { Log::error('Failed to get artworks for game', [ 'game_id' => $game->id, 'error' => $e->getMessage() ]); } // Process screenshots try { $screenshots = \MarcReichel\IGDBLaravel\Models\Screenshot::select([ 'id', 'url', 'width', 'height', 'image_id' ]) ->where('game', '=', $gameData->id) ->get(); foreach ($screenshots as $screenshotData) { Screenshot::updateOrCreate( ['igdb_id' => $screenshotData->id], [ 'game_id' => $game->id, 'url' => $screenshotData->url, 'width' => $screenshotData->width ?? null, 'height' => $screenshotData->height ?? null, 'image_id' => $screenshotData->image_id ?? null, ] ); } } catch (\Exception $e) { Log::error('Failed to get screenshots for game', [ 'game_id' => $game->id, 'error' => $e->getMessage() ]); } // Process videos try { $videos = \MarcReichel\IGDBLaravel\Models\GameVideo::select([ 'id', 'name', 'video_id', 'url', 'checksum' ]) ->where('game', '=', $gameData->id) ->get(); foreach ($videos as $videoData) { Video::updateOrCreate( ['igdb_id' => $videoData->id], [ 'game_id' => $game->id, 'name' => $videoData->name, 'video_id' => $videoData->video_id, 'url' => $videoData->url, 'checksum' => $videoData->checksum ?? null, ] ); } } catch (\Exception $e) { Log::error('Failed to get videos for game', [ 'game_id' => $game->id, 'error' => $e->getMessage() ]); } // Process relationships $this->processGameRelationships($game, $gameData); return $game; } private function processGameRelationships(Game $game,IgdbGame $gameData): void { // Ensure $gameData is an IgdbGame instance if (!($gameData instanceof \MarcReichel\IGDBLaravel\Models\Game)) { throw new \InvalidArgumentException('Game data must be an instance of IgdbGame'); } // Initialize relationships array $relationships = []; // Define relationship mappings and check each one $relationshipMappings = [ 'bundles', 'collections', 'dlcs', 'expanded_games', 'franchises', 'ports', 'remakes', 'similar_games' ]; // Only query IGDB for relationships that have data foreach ($relationshipMappings as $relationship) { if (!empty($gameData->$relationship)) { $relationships[$relationship] = IgdbGame::select(['id']) ->where('id', 'in', $gameData->$relationship) ->get() ->pluck('id') ->toArray(); } else { $relationships[$relationship] = []; } } // Process and sync each relationship foreach ($relationships as $igdbKey => $relatedIds) { // Convert IGDB relationship key to Laravel relationship method $relationshipMethod = str_replace('_', '', $igdbKey); // Remove underscores $relatedGames = []; if (!empty($relatedIds)) { $relatedGames = Game::whereIn('igdb_id', $relatedIds)->pluck('id')->toArray(); } // Only sync if the relationship method exists if (method_exists($game, $relationshipMethod)) { Log::info("Syncing relationship '$relationshipMethod' for game {$game->id}"); $game->$relationshipMethod()->sync($relatedGames); } else { Log::warning("Relationship method '$relationshipMethod' does not exist on Game model", [ 'game_id' => $game->id, 'igdb_key' => $igdbKey ]); } } } public function processGenreData(array $genreData): void { try { Genre::updateOrCreate( ['igdb_id' => $genreData['id']], [ 'name' => $genreData['name'], 'slug' => $genreData['slug'], ] ); } catch (\Exception $e) { Log::error('Failed to process genre data', [ 'genre_id' => $genreData['id'], 'error' => $e->getMessage() ]); throw $e; } } public function processPlatformData(array $platformData): void { try { Platform::updateOrCreate( ['igdb_id' => $platformData['id']], [ 'name' => $platformData['name'], 'slug' => $platformData['slug'], 'abbreviation' => $platformData['abbreviation'] ?? null, ] ); } catch (\Exception $e) { Log::error('Failed to process platform data', [ 'platform_id' => $platformData['id'], 'error' => $e->getMessage() ]); throw $e; } } }