Passed
Pull Request — master (#93)
by Julien
02:39
created

RestClient::setLogHistory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Mapado\RestClientSdk;
6
7
use GuzzleHttp\ClientInterface;
8
use GuzzleHttp\Exception\ClientException;
9
use GuzzleHttp\Exception\RequestException;
10
use GuzzleHttp\Exception\TransferException;
11
use Mapado\RestClientSdk\Exception\RestClientException;
12
use Mapado\RestClientSdk\Exception\RestException;
13
use Psr\Http\Message\ResponseInterface;
14
use Symfony\Component\HttpFoundation\Request;
15
16
/**
17
 * Class RestClient
18
 *
19
 * @author Julien Deniau <[email protected]>
20
 */
21
class RestClient
22
{
23
    /**
24
     * @var ClientInterface
25
     */
26
    private $httpClient;
27
28
    /**
29
     * @var ?string
30
     */
31
    private $baseUrl;
32
33
    /**
34
     * @var bool
35
     */
36
    private $logHistory;
37
38
    /**
39
     * @var array
40
     */
41
    private $requestHistory;
42
43
    /**
44
     * @var ?Request
45
     */
46
    private $currentRequest;
47
48
    public function __construct(
49
        ClientInterface $httpClient,
50
        ?string $baseUrl = null
51
    ) {
52 1
        $this->httpClient = $httpClient;
53 1
        $this->baseUrl =
54 1
            null !== $baseUrl && '/' === mb_substr($baseUrl, -1)
55
                ? mb_substr($baseUrl, 0, -1)
56 1
                : $baseUrl;
57 1
        $this->logHistory = false;
58 1
        $this->requestHistory = [];
59 1
    }
60
61
    public function isHistoryLogged(): bool
62
    {
63 1
        return $this->logHistory;
64
    }
65
66
    public function setCurrentRequest(Request $currentRequest): self
67
    {
68
        $this->currentRequest = $currentRequest;
69
70
        return $this;
71
    }
72
73
    public function setLogHistory(bool $logHistory): self
74
    {
75 1
        $this->logHistory = $logHistory;
76
77 1
        return $this;
78
    }
79
80
    public function getRequestHistory(): array
81
    {
82 1
        return $this->requestHistory;
83
    }
84
85
    /**
86
     * get a path
87
     *
88
     * @return array|ResponseInterface|null
89
     *
90
     * @throws RestException
91
     */
92
    public function get(string $path, array $parameters = [])
93
    {
94 1
        $requestUrl = $this->baseUrl . $path;
95
        try {
96 1
            return $this->executeRequest('GET', $requestUrl, $parameters);
97 1
        } catch (ClientException $e) {
98 1
            $response = $e->getResponse();
99 1
            if (null !== $response && 404 === $response->getStatusCode()) {
100 1
                return null;
101
            }
102 1
            throw new RestClientException(
103 1
                'Error while getting resource',
104
                $path,
105 1
                [],
106 1
                7,
107
                $e
108
            );
109 1
        } catch (TransferException $e) {
110 1
            throw new RestException(
111 1
                'Error while getting resource',
112
                $path,
113 1
                [],
114 1
                1,
115
                $e
116
            );
117
        }
118
    }
119
120
    /**
121
     * @throws RestException
122
     */
123
    public function delete(string $path): void
124
    {
125
        try {
126 1
            $this->executeRequest('DELETE', $this->baseUrl . $path);
127 1
        } catch (ClientException $e) {
128 1
            return;
129 1
        } catch (TransferException $e) {
130 1
            throw new RestException(
131 1
                'Error while deleting resource',
132
                $path,
133 1
                [],
134 1
                2,
135
                $e
136
            );
137
        }
138 1
    }
139
140
    /**
141
     * @return array|ResponseInterface
142
     *
143
     * @throws RestClientException
144
     * @throws RestException
145
     */
146
    public function post(string $path, array $data, array $parameters = [])
147
    {
148 1
        $parameters['json'] = $data;
149
        try {
150 1
            return $this->executeRequest(
151 1
                'POST',
152 1
                $this->baseUrl . $path,
153
                $parameters
154
            );
155 1
        } catch (ClientException $e) {
156 1
            throw new RestClientException(
157 1
                'Cannot create resource',
158
                $path,
159 1
                [],
160 1
                3,
161
                $e
162
            );
163 1
        } catch (TransferException $e) {
164 1
            throw new RestException(
165 1
                'Error while posting resource',
166
                $path,
167 1
                [],
168 1
                4,
169
                $e
170
            );
171
        }
172
    }
173
174
    /**
175
     * @return array|ResponseInterface
176
     *
177
     * @throws RestClientException
178
     * @throws RestException
179
     */
180
    public function put(string $path, array $data, array $parameters = [])
181
    {
182 1
        $parameters['json'] = $data;
183
184
        try {
185 1
            return $this->executeRequest(
186 1
                'PUT',
187 1
                $this->baseUrl . $path,
188
                $parameters
189
            );
190 1
        } catch (ClientException $e) {
191 1
            throw new RestClientException(
192 1
                'Cannot update resource',
193
                $path,
194 1
                [],
195 1
                5,
196
                $e
197
            );
198 1
        } catch (TransferException $e) {
199 1
            throw new RestException(
200 1
                'Error while puting resource',
201
                $path,
202 1
                [],
203 1
                6,
204
                $e
205
            );
206
        }
207
    }
208
209
    /**
210
     * Merge default parameters.
211
     */
212
    protected function mergeDefaultParameters(array $parameters): array
213
    {
214 1
        $request = $this->getCurrentRequest();
215
216 1
        $defaultParameters = ['version' => '1.0'];
217 1
        if (null !== $request) {
218
            $defaultParameters['headers'] = ['Referer' => $request->getUri()];
219
        }
220
221 1
        $out = array_replace_recursive($defaultParameters, $parameters);
222
223 1
        if (null === $out) {
224
            throw new \RuntimeException(
225
                sprintf(
226
                    'Error while calling array_replace_recursive in %s. This should not happen.',
227
                    __METHOD__
228
                )
229
            );
230
        }
231
232 1
        return $out;
233
    }
234
235
    protected function getCurrentRequest(): ?Request
236
    {
237 1
        if ('cli' === \PHP_SAPI) {
238
            // we are in cli mode, do not bother to get request
239 1
            return null;
240
        }
241
242
        if (!$this->currentRequest) {
243
            $this->currentRequest = Request::createFromGlobals();
244
        }
245
246
        return $this->currentRequest;
247
    }
248
249
    /**
250
     * Executes request.
251
     *
252
     * @return ResponseInterface|array
253
     *
254
     * @throws TransferException
255
     */
256
    private function executeRequest(
257
        string $method,
258
        string $url,
259
        array $parameters = []
260
    ) {
261 1
        $parameters = $this->mergeDefaultParameters($parameters);
262
263 1
        $startTime = null;
264 1
        if ($this->isHistoryLogged()) {
265 1
            $startTime = microtime(true);
266
        }
267
268
        try {
269 1
            $response = $this->httpClient->request($method, $url, $parameters);
270 1
            $this->logRequest(
271 1
                $startTime,
272
                $method,
273
                $url,
274
                $parameters,
275
                $response
276
            );
277 1
        } catch (RequestException $e) {
278 1
            $this->logRequest(
279 1
                $startTime,
280
                $method,
281
                $url,
282
                $parameters,
283 1
                $e->getResponse()
284
            );
285 1
            throw $e;
286
        } catch (TransferException $e) {
287
            $this->logRequest($startTime, $method, $url, $parameters);
288
            throw $e;
289
        }
290
291 1
        $headers = $response->getHeaders();
292 1
        $jsonContentTypeList = ['application/ld+json', 'application/json'];
293
294 1
        $requestIsJson = false;
295
296 1
        if (isset($headers['Content-Type'])) {
297 1
            foreach ($jsonContentTypeList as $contentType) {
298
                if (
299
                    false !==
300 1
                    mb_stripos($headers['Content-Type'][0], $contentType)
301
                ) {
302 1
                    $requestIsJson = true;
303 1
                    break;
304
                }
305
            }
306
        }
307
308 1
        if ($requestIsJson) {
309 1
            return json_decode((string) $response->getBody(), true);
310
        } else {
311 1
            return $response;
312
        }
313
    }
314
315
    private function logRequest(
316
        ?float $startTime,
317
        string $method,
318
        string $url,
319
        array $parameters,
320
        ?ResponseInterface $response = null
321
    ): void {
322 1
        if ($this->isHistoryLogged()) {
323 1
            $queryTime = microtime(true) - $startTime;
324
325 1
            $this->requestHistory[] = [
326 1
                'method' => $method,
327 1
                'url' => $url,
328 1
                'parameters' => $parameters,
329 1
                'response' => $response,
330 1
                'responseBody' => $response
331 1
                    ? json_decode((string) $response->getBody(), true)
332
                    : null,
333 1
                'queryTime' => $queryTime,
334 1
                'backtrace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),
335
            ];
336
        }
337 1
    }
338
}
339