121 lines
3.3 KiB
PHP
121 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Features\Scraper\Services;
|
|
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
class IGDBCoverScraper implements CoverScraperInterface
|
|
{
|
|
private string $clientId;
|
|
|
|
private string $clientSecret;
|
|
|
|
private ?string $accessToken = null;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->clientId = config('services.igdb.client_id', '');
|
|
$this->clientSecret = config('services.igdb.client_secret', '');
|
|
}
|
|
|
|
public function search(string $query, ?int $consoleId = null): Collection
|
|
{
|
|
if (empty($this->clientId) || empty($this->clientSecret)) {
|
|
return collect();
|
|
}
|
|
|
|
$body = "search \"{$query}\"; fields name,cover.url,platforms,release_dates.year;";
|
|
if ($consoleId) {
|
|
$body .= " where platforms = [{$consoleId}];";
|
|
}
|
|
|
|
$response = $this->makeRequest('/games', $body);
|
|
|
|
return collect($response)->map(fn ($game) => [
|
|
'id' => $game['id'],
|
|
'title' => $game['name'],
|
|
'cover_url' => isset($game['cover']['url'])
|
|
? str_replace('thumb', 'cover_big', $game['cover']['url'])
|
|
: null,
|
|
'year' => $game['release_dates'][0]['year'] ?? null,
|
|
'source' => 'igdb',
|
|
]);
|
|
}
|
|
|
|
public function getCoverUrl(int $externalId): ?string
|
|
{
|
|
if (empty($this->clientId) || empty($this->clientSecret)) {
|
|
return null;
|
|
}
|
|
|
|
$response = $this->makeRequest(
|
|
'/covers',
|
|
"fields url; where game = {$externalId};"
|
|
);
|
|
|
|
if (! empty($response[0]['url'])) {
|
|
return str_replace('thumb', 'cover_big', $response[0]['url']);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function getScreenshotUrl(int $externalId): ?string
|
|
{
|
|
if (empty($this->clientId) || empty($this->clientSecret)) {
|
|
return null;
|
|
}
|
|
|
|
$response = $this->makeRequest(
|
|
'/screenshots',
|
|
"fields url; where game = {$externalId};"
|
|
);
|
|
|
|
return $response[0]['url'] ?? null;
|
|
}
|
|
|
|
public function getImages(int $externalId): array
|
|
{
|
|
return array_filter([
|
|
'cover' => $this->getCoverUrl($externalId),
|
|
'screenshot' => $this->getScreenshotUrl($externalId),
|
|
]);
|
|
}
|
|
|
|
private function makeRequest(string $endpoint, string $body): array
|
|
{
|
|
try {
|
|
$this->ensureAccessToken();
|
|
|
|
$response = Http::withHeaders([
|
|
'Client-ID' => $this->clientId,
|
|
'Authorization' => "Bearer {$this->accessToken}",
|
|
])->timeout(10)->post("https://api.igdb.com/v4{$endpoint}", $body);
|
|
|
|
if ($response->successful()) {
|
|
return $response->json();
|
|
}
|
|
} catch (\Exception $e) {
|
|
// Log error
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
private function ensureAccessToken(): void
|
|
{
|
|
if ($this->accessToken) {
|
|
return;
|
|
}
|
|
|
|
$response = Http::asForm()->post('https://id.twitch.tv/oauth2/token', [
|
|
'client_id' => $this->clientId,
|
|
'client_secret' => $this->clientSecret,
|
|
'grant_type' => 'client_credentials',
|
|
]);
|
|
|
|
$this->accessToken = $response->json('access_token');
|
|
}
|
|
}
|