Skip to content

Commit 6242a5f

Browse files
authored
Merge pull request #1 from simivar/feature/third-party-code-api
Add version 4 of ThirdPartyCode and Summoner APIs
2 parents 80d350c + 425fbab commit 6242a5f

16 files changed

+735
-1
lines changed

composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
}
1515
],
1616
"require": {
17-
"php": ">=7.4"
17+
"php": ">=7.4",
18+
"psr/http-client": "^1.0",
19+
"psr/http-message": "^1.0",
20+
"psr/http-factory": "^1.0"
1821
},
1922
"autoload": {
2023
"psr-4": {

src/Riot/API.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riot;
6+
7+
use Riot\API\Version4\Summoner;
8+
use Riot\API\Version4\ThirdPartyCode;
9+
10+
final class API
11+
{
12+
private ConnectionInterface $riotConnection;
13+
14+
/** @var array<string, mixed> */
15+
private array $apis;
16+
17+
public function __construct(ConnectionInterface $riotConnection)
18+
{
19+
$this->riotConnection = $riotConnection;
20+
}
21+
22+
public function getSummonerV4Api(): Summoner
23+
{
24+
if (!isset($this->apis['summonerV4'])) {
25+
$this->apis['summonerV4'] = new Summoner($this->riotConnection);
26+
}
27+
28+
return $this->apis['summonerV4'];
29+
}
30+
31+
public function getThirdPartyCodeV4Api(): ThirdPartyCode
32+
{
33+
if (!isset($this->apis['thirdPartyCodeV4'])) {
34+
$this->apis['thirdPartyCodeV4'] = new ThirdPartyCode($this->riotConnection);
35+
}
36+
37+
return $this->apis['thirdPartyCodeV4'];
38+
}
39+
}

src/Riot/API/AbstractApi.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riot\API;
6+
7+
use Riot\ConnectionInterface;
8+
9+
abstract class AbstractApi
10+
{
11+
protected ConnectionInterface $riotConnection;
12+
13+
public function __construct(ConnectionInterface $riotConnection)
14+
{
15+
$this->riotConnection = $riotConnection;
16+
}
17+
}

src/Riot/API/Version4/Summoner.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riot\API\Version4;
6+
7+
use function json_decode;
8+
use Riot\API\AbstractApi;
9+
use Riot\DTO\SummonerDTO;
10+
use Riot\Exception\RateLimitExceededException;
11+
12+
final class Summoner extends AbstractApi
13+
{
14+
/**
15+
* @throws RateLimitExceededException
16+
* @throws \JsonException
17+
*/
18+
public function getByName(string $summonerName, string $region): ?SummonerDTO
19+
{
20+
$response = $this->riotConnection->get(
21+
$region,
22+
sprintf('lol/summoner/v4/summoners/by-name/%s', $summonerName),
23+
);
24+
25+
if (null === $response) {
26+
return null;
27+
}
28+
29+
$body = $response->getBody()->getContents();
30+
31+
return SummonerDTO::createFromArray(json_decode($body, true, 512, JSON_THROW_ON_ERROR));
32+
}
33+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riot\API\Version4;
6+
7+
use Riot\API\AbstractApi;
8+
use Riot\Exception\RateLimitExceededException;
9+
10+
final class ThirdPartyCode extends AbstractApi
11+
{
12+
/**
13+
* @throws RateLimitExceededException
14+
* @throws \JsonException
15+
*/
16+
public function getBySummonerId(string $encryptedSummonerId, string $region): ?string
17+
{
18+
$response = $this->riotConnection->get(
19+
$region,
20+
sprintf('lol/platform/v4/third-party-code/by-summoner/%s', $encryptedSummonerId),
21+
);
22+
23+
if (null === $response) {
24+
return null;
25+
}
26+
27+
$body = $response->getBody()->getContents();
28+
29+
return json_decode($body, true, 512, JSON_THROW_ON_ERROR);
30+
}
31+
}

src/Riot/Connection.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riot;
6+
7+
use Psr\Http\Client\ClientInterface;
8+
use Psr\Http\Message\RequestFactoryInterface;
9+
use Psr\Http\Message\ResponseInterface;
10+
use Riot\Exception\RateLimitExceededException;
11+
12+
final class Connection implements ConnectionInterface
13+
{
14+
private const API_URL = 'api.riotgames.com';
15+
16+
private const STATUS_CODE_LIMIT_EXCEEDED = 429;
17+
private const STATUS_CODE_OK = 200;
18+
19+
private ClientInterface $client;
20+
21+
private string $riotApiToken;
22+
23+
private RequestFactoryInterface $requestFactory;
24+
25+
public function __construct(ClientInterface $riotClient, string $riotApiToken, RequestFactoryInterface $requestFactory)
26+
{
27+
$this->client = $riotClient;
28+
$this->riotApiToken = $riotApiToken;
29+
$this->requestFactory = $requestFactory;
30+
}
31+
32+
public function get(string $region, string $path): ?ResponseInterface
33+
{
34+
$request = $this->requestFactory->createRequest(
35+
'GET',
36+
sprintf('https://%s.%s/%s', $region, self::API_URL, $path),
37+
);
38+
$request = $request->withAddedHeader('X-Riot-Token', $this->riotApiToken);
39+
40+
$response = $this->client->sendRequest($request);
41+
if (self::STATUS_CODE_LIMIT_EXCEEDED === $response->getStatusCode()) {
42+
throw RateLimitExceededException::createFromResponse($response);
43+
}
44+
45+
// todo throw exception?
46+
if (self::STATUS_CODE_OK !== $response->getStatusCode()) {
47+
return null;
48+
}
49+
50+
return $response;
51+
}
52+
}

src/Riot/ConnectionInterface.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riot;
6+
7+
use Psr\Http\Message\ResponseInterface;
8+
9+
interface ConnectionInterface
10+
{
11+
public function get(string $region, string $path): ?ResponseInterface;
12+
}

src/Riot/DTO/DTOInterface.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riot\DTO;
6+
7+
interface DTOInterface
8+
{
9+
/**
10+
* @param array<string, mixed> $data
11+
*/
12+
public static function createFromArray(array $data): self;
13+
}

src/Riot/DTO/SummonerDTO.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riot\DTO;
6+
7+
final class SummonerDTO implements DTOInterface
8+
{
9+
private string $accountId;
10+
11+
private int $profileIconId;
12+
13+
private int $revisionDate;
14+
15+
private string $name;
16+
17+
private string $id;
18+
19+
private string $puuid;
20+
21+
private int $summonerLevel;
22+
23+
public function __construct(
24+
string $accountId,
25+
int $profileIconId,
26+
int $revisionDate,
27+
string $name,
28+
string $id,
29+
string $puuid,
30+
int $summonerLevel
31+
) {
32+
$this->accountId = $accountId;
33+
$this->profileIconId = $profileIconId;
34+
$this->revisionDate = $revisionDate;
35+
$this->name = $name;
36+
$this->id = $id;
37+
$this->puuid = $puuid;
38+
$this->summonerLevel = $summonerLevel;
39+
}
40+
41+
public function getAccountId(): string
42+
{
43+
return $this->accountId;
44+
}
45+
46+
public function getProfileIconId(): int
47+
{
48+
return $this->profileIconId;
49+
}
50+
51+
public function getRevisionDate(): int
52+
{
53+
return $this->revisionDate;
54+
}
55+
56+
public function getName(): string
57+
{
58+
return $this->name;
59+
}
60+
61+
public function getId(): string
62+
{
63+
return $this->id;
64+
}
65+
66+
public function getPuuid(): string
67+
{
68+
return $this->puuid;
69+
}
70+
71+
public function getSummonerLevel(): int
72+
{
73+
return $this->summonerLevel;
74+
}
75+
76+
/**
77+
* @param array<string, mixed> $data
78+
*/
79+
public static function createFromArray(array $data): SummonerDTO
80+
{
81+
return new self(
82+
$data['accountId'],
83+
$data['profileIconId'],
84+
$data['revisionDate'],
85+
$data['name'],
86+
$data['id'],
87+
$data['puuid'],
88+
$data['summonerLevel'],
89+
);
90+
}
91+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Riot\Exception;
6+
7+
use Psr\Http\Message\ResponseInterface;
8+
9+
final class RateLimitExceededException extends RiotApiException
10+
{
11+
private int $retryAfter;
12+
13+
private string $rateLimitType;
14+
private string $appRateLimit;
15+
private string $appRateLimitCount;
16+
private string $methodRateLimit;
17+
private string $methodRateLimitCount;
18+
19+
public function __construct(
20+
string $message,
21+
int $retryAfter,
22+
string $rateLimitType,
23+
string $appRateLimit,
24+
string $appRateLimitCount,
25+
string $methodRateLimit,
26+
string $methodRateLimitCount
27+
) {
28+
parent::__construct($message);
29+
$this->retryAfter = $retryAfter;
30+
$this->rateLimitType = $rateLimitType;
31+
$this->appRateLimit = $appRateLimit;
32+
$this->appRateLimitCount = $appRateLimitCount;
33+
$this->methodRateLimit = $methodRateLimit;
34+
$this->methodRateLimitCount = $methodRateLimitCount;
35+
}
36+
37+
public function getRetryAfter(): int
38+
{
39+
return $this->retryAfter;
40+
}
41+
42+
public function getRateLimitType(): string
43+
{
44+
return $this->rateLimitType;
45+
}
46+
47+
public function getAppRateLimit(): string
48+
{
49+
return $this->appRateLimit;
50+
}
51+
52+
public function getAppRateLimitCount(): string
53+
{
54+
return $this->appRateLimitCount;
55+
}
56+
57+
public function getMethodRateLimit(): string
58+
{
59+
return $this->methodRateLimit;
60+
}
61+
62+
public function getMethodRateLimitCount(): string
63+
{
64+
return $this->methodRateLimitCount;
65+
}
66+
67+
public static function createFromResponse(ResponseInterface $response): self
68+
{
69+
return new self(
70+
'Rate limit exceeded',
71+
(int) $response->getHeader('retry-after')[0],
72+
$response->getHeader('x-rate-limit-type')[0],
73+
$response->getHeader('x-app-rate-limit')[0],
74+
$response->getHeader('x-app-rate-limit-count')[0],
75+
$response->getHeader('x-method-rate-limit')[0],
76+
$response->getHeader('x-method-rate-limit-count')[0],
77+
);
78+
}
79+
}

0 commit comments

Comments
 (0)