HandleProvider::useProvider()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace DucCnzj\Ip\Traits;
4
5
use DucCnzj\Ip\Imp\IpImp;
6
use DucCnzj\Ip\Exceptions\IncorrectInstanceException;
7
use DucCnzj\Ip\Exceptions\IpProviderClassNotExistException;
8
9
trait HandleProvider
10
{
11
    /**
12
     * @var \Closure[]
13
     */
14
    protected $bindings = [];
15
16
    /**
17
     * @var array
18
     */
19
    protected $withConfigurations = ['taobao' => false];
20
21
    /**
22
     * @var array
23
     */
24
    protected $providerConfig = [];
25
26
    /**
27
     * @var array|null ['baidu', 'taobao']
28
     */
29
    protected $providers = [];
30
31
    /**
32
     * @param string $provider
33
     * @param string $concrete
34
     * @param bool $hasConfig
35
     *
36
     * @return HandleProvider
37
     *
38
     * @author duc <[email protected]>
39
     */
40 13
    public function bind(string $provider, $concrete, $hasConfig = true)
41
    {
42 13
        $this->bindings[$provider] = $this->getClosure($provider, $concrete);
43 13
        $this->withConfigurations = $this->withConfigurations + [$provider => $hasConfig];
44
45 13
        return $this;
46
    }
47
48
    /**
49
     * @param string $provider
50
     * @param string $concrete
51
     * @return \Closure
52
     *
53
     * @author duc <[email protected]>
54
     */
55
    protected function getClosure(string $provider, $concrete = null)
56
    {
57 15
        return function () use ($provider, $concrete) {
58 14
            return $this->createProvider($provider, $concrete);
59 15
        };
60
    }
61
62
    /**
63
     * @param string $provider
64
     *
65
     * @param string $concrete
66
     * @return IpImp
67
     * @throws IpProviderClassNotExistException
68
     * @throws \ReflectionException
69
     * @author duc <[email protected]>
70
     */
71 14
    protected function createProvider(string $provider, $concrete)
72
    {
73 14
        if (is_object($concrete)) {
0 ignored issues
show
introduced by
The condition is_object($concrete) is always false.
Loading history...
74 10
            if (! $concrete instanceof IpImp) {
75 1
                $class = get_class($concrete);
76 1
                throw new IncorrectInstanceException("{$class} is not instanceof " . IpImp::class);
77
            }
78
79 9
            return $concrete;
80
        }
81
82 4
        $shortName = ucfirst(strtolower($provider)) . 'Ip';
83
84 4
        $class = $concrete ?: "\DucCnzj\Ip\Strategies\\{$shortName}";
85
86 4
        if (! class_exists($class)) {
87 1
            throw new IpProviderClassNotExistException("{$class} 不存在");
88
        }
89
90 3
        if (! (new \ReflectionClass($class))->implementsInterface(IpImp::class)) {
91 1
            throw new IncorrectInstanceException("{$class} is not instanceof " . IpImp::class);
92
        }
93
94 2
        $config = $this->getProviderConfig($provider);
95
96 2
        return new $class($config);
97
    }
98
99
    /**
100
     * @return array
101
     *
102
     * @throws IpProviderClassNotExistException
103
     * @author duc <[email protected]>
104
     */
105 16
    public function resolveProviders()
106
    {
107 16
        $providerClosures = [];
108
109 16
        foreach ($this->getProviders() as $provider) {
110 16
            if (! $this->shouldNotSkip($provider)) {
111 7
                continue;
112
            }
113
114 15
            if (! isset($this->bindings[$provider])) {
115 3
                $this->bindings[$provider] = $this->getClosure($provider);
116
            }
117
118 15
            $providerClosures[$provider] = $this->bindings[$provider];
119
        }
120
121 16
        return $providerClosures;
122
    }
123
124
    /**
125
     * @param string ...$provider
126
     *
127
     * @return HandleProvider
128
     *
129
     * @author duc <[email protected]>
130
     */
131 16
    public function useProvider(string ...$provider)
132
    {
133 16
        $providers = array_merge($this->providers ?? [], array_filter($provider));
134 16
        $this->providers = array_unique($providers);
135
136 16
        return $this;
137
    }
138
139
    /**
140
     * @param string ...$provider
141
     *
142
     * @return HandleProvider
143
     *
144
     * @author duc <[email protected]>
145
     */
146 10
    public function use(string ...$provider)
147
    {
148 10
        return $this->useProvider(...$provider);
149
    }
150
151
    /**
152
     * @return HandleProvider
153
     *
154
     * @author duc <[email protected]>
155
     */
156 2
    public function clearUse()
157
    {
158 2
        $this->providers = null;
159
160 2
        return $this;
161
    }
162
163
    /**
164
     * @param $provider
165
     * @return bool
166
     *
167
     * @author duc <[email protected]>
168
     */
169 17
    public function shouldNotSkip($provider): bool
170
    {
171 17
        if (isset($this->withConfigurations[$provider])) {
172 16
            if (! $this->withConfigurations[$provider] || ! ! $this->getProviderConfig($provider)) {
173 16
                return true;
174
            }
175
        }
176
177 8
        return ! ! $this->getProviderConfig($provider);
178
    }
179
180
    /**
181
     * @return array
182
     *
183
     * @author duc <[email protected]>
184
     */
185 19
    public function getProviders(): array
186
    {
187 19
        if (is_null($this->providers)) {
188 1
            return [];
189
        }
190
191 19
        if (count($this->providers) === 0) {
192 5
            return $this->providers = $this->getDefaultProviders();
193
        }
194
195 15
        return $this->providers;
196
    }
197
198
    /**
199
     * @param string $name
200
     *
201
     * @return mixed|null
202
     *
203
     * @author duc <[email protected]>
204
     */
205 1
    public function getInstanceByName(string $name)
206
    {
207 1
        return isset($this->bindings[$name]) ? $this->bindings[$name] : null;
208
    }
209
210
    /**
211
     * @param string $provider
212
     *
213
     * @return array|string
214
     */
215 10
    public function getProviderConfig(string $provider)
216
    {
217 10
        if (! isset($this->providerConfig[$provider])) {
218 10
            return [];
219
        }
220
221 3
        return $this->providerConfig[$provider];
222
    }
223
224
    /**
225
     * @return array
226
     *
227
     * @author duc <[email protected]>
228
     */
229 5
    protected function getDefaultProviders()
230
    {
231
        return [
232 5
            'baidu',
233
            'ali',
234
            'tencent',
235
            'taobao',
236
        ];
237
    }
238
239
    /**
240
     * @param string ...$names
241
     *
242
     * @return array
243
     *
244
     * @author duc <[email protected]>
245
     */
246 1
    public function getConfigs(string ...$names): array
247
    {
248 1
        if (empty($names)) {
249 1
            return $this->providerConfig;
250
        }
251
252 1
        $result = [];
253 1
        foreach ($names as $provider) {
254 1
            $result[$provider] = $this->getProviderConfig($provider);
255
        }
256
257 1
        return $result;
258
    }
259
260
    /**
261
     * @param array $configs
262
     *
263
     * @return HandleProvider
264
     *
265
     * @author duc <[email protected]>
266
     */
267 1
    public function setConfigs(array $configs)
268
    {
269 1
        foreach ($configs as $provider => $config) {
270 1
            $this->setProviderConfig($provider, $config);
271
        }
272
273 1
        return $this;
274
    }
275
276
    /**
277
     * @param string $provider
278
     * @param array|string $config
279
     *
280
     * @return HandleProvider
281
     *
282
     * @author duc <[email protected]>
283
     */
284 3
    public function setProviderConfig(string $provider, $config)
285
    {
286 3
        $this->providerConfig[$provider] = $config;
287
288 3
        return $this;
289
    }
290
}
291