Completed
Push — master ( 7c8cb2...ca5225 )
by Elf
02:41
created

HttpClient::request()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

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