Completed
Push — master ( 882e60...d7ace2 )
by Elf
06:03
created

HttpClient::withExceptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
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
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
    public static function client()
56
    {
57
        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
    public function __construct($config = null)
78
    {
79
        if (is_string($config)) {
80
            $this->options(['base_uri' => $config]);
81
        } elseif (is_array($config)) {
82
            $this->options($config);
83
        }
84
85
        $this->client = new Client($this->options);
86
    }
87
88
    /**
89
     * Get the Guzzle client instance.
90
     *
91
     * @return \GuzzleHttp\Client
92
     */
93
    public function getClient()
94
    {
95
        return $this->client;
96
    }
97
98
    /**
99
     * Trun on/off Guzzle exceptions.
100
     *
101
     * @param  bool  $throws
102
     * @return $this
103
     */
104
    public function withExceptions($throws)
105
    {
106
        $this->withExceptions = (bool) $throws;
107
    }
108
109
    /**
110
     * Get the request options.
111
     *
112
     * @return array
113
     */
114
    public function getOptions()
115
    {
116
        return $this->options;
117
    }
118
119
    /**
120
     * Merge request options.
121
     *
122
     * @param  array  $options
123
     * @return $this
124
     */
125
    public function options(array ...$options)
126
    {
127
        $this->options = array_merge_recursive($this->options, ...$options);
128
129
        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
    public function removeOptions($key)
139
    {
140
        if (is_null($key)) {
141
            $this->options = [];
142
        }
143
144
        Arr::forget($this->options, ...$key);
0 ignored issues
show
Bug introduced by
It seems like $key defined by parameter $key on line 138 can also be of type null; however, Illuminate\Support\Arr::forget() does only seem to accept array|string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
145
146
        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
    public function option($key, $value)
157
    {
158
        if ($key) {
159
            Arr::set($this->options, $key, $value);
160
        }
161
162
        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
    public function getResponse()
227
    {
228
        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
    public function request($url, $method = 'GET', $options = [])
312
    {
313
        $options = array_merge_recursive($this->options, $options);
314
315
        try {
316
            $this->response = $this->client->request($method, $url, $options);
317
        } catch (Exception $e) {
318
            if ($this->withExceptions) {
319
                throw $e;
320
            }
321
        }
322
323
        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
    public function __call($name, $args)
376
    {
377
        return $this->option(Str::snake($name), $args[0]);
378
    }
379
}
380