Completed
Push — master ( f5b526...93ad25 )
by Elf
07:00 queued 01:44
created

HttpClient::setOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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