Completed
Push — master ( b27094...afbc6d )
by Julien
05:50 queued 01:38
created

RestClient::executeRequest()   C

Complexity

Conditions 7
Paths 20

Size

Total Lines 35
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 7

Importance

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