mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
175 lines
5.8 KiB
PHP
175 lines
5.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Game;
|
|
use GuzzleHttp\Client;
|
|
use Exception;
|
|
|
|
class ExophaseSyncService extends BaseSyncService
|
|
{
|
|
private Client $httpClient;
|
|
private ?string $apiKey;
|
|
private string $baseUrl;
|
|
private int $processedCount = 0;
|
|
private int $newCount = 0;
|
|
private int $updatedCount = 0;
|
|
|
|
public function __construct(\PDO $pdo, array $source, ?int $existingSyncLogId = null)
|
|
{
|
|
parent::__construct($pdo, $source, $existingSyncLogId);
|
|
$this->httpClient = new Client([
|
|
'timeout' => 30,
|
|
'headers' => [
|
|
'User-Agent' => 'MediaCollector/1.0',
|
|
'Authorization' => 'Bearer ' . $source['api_key']
|
|
]
|
|
]);
|
|
$this->apiKey = $source['api_key'];
|
|
$this->baseUrl = rtrim($source['api_url'] ?? 'https://api.exophase.com', '/');
|
|
}
|
|
|
|
protected function executeSync(string $syncType): void
|
|
{
|
|
if (empty($this->apiKey)) {
|
|
throw new Exception('Exophase API key not configured');
|
|
}
|
|
|
|
$this->logProgress('Starting Exophase gaming data sync...');
|
|
|
|
// Sync games from all supported platforms
|
|
$this->syncGames();
|
|
|
|
$this->logProgress("Processed {$this->processedCount} Exophase gaming items");
|
|
}
|
|
|
|
private function syncGames(): void
|
|
{
|
|
try {
|
|
$games = $this->getExophaseGames();
|
|
|
|
foreach ($games as $gameData) {
|
|
$this->syncGame($gameData);
|
|
$this->processedCount++;
|
|
}
|
|
} catch (Exception $e) {
|
|
$this->logProgress('Error syncing games: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
private function getExophaseGames(): array
|
|
{
|
|
try {
|
|
// Exophase API endpoint for user's games
|
|
$response = $this->httpClient->get("{$this->baseUrl}/v1/user/games");
|
|
|
|
$data = json_decode($response->getBody(), true);
|
|
|
|
if (!isset($data['games'])) {
|
|
throw new Exception('No games found in Exophase');
|
|
}
|
|
|
|
return $data['games'];
|
|
} catch (Exception $e) {
|
|
throw new Exception('Failed to fetch Exophase games: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
private function syncGame(array $gameData): void
|
|
{
|
|
$gameModel = new Game($this->pdo);
|
|
|
|
// Check if game already exists
|
|
$existingGame = $gameModel->findAll([
|
|
'source_id' => $this->sourceId
|
|
]);
|
|
|
|
// Find existing game by platform-specific ID or title
|
|
foreach ($existingGame as $game) {
|
|
$metadata = json_decode($game['metadata'], true);
|
|
if (isset($metadata['exophase_game_id']) && $metadata['exophase_game_id'] === $gameData['id']) {
|
|
$existingGame = [$game];
|
|
break;
|
|
}
|
|
}
|
|
|
|
$gameData = [
|
|
'title' => $gameData['title'] ?: 'Untitled Game',
|
|
'game_key' => Game::generateGameKey($gameData['title'], $gameData['platform'] ?? null),
|
|
'platform' => $this->mapPlatform($gameData['platform'] ?? 'unknown'),
|
|
'playtime_minutes' => $gameData['playtime_minutes'] ?? 0,
|
|
'completion_percentage' => $gameData['completion_percentage'] ?? 0,
|
|
'source_id' => $this->sourceId,
|
|
'last_played_at' => isset($gameData['last_played']) ? date('Y-m-d H:i:s', strtotime($gameData['last_played'])) : null,
|
|
'metadata' => json_encode([
|
|
'exophase_game_id' => $gameData['id'],
|
|
'exophase_platform' => $gameData['platform'] ?? null,
|
|
'achievements_earned' => $gameData['achievements_earned'] ?? 0,
|
|
'achievements_total' => $gameData['achievements_total'] ?? 0,
|
|
'trophies_earned' => $gameData['trophies_earned'] ?? 0,
|
|
'trophies_total' => $gameData['trophies_total'] ?? 0,
|
|
'gamerscore_earned' => $gameData['gamerscore_earned'] ?? 0,
|
|
'gamerscore_total' => $gameData['gamerscore_total'] ?? 0,
|
|
'last_achievement' => $gameData['last_achievement'] ?? null,
|
|
'first_achievement' => $gameData['first_achievement'] ?? null,
|
|
'rating' => $gameData['rating'] ?? null,
|
|
'genre' => $gameData['genre'] ?? null,
|
|
'developer' => $gameData['developer'] ?? null,
|
|
'publisher' => $gameData['publisher'] ?? null,
|
|
'release_date' => $gameData['release_date'] ?? null
|
|
])
|
|
];
|
|
|
|
if (empty($existingGame)) {
|
|
$gameModel->create($gameData);
|
|
$this->newCount++;
|
|
} else {
|
|
$gameModel->update($existingGame[0]['id'], $gameData);
|
|
$this->updatedCount++;
|
|
}
|
|
}
|
|
|
|
private function mapPlatform(string $platform): string
|
|
{
|
|
$platformMap = [
|
|
'steam' => 'PC',
|
|
'psn' => 'PlayStation',
|
|
'ps4' => 'PlayStation 4',
|
|
'ps5' => 'PlayStation 5',
|
|
'xbox' => 'Xbox',
|
|
'xbox360' => 'Xbox 360',
|
|
'xboxone' => 'Xbox One',
|
|
'xboxseries' => 'Xbox Series X/S',
|
|
'nintendo' => 'Nintendo',
|
|
'switch' => 'Nintendo Switch',
|
|
'epic' => 'Epic Games',
|
|
'gog' => 'GOG',
|
|
'origin' => 'Origin',
|
|
'uplay' => 'Ubisoft Connect',
|
|
'battlenet' => 'Battle.net'
|
|
];
|
|
|
|
return $platformMap[$platform] ?? ucfirst($platform);
|
|
}
|
|
|
|
protected function getProcessedCount(): int
|
|
{
|
|
return $this->processedCount;
|
|
}
|
|
|
|
protected function getNewCount(): int
|
|
{
|
|
return $this->newCount;
|
|
}
|
|
|
|
protected function getUpdatedCount(): int
|
|
{
|
|
return $this->updatedCount;
|
|
}
|
|
|
|
protected function getDeletedCount(): int
|
|
{
|
|
return 0; // Exophase doesn't provide deletion info in this context
|
|
}
|
|
}
|