Completed
Push — master ( 070015...50a9e6 )
by Steven
02:17
created

Http::getRequestOptions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

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