GuzzleManager::callCustomCreator()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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