Completed
Push — master ( e8c731...726653 )
by Elf
01:39
created

HttpClient::getJson()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 4
cp 0.75
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
crap 2.0625
1
<?php
2
3
namespace ElfSundae;
4
5
use Exception;
6
use GuzzleHttp\Client;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Str;
9
use InvalidArgumentException;
10
use Psr\Http\Message\UriInterface;
11
12
class HttpClient
13
{
14
    /**
15
     * The default request options.
16
     *
17
     * @var array
18
     */
19
    protected static $defaultOptions = [
20
        'connect_timeout' => 5,
21
        'timeout' => 25,
22
    ];
23
24
    /**
25
     * The Guzzle client.
26
     *
27
     * @var \GuzzleHttp\Client
28
     */
29
    protected $client;
30
31
    /**
32
     * The Guzzle response.
33
     *
34
     * @var \GuzzleHttp\Psr7\Response
35
     */
36
    protected $response;
37
38
    /**
39
     * The request options.
40
     *
41
     * @var array
42
     */
43
    protected $options = [];
44
45
    /**
46
     * Indicate whether to catch Guzzle exceptions.
47
     *
48
     * @var bool
49
     */
50
    protected $catchExceptions = true;
51
52
    /**
53
     * Get the default request options.
54
     *
55
     * @return array
56
     */
57 24
    public static function defaultOptions()
58
    {
59 24
        return static::$defaultOptions;
60
    }
61
62
    /**
63
     * Set the default request options.
64
     *
65
     * @param  array  $options
66
     * @return void
67
     */
68 1
    public static function setDefaultOptions(array $options)
69
    {
70 1
        static::$defaultOptions = $options;
71 1
    }
72
73
    /**
74
     * Create a http client instance.
75
     *
76
     * @param  array|string|\Psr\Http\Message\UriInterface  $config  base URI or any request options
77
     */
78 23
    public function __construct($config = [])
79
    {
80 23
        if (is_string($config) || $config instanceof UriInterface) {
81 1
            $config = ['base_uri' => $config];
82 23
        } elseif (! is_array($config)) {
83
            throw new InvalidArgumentException('config must be a string, UriInterface, or an array');
84
        }
85
86 23
        $this->client = new Client(
87 23
            $this->options = $config + static::defaultOptions()
88 23
        );
89 23
    }
90
91
    /**
92
     * Get the Guzzle client instance.
93
     *
94
     * @return \GuzzleHttp\Client
95
     */
96 2
    public function getClient()
97
    {
98 2
        return $this->client;
99
    }
100
101
    /**
102
     * Get whether to catch Guzzle exceptions or not.
103
     *
104
     * @return bool
105
     */
106
    public function areExceptionsCaught()
107
    {
108
        return $this->catchExceptions;
109
    }
110
111
    /**
112
     * Set whether to catch Guzzle exceptions or not.
113
     *
114
     * @param  bool  $catch
115
     * @return $this
116
     */
117
    public function catchExceptions($catch)
118
    {
119
        $this->catchExceptions = (bool) $catch;
120
121
        return $this;
122
    }
123
124
    /**
125
     * Get the request options.
126
     *
127
     * @return array
128
     */
129 9
    public function getOptions()
130
    {
131 9
        return $this->options;
132
    }
133
134
    /**
135
     * Set the request options.
136
     *
137
     * @param  array  $options
138
     * @return $this
139
     */
140 2
    public function setOptions(array $options)
141
    {
142 2
        $this->options = $options;
143
144 2
        return $this;
145
    }
146
147
    /**
148
     * Merge the request options.
149
     *
150
     * @param  array  $options
151
     * @return $this
152
     */
153 2
    public function options(array $options)
154
    {
155 2
        return $this->setOptions($options + $this->options);
156
    }
157
158
    /**
159
     * Remove one or many options using "dot" notation.
160
     *
161
     * @param  string|array|null $key
162
     * @return $this
163
     */
164 16
    public function removeOptions($key = null)
165
    {
166 16
        if (is_null($key)) {
167 16
            $this->options = [];
168 16
        } else {
169 1
            Arr::forget($this->options, is_array($key) ? $key : func_get_args());
170
        }
171
172 16
        return $this;
173
    }
174
175
    /**
176
     * Set a request option using "dot" notation.
177
     *
178
     * @param  string|array  $key
179
     * @param  mixed  $value
180
     * @return $this
181
     */
182 8
    public function option($key, $value = null)
183
    {
184 8
        $keys = is_array($key) ? $key : [$key => $value];
185
186 8
        foreach ($keys as $key => $value) {
187 8
            Arr::set($this->options, $key, $value);
188 8
        }
189
190 8
        return $this;
191
    }
192
193
    /**
194
     * Get a request option using "dot" notation.
195
     *
196
     * @param  string $key
197
     * @return mixed
198
     */
199 3
    public function getOption($key)
200
    {
201 3
        return Arr::get($this->options, $key);
202
    }
203
204
    /**
205
     * Set the request header.
206
     *
207
     * @param  string  $name
208
     * @param  mixed  $value
209
     * @return $this
210
     */
211 4
    public function header($name, $value)
212
    {
213 4
        return $this->option('headers.'.$name, $value);
214
    }
215
216
    /**
217
     * Set the request content type.
218
     *
219
     * @param  string  $type
220
     * @return $this
221
     */
222 1
    public function contentType($type)
223
    {
224 1
        return $this->header('Content-Type', $type);
225
    }
226
227
    /**
228
     * Set the request accept type.
229
     *
230
     * @param  string  $type
231
     * @return $this
232
     */
233 2
    public function accept($type)
234
    {
235 2
        return $this->header('Accept', $type);
236
    }
237
238
    /**
239
     * Set the request accept type to JSON.
240
     *
241
     * @return $this
242
     */
243 1
    public function acceptJson()
244
    {
245 1
        return $this->accept('application/json');
246
    }
247
248
    /**
249
     * Specify where the body of a response will be saved.
250
     * Set the "sink" option.
251
     *
252
     * @param  mixed  $value
253
     * @return $this
254
     */
255 1
    public function saveTo($value)
256
    {
257 1
        return $this->option('sink', $value);
258
    }
259
260
    /**
261
     * Get the Guzzle response instance.
262
     *
263
     * @return \GuzzleHttp\Psr7\Response|null
264
     */
265 8
    public function getResponse()
266
    {
267 8
        return $this->response;
268
    }
269
270
    /**
271
     * Get the status code of response.
272
     *
273
     * @return int
274
     */
275
    public function getStatusCode()
276
    {
277
        if ($this->response) {
278
            return $this->response->getStatusCode();
279
        }
280
    }
281
282
    /**
283
     * Get the response header value.
284
     *
285
     * @param  string  $name
286
     * @return mixed
287
     */
288
    public function getHeader($name)
289
    {
290
        if ($this->response) {
291
            return $this->response->getHeaderLine($name);
292
        }
293
    }
294
295
    /**
296
     * Get all response headers values.
297
     *
298
     * @return array
299
     */
300
    public function getHeaders()
301
    {
302
        return $this->response ? $this->response->getHeaders() : [];
303
    }
304
305
    /**
306
     * Get response body.
307
     *
308
     * @return \GuzzleHttp\Psr7\Stream|null
309
     */
310 2
    public function getBody()
311
    {
312 2
        if ($this->response) {
313 2
            return $this->response->getBody();
314
        }
315
    }
316
317
    /**
318
     * Get response content.
319
     *
320
     * @return string|null
321
     */
322 2
    public function getContent()
323
    {
324 2
        if ($this->response) {
325 2
            return (string) $this->getBody();
326
        }
327
    }
328
329
    /**
330
     * Get JSON decoded response content.
331
     *
332
     * @param  bool  $assoc
333
     * @return mixed
334
     */
335 1
    public function getJson($assoc = true)
336
    {
337 1
        if ($this->response) {
338 1
            return json_decode($this->getContent(), $assoc);
339
        }
340
    }
341
342
    /**
343
     * Make request to a URI.
344
     *
345
     * @param  string  $uri
346
     * @param  string  $method
347
     * @param  array  $options
348
     * @return $this
349
     */
350 9
    public function request($uri, $method = 'GET', array $options = [])
351
    {
352
        try {
353 9
            $this->response = $this->client->request(
354 9
                $method, $uri, $options += $this->options
355 9
            );
356 9
        } catch (Exception $e) {
357 1
            if (! $this->catchExceptions) {
358
                throw $e;
359
            }
360
        }
361
362 9
        return $this;
363
    }
364
365
    /**
366
     * Make request to a URI, expecting JSON content.
367
     *
368
     * @param  string  $uri
369
     * @param  string  $method
370
     * @param  array  $options
371
     * @return $this
372
     */
373 3
    public function requestJson($uri, $method = 'GET', array $options = [])
374
    {
375 3
        Arr::set($options, 'headers.Accept', 'application/json');
376
377 3
        return $this->request($uri, $method, $options);
378
    }
379
380
    /**
381
     * Request the URI and return the response content.
382
     *
383
     * @param  string  $uri
384
     * @param  string  $method
385
     * @param  array  $options
386
     * @return string|null
387
     */
388 1
    public function fetchContent($uri, $method = 'GET', array $options = [])
389
    {
390 1
        return $this->request($uri, $method, $options)->getContent();
391
    }
392
393
    /**
394
     * Request the URI and return the JSON decoded response content.
395
     *
396
     * @param  string  $uri
397
     * @param  string  $method
398
     * @param  array  $options
399
     * @param  bool  $assoc
400
     * @return mixed
401
     */
402 1
    public function fetchJson($uri, $method = 'GET', array $options = [], $assoc = true)
403
    {
404 1
        return $this->requestJson($uri, $method, $options)->getJson($assoc);
405
    }
406
407
    /**
408
     * Dynamically methods to set request option, send request, or get
409
     * response properties.
410
     *
411
     * @param  string  $method
412
     * @param  array  $args
413
     * @return mixed
414
     */
415 4
    public function __call($method, $args)
416
    {
417
        // Handle magic request methods
418 4
        if (in_array($method, ['get', 'head', 'put', 'post', 'patch', 'delete'])) {
419 2
            if (count($args) < 1) {
420
                throw new InvalidArgumentException('Magic request methods require an URI and optional options array');
421
            }
422
423 2
            $url = $args[0];
424 2
            $options = isset($args[1]) ? $args[1] : [];
425
426 2
            return $this->request($url, $method, $options);
427
        }
428
429
        // Handle setting request options
430 2
        return $this->option(Str::snake($method), $args[0]);
431
    }
432
}
433