Completed
Pull Request — master (#93)
by Julien
05:06 queued 02:16
created

RestClient::executeRequest()   B

Complexity

Conditions 8
Paths 24

Size

Total Lines 56
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 8.0983

Importance

Changes 8
Bugs 0 Features 2
Metric Value
cc 8
eloc 37
c 8
b 0
f 2
nc 24
nop 3
dl 0
loc 56
ccs 23
cts 26
cp 0.8846
crap 8.0983
rs 8.0835

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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