Completed
Pull Request — master (#31)
by
unknown
04:11
created

Http   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 340
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 26
c 2
b 0
f 0
lcom 1
cbo 9
dl 0
loc 340
ccs 104
cts 104
cp 1
rs 10

18 Methods

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