Completed
Pull Request — master (#11)
by Laurens
02:39 queued 51s
created

GuzzleIzettleClient   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 5
dl 0
loc 141
ccs 70
cts 70
cp 1
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A setAccessToken() 0 5 1
A getAccessTokenFromUserLogin() 0 16 1
A refreshAccessToken() 0 16 1
A get() 0 12 2
A post() 0 13 1
A put() 0 14 1
A delete() 0 4 1
A getJson() 0 4 1
A getAuthorizationHeader() 0 6 1
A validateAccessToken() 0 12 2
A requestAccessToken() 0 14 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LauLamanApps\IzettleApi;
6
7
use DateTime;
8
use GuzzleHttp\ClientInterface;
9
use GuzzleHttp\Exception\RequestException;
10
use LauLamanApps\IzettleApi\Client\AccessToken;
11
use LauLamanApps\IzettleApi\Client\Exceptions\AccessTokenExpiredException;
12
use LauLamanApps\IzettleApi\Exception\NotFoundException;
13
use Psr\Http\Message\ResponseInterface;
14
15
class GuzzleIzettleClient implements IzettleClientInterface
16
{
17
    private $guzzleClient;
18
    private $clientId;
19
    private $clientSecret;
20
    private $accessToken;
21
22 19
    public function __construct(ClientInterface $guzzleClient, string $clientId, string $clientSecret)
23
    {
24 19
        $this->guzzleClient = $guzzleClient;
25 19
        $this->clientId = $clientId;
26 19
        $this->clientSecret = $clientSecret;
27 19
    }
28
29 19
    public function setAccessToken(AccessToken $accessToken): void
30
    {
31 19
        $this->accessToken = $accessToken;
32 19
        $this->validateAccessToken();
33 18
    }
34
35 1
    public function getAccessTokenFromUserLogin(string $username, string $password): AccessToken
36
    {
37
        $options = [
38
            'form_params' => [
39 1
                'grant_type' => self::API_ACCESS_TOKEN_PASSWORD_GRANT,
40 1
                'client_id' => $this->clientId,
41 1
                'client_secret' => $this->clientSecret,
42 1
                'username' => $username,
43 1
                'password' => $password
44
            ],
45
        ];
46
47 1
        $this->setAccessToken($this->requestAccessToken(self::API_ACCESS_TOKEN_REQUEST_URL, $options));
48
49 1
        return $this->accessToken;
50
    }
51
52 1
    public function refreshAccessToken(?AccessToken $accessToken =  null): AccessToken
53
    {
54 1
        $accessToken = $accessToken ?? $this->accessToken;
55
        $options = [
56
            'form_params' => [
57 1
                'grant_type' => self::API_ACCESS_TOKEN_REFRESH_TOKEN_GRANT,
58 1
                'client_id' => $this->clientId,
59 1
                'client_secret' => $this->clientSecret,
60 1
                'refresh_token' => $accessToken->getRefreshToken()
61
            ],
62
        ];
63
64 1
        $this->setAccessToken($this->requestAccessToken(self::API_ACCESS_TOKEN_REFRESH_TOKEN_URL, $options));
65
66 1
        return $this->accessToken;
67
    }
68
69 10
    public function get(string $url, ?array $queryParameters = null): ResponseInterface
70
    {
71 10
        $options =  array_merge(['headers' => $this->getAuthorizationHeader()], ['query' => $queryParameters]);
72
73
        try {
74 10
            $response = $this->guzzleClient->get($url, $options);
75 1
        } catch (RequestException $e) {
76 1
            throw new NotFoundException($e->getMessage());
77
        }
78
79 9
        return $response;
80
    }
81
82 2
    public function post(string $url, string $jsonData): void
83
    {
84 2
        $headers = array_merge(
85 2
            $this->getAuthorizationHeader(),
86
            [
87 2
                'content-type' => 'application/json',
88
                'Accept' => 'application/json',
89
            ]
90
        );
91
92 2
        $options =  array_merge(['headers' => $headers], ['body' => $jsonData]);
93 2
        $this->guzzleClient->post($url, $options);
94 2
    }
95
96 2
    public function put(string $url, string $jsonData): void
97
    {
98 2
        $headers = array_merge(
99 2
            $this->getAuthorizationHeader(),
100
            [
101 2
                'content-type' => 'application/json',
102
                'Accept' => 'application/json',
103
            ]
104
        );
105
106 2
        $options =  array_merge(['headers' => $headers], ['body' => $jsonData]);
107
108 2
        $this->guzzleClient->put($url, $options);
109 2
    }
110
111 1
    public function delete(string $url): void
112
    {
113 1
        $this->guzzleClient->delete($url, ['headers' => $this->getAuthorizationHeader()]);
114 1
    }
115
116 7
    public function getJson(ResponseInterface $response): string
117
    {
118 7
        return $response->getBody()->getContents();
119
    }
120
121 15
    private function getAuthorizationHeader(): array
122
    {
123 15
        $this->validateAccessToken();
124
125 15
        return ['Authorization' => sprintf('Bearer %s', $this->accessToken->getToken())];
126
    }
127
128 19
    private function validateAccessToken(): void
129
    {
130 19
        if ($this->accessToken->isExpired()) {
131 1
            throw new AccessTokenExpiredException(
132 1
                sprintf(
133 1
                    'Access Token was valid till \'%s\' it\'s now \'%s\'',
134 1
                    $this->accessToken->getExpires()->format('Y-m-d H:i:s.u'),
135 1
                    (new DateTime())->format('Y-m-d H:i:s.u')
136
                )
137
            );
138
        }
139 18
    }
140
141 2
    private function requestAccessToken($url, $options): AccessToken
142
    {
143 2
        $headers = ['headers' => ['Content-Type' => 'application/x-www-form-urlencoded']];
144 2
        $options = array_merge($headers, $options);
145
146 2
        $response = $this->guzzleClient->post($url, $options);
147 2
        $data = json_decode($response->getBody()->getContents(), true);
148
149 2
        return new AccessToken(
150 2
            $data['access_token'],
151 2
            new DateTime(sprintf('+%d second', $data['expires_in'])),
152 2
            $data['refresh_token']
153
        );
154
    }
155
}
156