Skip to content

Commit

Permalink
feat: refactor to use Guzzle
Browse files Browse the repository at this point in the history
  • Loading branch information
owenvoke committed Apr 24, 2024
1 parent c833f5f commit 29833f8
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 195 deletions.
23 changes: 13 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
{
"name": "retroachievements/api",
"description": "RetroAchievements Web API Client",
"type": "library",
"description": "RetroAchievements Web API Client",
"license": "MIT",
"keywords": [
"RetroAchievmenets",
"RetroAchievements",
"retro",
"achievements",
"API"
],
"homepage": "https://github.com/retroachievements/api-php",
"license": "MIT",
"require": {
"php": "^8.2"
"php": "^8.2",
"guzzlehttp/guzzle": "^6.5.8|^7.8.1"
},
"require-dev": {},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"sort-packages": true
"require-dev": {
"symfony/var-dumper": "^6.4|^7.0"
},
"autoload": {
"psr-4": {
Expand All @@ -29,5 +27,10 @@
"Tests\\": "tests"
}
},
"scripts": {}
"scripts": {},
"config": {
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}
11 changes: 11 additions & 0 deletions src/Exceptions/GenericException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace RetroAchievements\Api\Exceptions;

use Exception;

class GenericException extends Exception implements RetroAchievementsException
{
}
11 changes: 11 additions & 0 deletions src/Exceptions/NotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace RetroAchievements\Api\Exceptions;

use Exception;

class NotFoundException extends Exception implements RetroAchievementsException
{
}
9 changes: 9 additions & 0 deletions src/Exceptions/RetroAchievementsException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace RetroAchievements\Api\Exceptions;

interface RetroAchievementsException
{
}
11 changes: 11 additions & 0 deletions src/Exceptions/UnauthorizedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace RetroAchievements\Api\Exceptions;

use Exception;

class UnauthorizedException extends Exception implements RetroAchievementsException
{
}
68 changes: 68 additions & 0 deletions src/MakesHttpRequests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

namespace RetroAchievements\Api;

use Psr\Http\Message\ResponseInterface;
use RetroAchievements\Api\Exceptions\GenericException;
use RetroAchievements\Api\Exceptions\NotFoundException;
use RetroAchievements\Api\Exceptions\UnauthorizedException;

trait MakesHttpRequests
{
protected function get(string $uri)
{
return $this->request('GET', $uri);
}

protected function post(string $uri, array $payload = [])
{
return $this->request('POST', $uri, $payload);
}

protected function put(string $uri, array $payload = [])
{
return $this->request('PUT', $uri, $payload);
}

protected function delete(string $uri, array $payload = [])
{
return $this->request('DELETE', $uri, $payload);
}

protected function request(string $verb, string $uri, array $payload = [])
{
$response = $this->client->request(
$verb,
$uri,
empty($payload) ? [] : ['form_params' => $payload]
);

if (! $this->isSuccessful($response)) {
$this->handleRequestError($response);
}

$responseBody = (string) $response->getBody();

return json_decode($responseBody, true) ?: $responseBody;
}

protected function isSuccessful(ResponseInterface $response): bool
{
return (int) substr((string) $response->getStatusCode(), 0, 1) === 2;
}

protected function handleRequestError(ResponseInterface $response): void
{
if ($response->getStatusCode() === 404) {
throw new NotFoundException((string) $response->getBody());
}

if ($response->getStatusCode() === 401) {
throw new UnauthorizedException((string) $response->getBody());
}

throw new GenericException((string) $response->getBody());
}
}
145 changes: 145 additions & 0 deletions src/RetroAchievements.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php

declare(strict_types=1);

namespace RetroAchievements\Api;

use GuzzleHttp\Client;

class RetroAchievements
{
use MakesHttpRequests;

const API_URL = 'https://retroachievements.org/API/';

const API_VERSION = 1;

protected Client $client;

public function __construct(public string $username, public string $apiKey, string $baseUri = self::API_URL)
{
$this->client = new Client([
'base_uri' => $baseUri,
'http_errors' => false,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
],
]);
}

public function setClient(Client $client): self
{
$this->client = $client;

return $this;
}

public function getTopTenUsers(): mixed
{
return $this->get($this->getApiUrl('API_GetTopTenUsers.php'));
}

public function getGameInfo(int $gameID): mixed
{
return $this->get($this->getApiUrl('API_GetGame.php', [
'i' => $gameID,
]));
}

public function getGameInfoExtended(int $gameID): mixed
{
return $this->get($this->getApiUrl('API_GetGameExtended.php', [
'i' => $gameID,
]));
}

public function getConsoleIDs(): mixed
{
return $this->get($this->getApiUrl('API_GetConsoleIDs.php'));
}

public function getGameList(int $consoleID): mixed
{
return $this->get($this->getApiUrl('API_GetGameList.php', [
'i' => $consoleID,
]));
}

public function getFeedFor(string $user, int $count, int $offset = 0): mixed
{
return $this->get($this->getApiUrl('API_GetFeed.php', [
'u' => $user,
'c' => $count,
'o' => $offset,
]));
}

public function getUserRankAndScore(string $user): mixed
{
return $this->get($this->getApiUrl('API_GetUserRankAndScore.php', [
'u' => $user,
]));
}

public function getUserProgress(string $user, string $gameIDCSV): mixed
{
$gameIDCSV = preg_replace('/\s+/', '', $gameIDCSV); // Remove all whitespace

return $this->get($this->getApiUrl('API_GetUserProgress.php', [
'u' => $user,
'i' => $gameIDCSV,
]));
}

public function getUserRecentlyPlayedGames(string $user, int $count, int $offset = 0): mixed
{
return $this->get($this->getApiUrl('API_GetUserRecentlyPlayedGames.php', [
'u' => $user,
'c' => $count,
'o' => $offset,
]));
}

public function getUserSummary(string $user, int $numRecentGames): mixed
{
return $this->get($this->getApiUrl('API_GetUserSummary.php', [
'u' => $user,
'g' => $numRecentGames,
'a' => 5,
]));
}

public function getGameInfoAndUserProgress(string $user, int $gameID): mixed
{
return $this->get($this->getApiUrl('API_GetGameInfoAndUserProgress.php', [
'u' => $user,
'g' => $gameID,
]));
}

public function getAchievementsEarnedOnDay(string $user, string $date): mixed
{
return $this->get($this->getApiUrl('API_GetAchievementsEarnedOnDay.php', [
'u' => $user,
'd' => $date,
]));
}

public function getAchievementsEarnedBetween(string $user, string $startDate, string $endDate): mixed
{
return $this->get($this->getApiUrl('API_GetAchievementsEarnedBetween.php', [
'u' => $user,
'f' => strtotime($startDate),
't' => strtotime($endDate),
]));
}

protected function getApiUrl(string $endpoint, array $parameters = []): string
{
return sprintf('%s?%s', $endpoint, http_build_query([
'z' => $this->username,
'y' => $this->apiKey,
] + $parameters));
}
}
Loading

0 comments on commit 29833f8

Please sign in to comment.