Http   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 322
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 78
dl 0
loc 322
ccs 100
cts 100
cp 1
rs 10
c 6
b 0
f 0
wmc 26

17 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 5 1
A createRequest() 0 19 2
A delete() 0 5 1
A putAsBody() 0 7 1
A authenticateRequest() 0 11 1
A getRequest() 0 9 2
A getHeaders() 0 3 1
A put() 0 5 1
A setClient() 0 5 1
A getRequestExceptionParts() 0 9 4
A __construct() 0 3 1
A getUrlFromPath() 0 3 1
A queueResourceAs() 0 5 1
A sendRequest() 0 13 2
A post() 0 5 1
A getRequestOptions() 0 11 2
A throwRequestException() 0 20 3
1
<?php
2
3
namespace Stevenmaguire\Services\Trello;
4
5
use GuzzleHttp\Client as HttpClient;
6
use GuzzleHttp\ClientInterface as HttpClientInterface;
7
use GuzzleHttp\Exception\RequestException;
8
use GuzzleHttp\Psr7;
9
use GuzzleHttp\Psr7\Request;
10
use Psr\Http\Message\RequestInterface;
11
use Psr\Http\Message\StreamInterface;
12
13
class Http
14
{
15
    public const HTTP_DELETE = 'DELETE';
16
    public const HTTP_GET = 'GET';
17
    public const HTTP_POST = 'POST';
18
    public const HTTP_PUT = 'PUT';
19
20
    /**
21
     * Multipart resources to include in next request.
22
     *
23
     * @var array
24
     */
25
    protected $multipartResources = [];
26
27
    /**
28
     * Http client
29
     *
30
     * @var HttpClientInterface
31
     */
32
    protected $httpClient;
33
34 702
    /**
35
     * Creates a new http broker.
36 702
     */
37 702
    public function __construct()
38
    {
39
        $this->httpClient = new HttpClient();
40
    }
41
42
    /**
43
     * Adds authentication credentials to given request.
44
     *
45
     * @param  RequestInterface  $request
46 682
     *
47
     * @return RequestInterface
48 682
     */
49 682
    protected function authenticateRequest(RequestInterface $request)
50
    {
51 682
        $uri = $request->getUri();
52 682
        parse_str($uri->getQuery(), $query);
53
54 682
        $query['key'] = Configuration::get('key');
55
        $query['token'] = Configuration::get('token');
56 682
57
        $uri = $uri->withQuery(http_build_query($query));
58
59
        return $request->withUri($uri);
60
    }
61
62
    /**
63
     * Creates a request.
64
     *
65
     * @param  string $verb
66
     * @param  string $path
67
     * @param  array  $parameters
68 684
     *
69
     * @return Request
70 684
     */
71 2
    protected function createRequest($verb, $path, $parameters = [])
72 2
    {
73 2
        if (isset($parameters['file'])) {
74 1
            $this->queueResourceAs(
75 2
                'file',
76 1
                Psr7\Utils::streamFor($parameters['file'])
77
            );
78 684
            unset($parameters['file']);
79 684
        }
80 684
81 684
        $request = new Request(
82 342
            $verb,
83
            $this->getUrlFromPath($path),
84 684
            $this->getHeaders()
85 684
        );
86 684
87 342
        return $request->withUri(
88 342
            $request->getUri()->withQuery(
89
                http_build_query($parameters)
90
            )
91
        );
92
    }
93
94
    /**
95
     * Retrieves http response for a request with the delete method.
96
     *
97
     * @param  string $path
98
     * @param  array  $parameters
99 62
     *
100
     * @return object
101 62
     */
102
    public function delete($path, $parameters = [])
103 62
    {
104
        $request = $this->getRequest(static::HTTP_DELETE, $path, $parameters);
105
106
        return $this->sendRequest($request);
107
    }
108
109
    /**
110
     * Retrieves http response for a request with the get method.
111
     *
112
     * @param  string $path
113
     * @param  array  $parameters
114 312
     *
115
     * @return object
116 312
     */
117
    public function get($path, $parameters = [])
118 312
    {
119
        $request = $this->getRequest(static::HTTP_GET, $path, $parameters);
120
121
        return $this->sendRequest($request);
122
    }
123
124
    /**
125
     * Creates and returns a request.
126
     *
127
     * @param  string $method
128
     * @param  string $path
129
     * @param  array  $parameters
130 684
     *
131
     * @return RequestInterface
132 684
     */
133
    public function getRequest($method, $path, $parameters = [], $authenticated = true)
134 684
    {
135 682
        $request = $this->createRequest($method, $path, $parameters);
136 341
137
        if ($authenticated) {
138 684
            $request = $this->authenticateRequest($request);
139
        }
140
141
        return $request;
142
    }
143
144
    /**
145
     * Retrieves default headers.
146 684
     *
147
     * @return array
148 684
     */
149
    protected function getHeaders()
150
    {
151
        return [];
152
    }
153
154
    /**
155
     * Prepares an array of important exception parts based on composition of a
156
     * given exception.
157
     *
158
     * @param  RequestException  $requestException
159 8
     *
160
     * @return array
161 8
     */
162 8
    private function getRequestExceptionParts(RequestException $requestException)
163 8
    {
164 8
        $response = $requestException->getResponse();
165 8
        $parts = [];
166
        $parts['reason'] = $response ? $response->getReasonPhrase() : $requestException->getMessage();
167 8
        $parts['code'] = $response ? $response->getStatusCode() : $requestException->getCode();
168
        $parts['body'] = $response ? $response->getBody() : null;
169
170
        return $parts;
171
    }
172
173
    /**
174
     * Creates an array of request options based on the current status of the
175
     * http client.
176 680
     *
177
     * @return array
178
     */
179 680
    protected function getRequestOptions()
180 340
    {
181
        $options = [
182 680
            'proxy' => Configuration::get('proxy'),
183 2
        ];
184 1
185
        if (! empty(array_filter($this->multipartResources))) {
186 680
            $options['multipart'] = $this->multipartResources;
187
        }
188
189
        return $options;
190
    }
191
192
    /**
193
     * Creates fully qualified domain from given path.
194
     *
195
     * @param  string  $path
196 684
     *
197
     * @return string
198 684
     */
199
    protected function getUrlFromPath($path = '/')
200
    {
201
        return Configuration::get('domain').'/'.Configuration::get('version').'/'.ltrim($path, '/');
202
    }
203
204
    /**
205
     * Retrieves http response for a request with the post method.
206
     *
207
     * @param  string $path
208
     * @param  array  $parameters
209 86
     *
210
     * @return object
211 86
     */
212
    public function post($path, $parameters)
213 86
    {
214
        $request = $this->getRequest(static::HTTP_POST, $path, $parameters);
215
216
        return $this->sendRequest($request);
217
    }
218
219
    /**
220
     * Retrieves http response for a request with the put method.
221
     *
222
     * @param  string $path
223
     * @param  array  $parameters
224 218
     *
225
     * @return object
226 218
     */
227
    public function put($path, $parameters)
228 218
    {
229
        $request = $this->getRequest(static::HTTP_PUT, $path, $parameters);
230
231
        return $this->sendRequest($request);
232
    }
233
234
    /**
235
     * Retrieves http response for a request with the put method,
236
     * ensuring parameters are passed as body.
237
     *
238
     * @param  string $path
239
     * @param  array  $parameters
240 2
     *
241
     * @return object
242 2
     */
243 2
    public function putAsBody($path, $parameters)
244 2
    {
245
        $request = $this->getRequest(static::HTTP_PUT, $path)
246 2
            ->withBody(Psr7\Utils::streamFor(json_encode($parameters)))
247
            ->withHeader('content-type', 'application/json');
248
249
        return $this->sendRequest($request);
250
    }
251
252
    /**
253
     * Adds a given resource to multipart stream collection, to be processed by next request.
254
     *
255
     * @param  string                                           $name
256
     * @param  resource|string|StreamInterface $resource
257 2
     *
258
     * @return void
259 2
     */
260 2
    protected function queueResourceAs($name, $resource)
261 2
    {
262 1
        array_push($this->multipartResources, [
263 2
            'name' => $name,
264
            'contents' => $resource,
265
        ]);
266
    }
267
268
    /**
269
     * Retrieves http response for a given request.
270
     *
271
     * @param  RequestInterface $request
272
     *
273 680
     * @return object
274
     * @throws Exceptions\Exception
275
     */
276 680
    protected function sendRequest(RequestInterface $request)
277 680
    {
278 680
        try {
279 340
            $response = $this->httpClient->send(
280
                $request,
281 672
                $this->getRequestOptions()
282
            );
283 672
284 8
            $this->multipartResources = [];
285 8
286
            return json_decode((string) $response->getBody());
287
        } catch (RequestException $e) {
288
            $this->throwRequestException($e);
289
        }
290
    } // @codeCoverageIgnore
291
292
    /**
293
     * Updates the http client.
294
     *
295
     * @param HttpClientInterface  $httpClient
296 680
     *
297
     * @return Http
298 680
     */
299
    public function setClient(HttpClientInterface $httpClient)
300 680
    {
301
        $this->httpClient = $httpClient;
302
303
        return $this;
304
    }
305
306
    /**
307
     * Creates local exception from guzzle request exception, which includes
308
     * response body.
309
     *
310
     * @param  RequestException  $requestException
311
     *
312 8
     * @return void
313
     * @throws Exceptions\Exception
314 8
     */
315
    protected function throwRequestException(RequestException $requestException)
316 8
    {
317 8
        $exceptionParts = $this->getRequestExceptionParts($requestException);
318 8
319 4
        $exception = new Exceptions\Exception(
320 4
            $exceptionParts['reason'],
321
            $exceptionParts['code'],
322 8
            $requestException
323 8
        );
324
325 8
326 5
        if ($body = $exceptionParts['body']) {
327
            $json = json_decode($body);
328
329 3
            if (json_last_error() == JSON_ERROR_NONE) {
330
                throw $exception->setResponseBody($json);
331
            }
332 2
        }
333
334
        throw $exception->setResponseBody($body);
335
    }
336
}
337