Files
MediaCollectorLibary/app/Services/ExophaseSyncService.php
Lars Behrends 0f95458466 sync logs :D
2025-10-19 14:54:33 +02:00

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
}
}