RestClient::delete()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 2
b 0
f 0
nc 3
nop 1
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 3
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('Error while getting resource', $path, [], 7, $e);
103 1
        } catch (TransferException $e) {
104 1
            throw new RestException('Error while getting resource', $path, [], 1, $e);
105
        }
106
    }
107
108
    /**
109
     * @throws RestException
110
     */
111
    public function delete(string $path): void
112
    {
113
        try {
114 1
            $this->executeRequest('DELETE', $this->baseUrl . $path);
115 1
        } catch (ClientException $e) {
116 1
            return;
117 1
        } catch (TransferException $e) {
118 1
            throw new RestException('Error while deleting resource', $path, [], 2, $e);
119
        }
120 1
    }
121
122
    /**
123
     * @return array|ResponseInterface
124
     *
125
     * @throws RestClientException
126
     * @throws RestException
127
     */
128
    public function post(string $path, array $data, array $parameters = [])
129
    {
130 1
        $parameters['json'] = $data;
131
        try {
132 1
            return $this->executeRequest(
133 1
                'POST',
134 1
                $this->baseUrl . $path,
135
                $parameters
136
            );
137 1
        } catch (ClientException $e) {
138 1
            throw new RestClientException('Cannot create resource', $path, [], 3, $e);
139 1
        } catch (TransferException $e) {
140 1
            throw new RestException('Error while posting resource', $path, [], 4, $e);
141
        }
142
    }
143
144
    /**
145
     * @return array|ResponseInterface
146
     *
147
     * @throws RestClientException
148
     * @throws RestException
149
     */
150
    public function put(string $path, array $data, array $parameters = [])
151
    {
152 1
        $parameters['json'] = $data;
153
154
        try {
155 1
            return $this->executeRequest(
156 1
                'PUT',
157 1
                $this->baseUrl . $path,
158
                $parameters
159
            );
160 1
        } catch (ClientException $e) {
161 1
            throw new RestClientException('Cannot update resource', $path, [], 5, $e);
162 1
        } catch (TransferException $e) {
163 1
            throw new RestException('Error while puting resource', $path, [], 6, $e);
164
        }
165
    }
166
167
    /**
168
     * Merge default parameters.
169
     */
170
    protected function mergeDefaultParameters(array $parameters): array
171
    {
172 1
        $request = $this->getCurrentRequest();
173
174 1
        $defaultParameters = ['version' => '1.0'];
175 1
        if (null !== $request) {
176
            $defaultParameters['headers'] = ['Referer' => $request->getUri()];
177
        }
178
179
        /** @var array|null $out */
180 1
        $out = array_replace_recursive($defaultParameters, $parameters);
181
182 1
        if (null === $out) {
183
            throw new \RuntimeException(sprintf('Error while calling array_replace_recursive in %s. This should not happen.', __METHOD__));
184
        }
185
186 1
        return $out;
187
    }
188
189
    protected function getCurrentRequest(): ?Request
190
    {
191 1
        if ('cli' === \PHP_SAPI) {
192
            // we are in cli mode, do not bother to get request
193 1
            return null;
194
        }
195
196
        if (!$this->currentRequest) {
197
            $this->currentRequest = Request::createFromGlobals();
198
        }
199
200
        return $this->currentRequest;
201
    }
202
203
    /**
204
     * Executes request.
205
     *
206
     * @return ResponseInterface|array
207
     *
208
     * @throws TransferException
209
     */
210
    private function executeRequest(
211
        string $method,
212
        string $url,
213
        array $parameters = []
214
    ) {
215 1
        $parameters = $this->mergeDefaultParameters($parameters);
216
217 1
        $startTime = null;
218 1
        if ($this->isHistoryLogged()) {
219 1
            $startTime = microtime(true);
220
        }
221
222
        try {
223 1
            $response = $this->httpClient->request($method, $url, $parameters);
224 1
            $this->logRequest(
225 1
                $startTime,
0 ignored issues
show
Bug introduced by
It seems like $startTime can also be of type string; however, parameter $startTime of Mapado\RestClientSdk\RestClient::logRequest() does only seem to accept double|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

225
                /** @scrutinizer ignore-type */ $startTime,
Loading history...
226
                $method,
227
                $url,
228
                $parameters,
229
                $response
230
            );
231 1
        } catch (RequestException $e) {
232 1
            $this->logRequest(
233 1
                $startTime,
234
                $method,
235
                $url,
236
                $parameters,
237 1
                $e->getResponse()
238
            );
239 1
            throw $e;
240
        } catch (TransferException $e) {
241
            $this->logRequest($startTime, $method, $url, $parameters);
242
            throw $e;
243
        }
244
245 1
        $headers = $response->getHeaders();
246 1
        $jsonContentTypeList = ['application/ld+json', 'application/json'];
247
248 1
        $requestIsJson = false;
249
250
        $responseContentType =
251 1
            $headers['Content-Type'] ?? $headers['content-type'] ?? null;
252 1
        if ($responseContentType) {
253 1
            foreach ($jsonContentTypeList as $contentType) {
254
                if (
255 1
                    false !== mb_stripos($responseContentType[0], $contentType)
256
                ) {
257 1
                    $requestIsJson = true;
258 1
                    break;
259
                }
260
            }
261
        }
262
263 1
        if ($requestIsJson) {
264 1
            return json_decode((string) $response->getBody(), true);
265
        } else {
266 1
            return $response;
267
        }
268
    }
269
270
    private function logRequest(
271
        ?float $startTime,
272
        string $method,
273
        string $url,
274
        array $parameters,
275
        ?ResponseInterface $response = null
276
    ): void {
277 1
        if ($this->isHistoryLogged()) {
278 1
            $queryTime = microtime(true) - $startTime;
279
280 1
            $this->requestHistory[] = [
281 1
                'method' => $method,
282 1
                'url' => $url,
283 1
                'parameters' => $parameters,
284 1
                'response' => $response,
285 1
                'responseBody' => $response
286 1
                    ? json_decode((string) $response->getBody(), true)
287
                    : null,
288 1
                'queryTime' => $queryTime,
289 1
                'backtrace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),
290
            ];
291
        }
292 1
    }
293
}
294