Passed
Push — master ( 881b80...a7445e )
by Jérémy
01:38
created

Client::clientApi()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace JDecool\Clockify;
6
7
use Http\Client\Common\HttpMethodsClient;
8
use JDecool\Clockify\{
9
    Api\Client\Client as ClientApi,
10
    Api\Tag\Tag,
11
    Api\Workspace\Workspace,
12
    Exception\ClockifyException,
13
    Exception\BadRequest,
14
    Exception\Forbidden,
15
    Exception\NotFound,
16
    Exception\Unauthorized
17
};
18
use Psr\Http\Message\ResponseInterface;
19
use RuntimeException;
20
21
class Client
22
{
23
    private $http;
24
    private $baseUri;
25
    private $apiKey;
26
27
    public function __construct(HttpMethodsClient $http, string $baseUri, string $apiKey)
28
    {
29
        if (false === filter_var($baseUri, FILTER_VALIDATE_URL)) {
30
            throw new RuntimeException('Invalid Clockify endpoint.');
31
        }
32
33
        $this->http = $http;
34
        $this->baseUri = $baseUri;
35
        $this->apiKey = $apiKey;
36
    }
37
38
    public function clientApi(): ClientApi
39
    {
40
        return new ClientApi($this);
41
    }
42
43
    public function tagApi(): Tag
44
    {
45
        return new Tag($this);
46
    }
47
48
    public function workspaceApi(): Workspace
49
    {
50
        return new Workspace($this);
51
    }
52
53
    public function get(string $uri, array $params = []): array
54
    {
55
        $response = $this->http->get(
56
            $this->endpoint($uri, $params),
57
            ['X-Api-Key' => $this->apiKey]
58
        );
59
60
        if (200 !== $response->getStatusCode()) {
61
            throw $this->createExceptionFromResponse($response);
62
        }
63
64
        return json_decode($response->getBody()->getContents(), true);
65
    }
66
67
    public function post(string $uri, array $data): array
68
    {
69
        $response = $this->http->post(
70
            $this->endpoint($uri),
71
            [
72
                'Content-Type' => 'application/json',
73
                'X-Api-Key' => $this->apiKey,
74
            ],
75
            json_encode($data)
76
        );
77
78
        if (201 !== $response->getStatusCode()) {
79
            throw $this->createExceptionFromResponse($response);
80
        }
81
82
        return json_decode($response->getBody()->getContents(), true);
83
    }
84
85
    public function put(string $uri, array $data): array
86
    {
87
        $response = $this->http->put(
88
            $this->endpoint($uri),
89
            [
90
                'Content-Type' => 'application/json',
91
                'X-Api-Key' => $this->apiKey,
92
            ],
93
            json_encode($data)
94
        );
95
96
        if (!in_array($response->getStatusCode(), [200, 201], true)) {
97
            throw $this->createExceptionFromResponse($response);
98
        }
99
100
        return json_decode($response->getBody()->getContents(), true);
101
    }
102
103
    public function patch(string $uri, array $data): array
104
    {
105
        $response = $this->http->patch(
106
            $this->endpoint($uri),
107
            [
108
                'Content-Type' => 'application/json',
109
                'X-Api-Key' => $this->apiKey,
110
            ],
111
            json_encode($data)
112
        );
113
114
        if (!in_array($response->getStatusCode(), [200, 204], true)) {
115
            throw $this->createExceptionFromResponse($response);
116
        }
117
118
        return json_decode($response->getBody()->getContents(), true);
119
    }
120
121
    public function delete(string $uri): void
122
    {
123
        $response = $this->http->delete(
124
            $this->endpoint($uri)
125
        );
126
127
        if (204 !== $response->getStatusCode()) {
128
            throw $this->createExceptionFromResponse($response);
129
        }
130
    }
131
132
    private function endpoint(string $uri, array $params = []): string
133
    {
134
        $endpoint = sprintf(
135
            '%s/%s',
136
            rtrim($this->baseUri, '/'),
137
            ltrim($uri, '/')
138
        );
139
140
        if (!empty($params)) {
141
            $endpoint .= http_build_query($params);
142
        }
143
144
        return $endpoint;
145
    }
146
147
    private function createExceptionFromResponse(ResponseInterface $response): ClockifyException
148
    {
149
        switch ($response->getStatusCode()) {
150
            case 400:
151
                return new BadRequest();
152
153
            case 401:
154
                return new Unauthorized();
155
156
            case 403:
157
                return new Forbidden();
158
159
            case 404:
160
                return new NotFound();
161
        }
162
163
        return new ClockifyException();
164
    }
165
}
166