Completed
Push — master ( becdd8...efb850 )
by Lynh
15:18
created

GuzzleManager::createJsonDriver()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Jenky\Hermes;
4
5
use Closure;
6
use GuzzleHttp\Client;
7
use Illuminate\Contracts\Foundation\Application;
8
use InvalidArgumentException;
9
use Jenky\Hermes\Contracts\Hermes;
10
11
class GuzzleManager implements Hermes
12
{
13
    use Concerns\InteractsWithConfiguration;
14
15
    /**
16
     * The application instance.
17
     *
18
     * @var \Illuminate\Contracts\Foundation\Application
19
     */
20
    protected $app;
21
22
    /**
23
     * The array of resolved channels.
24
     *
25
     * @var array
26
     */
27
    protected $channels = [];
28
29
    /**
30
     * The registered custom driver creators.
31
     *
32
     * @var array
33
     */
34
    protected $customCreators = [];
35
36
    /**
37
     * Create a new Guzzle manager instance.
38
     *
39
     * @param  \Illuminate\Contracts\Foundation\Application  $app
40
     * @return void
41
     */
42
    public function __construct(Application $app)
43
    {
44
        $this->app = $app;
45
    }
46
47
    /**
48
     * Get all the channels.
49
     *
50
     * @return array
51
     */
52
    public function getChannels()
53
    {
54
        return $this->channels;
55
    }
56
57
    /**
58
     * Get a client instance.
59
     *
60
     * @param  string  $channel
61
     * @param  array $options
62
     * @throws \InvalidArgumentException
63
     * @return \GuzzleHttp\Client
64
     */
65
    public function channel($channel = null, array $options = [])
66
    {
67
        return $this->client(
68
            $channel ?: $this->getDefaultChannel(), $options
69
        );
70
    }
71
72
    /**
73
     * Attempt to get the client from the local cache.
74
     *
75
     * @param  string  $name
76
     * @param  array $options
77
     * @return \GuzzleHttp\Client
78
     */
79
    protected function client($name, array $options = [])
80
    {
81
        return $this->channels[$name] ?? with($this->resolve($name, $options), function ($client) use ($name) {
82
            return $this->channels[$name] = $client;
83
        });
84
    }
85
86
    /**
87
     * Get the client configuration.
88
     *
89
     * @param  string  $name
90
     * @return array
91
     */
92
    protected function configurationFor($name)
93
    {
94
        return $this->app['config']["hermes.channels.{$name}"] ?? [];
95
    }
96
97
    /**
98
     * Resolve the given log instance by name.
99
     *
100
     * @param  string  $name
101
     * @param  array $options
102
     * @throws \InvalidArgumentException
103
     * @return \GuzzleHttp\Client
104
     */
105
    protected function resolve($name, array $options = [])
106
    {
107
        $config = array_merge(
108
            $this->configurationFor($name), $options
109
        );
110
111
        if (empty($config)) {
112
            throw new InvalidArgumentException("Guzzle channel [{$name}] is not defined.");
113
        }
114
115
        if (empty($config['driver'])) {
116
            throw new InvalidArgumentException('Guzzle driver is not defined.');
117
        }
118
119
        if (isset($this->customCreators[$config['driver']])) {
120
            return $this->callCustomCreator($config);
121
        }
122
123
        $driverMethod = 'create'.ucfirst($config['driver']).'Driver';
124
125
        if (method_exists($this, $driverMethod)) {
126
            return $this->{$driverMethod}($config);
127
        }
128
129
        throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
130
    }
131
132
    /**
133
     * Register a custom driver creator Closure.
134
     *
135
     * @param  string    $driver
136
     * @param  \Closure  $callback
137
     * @return $this
138
     */
139
    public function extend($driver, Closure $callback)
140
    {
141
        $this->customCreators[$driver] = $callback->bindTo($this, $this);
142
143
        return $this;
144
    }
145
146
    /**
147
     * Call a custom driver creator.
148
     *
149
     * @param  array  $config
150
     * @return mixed
151
     */
152
    protected function callCustomCreator(array $config)
153
    {
154
        return $this->customCreators[$config['driver']]($this->app, $config);
155
    }
156
157
    /**
158
     * Create a custom Guzzle driver instance.
159
     *
160
     * @param  array  $config
161
     * @return \GuzzleHttp\Client
162
     */
163
    protected function createCustomDriver(array $config)
164
    {
165
        $factory = is_callable($via = $config['via']) ? $via : $this->app->make($via);
166
167
        return $factory($config);
168
    }
169
170
    /**
171
     * Create a default Guzzle driver instance.
172
     *
173
     * @param  array  $config
174
     * @throws \InvalidArgumentException
175
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
176
     * @return \GuzzleHttp\Client
177
     */
178
    protected function createGuzzleDriver(array $config)
179
    {
180
        return new Client($this->makeClientOptions($config));
181
    }
182
183
    /**
184
     * Create a JSON Guzzle driver instance.
185
     *
186
     * @param  array  $config
187
     * @throws \InvalidArgumentException
188
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
189
     * @return \GuzzleHttp\Client
190
     */
191
    protected function createJsonDriver(array $config)
192
    {
193
        return new Client($this->makeClientOptions(
194
            array_merge_recursive($config, [
195
                'options' => [
196
                    'response_handler' => JsonResponse::class,
197
                ],
198
                'interceptors' => [
199
                    Interceptors\ResponseHandler::class,
200
                    Interceptors\RequestEvent::class,
201
                ],
202
            ])
203
        ));
204
    }
205
206
    /**
207
     * Get the default client name.
208
     *
209
     * @return string
210
     */
211
    public function getDefaultChannel()
212
    {
213
        return $this->app['config']['hermes.default'];
214
    }
215
216
    /**
217
     * Set the default guzzle client name.
218
     *
219
     * @param  string  $name
220
     * @return void
221
     */
222
    public function setDefaultChannel($name)
223
    {
224
        $this->app['config']['hermes.default'] = $name;
225
    }
226
227
    /**
228
     * Dynamically call the default driver instance.
229
     *
230
     * @param  string  $method
231
     * @param  array   $parameters
232
     * @return mixed
233
     */
234
    public function __call($method, $parameters)
235
    {
236
        return $this->channel()->{$method}(...$parameters);
237
    }
238
}
239