Completed
Push — master ( d88ab8...687bbf )
by Elf
02:32
created

HttpClient::withExceptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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