first commit
This commit is contained in:
@@ -0,0 +1,346 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Game;
|
||||
use App\Models\Genre;
|
||||
use App\Models\Platform;
|
||||
use App\Models\Artwork;
|
||||
use App\Models\Screenshot;
|
||||
use App\Models\Video;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use MarcReichel\IGDBLaravel\Models\Collection;
|
||||
use MarcReichel\IGDBLaravel\Models\Game as IgdbGame;
|
||||
use MarcReichel\IGDBLaravel\Models\Cover;
|
||||
use MarcReichel\IGDBLaravel\Models\Genre as IgdbGenre;
|
||||
use MarcReichel\IGDBLaravel\Models\Platform as IgdbPlatform;
|
||||
|
||||
class IgdbService
|
||||
{
|
||||
public function get()
|
||||
{
|
||||
try {
|
||||
$existingIds = $this->getExistingIds();
|
||||
|
||||
$queryBuilder = IgdbGame::select([
|
||||
'id',
|
||||
'name',
|
||||
'summary',
|
||||
'cover.url',
|
||||
'slug',
|
||||
'genres',
|
||||
'platforms',
|
||||
'first_release_date',
|
||||
'rating',
|
||||
'rating_count'
|
||||
])
|
||||
->where('rating_count', '>', 0)
|
||||
->where('category', '=', 0);
|
||||
|
||||
if (!empty($existingIds)) {
|
||||
$queryBuilder = $queryBuilder->whereNotIn('id', array_map(function($id) {
|
||||
return (int)str_replace('"', '', $id);
|
||||
}, $existingIds));
|
||||
}
|
||||
|
||||
$a = $queryBuilder
|
||||
->limit(50)
|
||||
->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->id;
|
||||
}
|
||||
|
||||
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)) {
|
||||
foreach ($gameData->platforms as $platformId) {
|
||||
if ($platformDetails = $this->getPlatformDetails($platformId)) {
|
||||
$platform = Platform::updateOrCreate(
|
||||
['igdb_id' => $platformDetails['id']],
|
||||
[
|
||||
'name' => $platformDetails['name'],
|
||||
'slug' => $platformDetails['slug'],
|
||||
'abbreviation' => $platformDetails['abbreviation'],
|
||||
]
|
||||
);
|
||||
$platforms[] = $platform->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Create or update the game
|
||||
$game = Game::updateOrCreate(
|
||||
['igdb_id' => $gameData->id],
|
||||
[
|
||||
'name' => $gameData->name,
|
||||
'summary' => $gameData->summary ?? null,
|
||||
'cover_url' => $gameData->cover?->url ?? null,
|
||||
'slug' => $gameData->slug,
|
||||
'first_release_date' => $gameData->first_release_date ?? null,
|
||||
'rating' => $gameData->rating ?? null,
|
||||
'rating_count' => $gameData->rating_count ?? null,
|
||||
]
|
||||
);
|
||||
|
||||
// Process artworks
|
||||
if (isset($gameData->artworks) && is_array($gameData->artworks)) {
|
||||
foreach ($gameData->artworks as $artwork) {
|
||||
Artwork::updateOrCreate(
|
||||
['igdb_id' => $artwork->id],
|
||||
[
|
||||
'game_id' => $game->id,
|
||||
'url' => $artwork->url,
|
||||
'width' => $artwork->width ?? null,
|
||||
'height' => $artwork->height ?? null,
|
||||
'image_id' => $artwork->image_id ?? null,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
// Process platforms relationship
|
||||
if (!empty($platforms)) {
|
||||
$game->platforms()->sync($platforms);
|
||||
}
|
||||
|
||||
// Process screenshots
|
||||
if (isset($gameData->screenshots) && is_array($gameData->screenshots)) {
|
||||
foreach ($gameData->screenshots as $screenshot) {
|
||||
Screenshot::updateOrCreate(
|
||||
['igdb_id' => $screenshot->id],
|
||||
[
|
||||
'game_id' => $game->id,
|
||||
'url' => $screenshot->url,
|
||||
'width' => $screenshot->width ?? null,
|
||||
'height' => $screenshot->height ?? null,
|
||||
'image_id' => $screenshot->image_id ?? null,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Process videos
|
||||
if (isset($gameData->videos) && is_array($gameData->videos)) {
|
||||
foreach ($gameData->videos as $video) {
|
||||
Video::updateOrCreate(
|
||||
['igdb_id' => $video->id],
|
||||
[
|
||||
'game_id' => $game->id,
|
||||
'name' => $video->name,
|
||||
'video_id' => $video->video_id,
|
||||
'url' => $video->url,
|
||||
'checksum' => $video->checksum ?? null,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 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');
|
||||
}
|
||||
|
||||
$relationships = [
|
||||
'bundles' => 'bundles',
|
||||
'collections' => 'collections',
|
||||
'dlcs' => 'dlcs',
|
||||
'expanded_games' => 'expansions',
|
||||
'franchises' => 'franchises',
|
||||
'ports' => 'ports',
|
||||
'remakes' => 'remakes',
|
||||
'similar_games' => 'similarGames',
|
||||
];
|
||||
|
||||
$collections = Collection::where('games', $gameData->identifier)->first();
|
||||
|
||||
dd(
|
||||
$gameData,
|
||||
$collections
|
||||
);
|
||||
|
||||
foreach ($relationships as $igdbKey => $relationship) {
|
||||
$relatedGames = [];
|
||||
if (isset($gameData->$igdbKey) && !empty($gameData->$igdbKey)) {
|
||||
$relatedIds = collect($gameData->$igdbKey)->pluck('id')->toArray();
|
||||
$relatedGames = Game::whereIn('igdb_id', $relatedIds)->pluck('id')->toArray();
|
||||
}
|
||||
$game->$relationship()->sync($relatedGames);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user