Completed
Push — master ( 3c2ce9...625253 )
by Elf
03:05
created

HttpClient::mergeOptions()   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
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 0
cts 0
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace ElfSundae\Laravel\Helper;
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 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->mergeOptions(['base_uri' => $config]);
81
        } elseif (is_array($config)) {
82
            $this->mergeOptions($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 mergeOptions(array ...$options)
126
    {
127
        $this->options = array_merge_recursive($this->options, ...$options);
128
129
        return $this;
130
    }
131
132
    /**
133
     * Set a request option using "dot" notation.
134
     *
135
     * @param  string  $key
136
     * @param  mixed  $value
137
     * @return $this
138
     */
139
    public function option($key, $value)
140
    {
141
        if ($key) {
142
            Arr::set($this->options, $key, $value);
143
        }
144
145
        return $this;
146
    }
147
148
    /**
149
     * Set the request header.
150
     *
151
     * @param  string  $name
152
     * @param  mixed  $value
153
     * @return $this
154
     */
155
    public function header($name, $value)
156
    {
157
        return $this->option('headers.'.$name, $value);
158
    }
159
160
    /**
161
     * Set the request content type.
162
     *
163
     * @param  string  $type
164
     * @return $this
165
     */
166
    public function contentType($type)
167
    {
168
        return $this->header('Content-Type', $type);
169
    }
170
171
    /**
172
     * Set the request accept type.
173
     *
174
     * @param  string  $type
175
     * @return $this
176
     */
177
    public function accept($type)
178
    {
179
        return $this->header('Accept', $type);
180
    }
181
182
    /**
183
     * Set the request accept type to JSON.
184
     *
185
     * @return $this
186
     */
187
    public function acceptJson()
188
    {
189
        return $this->accept('application/json');
190
    }
191
192
    /**
193
     * Specify where the body of a response will be saved.
194
     * Set the "sink" option.
195
     *
196
     * @param  mixed  $value
197
     * @return $this
198
     */
199
    public function saveTo($value)
200
    {
201
        return $this->option('sink', $value);
202
    }
203
204
    /**
205
     * Get the Guzzle response instance.
206
     *
207
     * @return \GuzzleHttp\Psr7\Response|null
208
     */
209
    public function getResponse()
210
    {
211
        return $this->response;
212
    }
213
214
    /**
215
     * Get the status code of response.
216
     *
217
     * @return int
218
     */
219
    public function getStatusCode()
220
    {
221
        if ($this->response) {
222
            return $this->response->getStatusCode();
223
        }
224
    }
225
226
    /**
227
     * Get the response header value.
228
     *
229
     * @param  string  $name
230
     * @return mixed
231
     */
232
    public function getHeader($name)
233
    {
234
        if ($this->response) {
235
            return $this->response->getHeaderLine($name);
236
        }
237
    }
238
239
    /**
240
     * Get all response headers values.
241
     *
242
     * @return array
243
     */
244
    public function getHeaders()
245
    {
246
        return $this->response ? $this->response->getHeaders() : [];
247
    }
248
249
    /**
250
     * Get response body.
251
     *
252
     * @return \GuzzleHttp\Psr7\Stream|null
253
     */
254
    public function getBody()
255
    {
256
        if ($this->response) {
257
            return $this->response->getBody();
258
        }
259
    }
260
261
    /**
262
     * Get response content.
263
     *
264
     * @return string|null
265
     */
266
    public function getContent()
267
    {
268
        if ($body = $this->getBody()) {
269
            return (string) $body;
270
        }
271
    }
272
273
    /**
274
     * Get JSON decoded response content.
275
     *
276
     * @param  bool  $assoc
277
     * @return mixed
278
     */
279
    public function getJson($assoc = true)
280
    {
281
        if ($content = $this->getContent()) {
282
            return json_decode($content, $assoc);
283
        }
284
    }
285
286
    /**
287
     * Make request to an URL.
288
     *
289
     * @param  string  $url
290
     * @param  string  $method
291
     * @param  array  $options
292
     * @return $this
293
     */
294
    public function request($url, $method = 'GET', $options = [])
295
    {
296
        $options = array_merge_recursive($this->options, $options);
297
298
        try {
299
            $this->response = $this->client->request($method, $url, $options);
300
        } catch (Exception $e) {
301
            if ($this->withExceptions) {
302
                throw $e;
303
            }
304
        }
305
306
        return $this;
307
    }
308
309
    /**
310
     * Make request to an URL, expecting JSON content.
311
     *
312
     * @param  string  $url
313
     * @param  string  $method
314
     * @param  array  $options
315
     * @return $this
316
     */
317
    public function requestJson($url, $method = 'GET', $options = [])
318
    {
319
        Arr::set($options, 'headers.Accept', 'application/json');
320
321
        return $this->request($url, $method, $options);
322
    }
323
324
    /**
325
     * Request the URL and return the response content.
326
     *
327
     * @param  string  $url
328
     * @param  string  $method
329
     * @param  array  $options
330
     * @return string|null
331
     */
332
    public function fetchContent($url, $method = 'GET', $options = [])
333
    {
334
        return $this->request($url, $method, $options)->getContent();
335
    }
336
337
    /**
338
     * Request the URL and return the JSON decoded response content.
339
     *
340
     * @param  string  $url
341
     * @param  string  $method
342
     * @param  array  $options
343
     * @param  bool  $assoc
344
     * @return mixed
345
     */
346
    public function fetchJson($url, $method = 'GET', $options = [], $assoc = true)
347
    {
348
        return $this->requestJson($url, $method, $options)->getJson($assoc);
349
    }
350
351
    /**
352
     * Any unhandled methods will be sent to $this->option() to set request option.
353
     *
354
     * @param  string  $name
355
     * @param  array  $args
356
     * @return $this
357
     */
358
    public function __call($name, $args)
359
    {
360
        return $this->option(Str::snake($name), $args[0]);
361
    }
362
}
363