Passed
Push — master ( d09937...a89747 )
by du
06:01
created

IpClient   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 417
Duplicated Lines 0 %

Test Coverage

Coverage 97.94%

Importance

Changes 0
Metric Value
wmc 39
eloc 85
dl 0
loc 417
ccs 95
cts 97
cp 0.9794
rs 9.28
c 0
b 0
f 0

26 Methods

Rating   Name   Duplication   Size   Complexity  
A checkIp() 0 6 2
A setProviderConfig() 0 5 1
A setRequestHandler() 0 5 1
A getIp() 0 7 2
A setDataMapper() 0 5 1
A getOriginalInfo() 0 10 2
A setCacheStore() 0 5 1
A getDataMapper() 0 15 3
A getInstanceByName() 0 3 2
A bound() 0 5 1
A use() 0 3 1
A getProviders() 0 11 3
A resolveProviders() 0 13 3
A getRequestHandler() 0 7 2
A getProviderConfig() 0 7 2
A getCacheStore() 0 3 1
A try() 0 5 1
A useProvider() 0 6 1
A createProvider() 0 13 2
A clearUse() 0 5 1
A getDefaultProviders() 0 7 1
A responseWithError() 0 5 1
A getErrors() 0 3 1
A __get() 0 3 1
A setIp() 0 7 1
A __call() 0 3 1
1
<?php
2
3
namespace DucCnzj\Ip;
4
5
use DucCnzj\Ip\Imp\IpImp;
6
use DucCnzj\Ip\Imp\DataMapImp;
7
use DucCnzj\Ip\Imp\CacheStoreImp;
8
use DucCnzj\Ip\Imp\RequestHandlerImp;
9
use DucCnzj\Ip\Exceptions\InvalidIpAddress;
10
use DucCnzj\Ip\Exceptions\ServerErrorException;
11
use DucCnzj\Ip\Exceptions\IpProviderClassNotExistException;
12
13
/**
14
 * @method string getCity()
15
 * @method string getCountry()
16
 * @method string getAddress()
17
 * @method string getRegion()
18
 *
19
 * Class IpClient
20
 *
21
 * @package DucCnzj\Ip
22
 */
23
class IpClient
24
{
25
    /**
26
     * @var string
27
     */
28
    protected $ip;
29
30
    /**
31
     * @var array
32
     */
33
    protected $providerConfig = [];
34
35
    /**
36
     * @var array|null ['baidu', 'taobao']
37
     */
38
    protected $providers = [];
39
40
    /**
41
     * @var array
42
     */
43
    protected $instances = [];
44
45
    /**
46
     * @var DataMapImp
47
     */
48
    protected $dataMapper;
49
50
    /**
51
     * @var RequestHandlerImp|null
52
     */
53
    protected $requestHandler;
54
55
    /**
56
     * @param int $times
57
     *
58
     * @return $this
59
     *
60
     * @author duc <[email protected]>
61
     */
62 5
    public function try(int $times)
63
    {
64 5
        $this->requestHandler = $this->getRequestHandler()->setTryTimes($times);
65
66 5
        return $this;
67
    }
68
69
    /**
70
     * @param string $ip
71
     *
72
     * @throws InvalidIpAddress
73
     *
74
     * @author duc <[email protected]>
75
     */
76 15
    public function checkIp(string $ip)
77
    {
78 15
        $b = preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip);
79
80 15
        if (! $b) {
81 1
            throw new InvalidIpAddress;
82
        }
83 14
    }
84
85
    /**
86
     * @return array
87
     *
88
     * @author duc <[email protected]>
89
     */
90 12
    public function resolveProviders()
91
    {
92 12
        $providerInstance = [];
93
94 12
        foreach ($this->getProviders() as $provider) {
95 12
            if (! isset($this->instances[$provider])) {
96 5
                $this->instances[$provider] = $this->createProvider($provider);
97
            }
98
99 11
            $providerInstance[$provider] = $this->instances[$provider];
100
        }
101
102 11
        return $providerInstance;
103
    }
104
105
    /**
106
     * @param string $provider
107
     *
108
     * @return IpImp
109
     * @throws IpProviderClassNotExistException
110
     *
111
     * @author duc <[email protected]>
112
     */
113 5
    public function createProvider(string $provider)
114
    {
115 5
        $config = $this->getProviderConfig($provider);
116
117 5
        $shortName = ucfirst(strtolower($provider)) . 'Ip';
118
119 5
        $class = __NAMESPACE__ . "\Strategies\\{$shortName}";
120
121 5
        if (! class_exists($class)) {
122 1
            throw new IpProviderClassNotExistException("{$class} 不存在");
123
        }
124
125 4
        return new $class($config);
126
    }
127
128
    /**
129
     * @param string $msg
130
     *
131
     * @return array
132
     *
133
     * @author duc <[email protected]>
134
     */
135 5
    public function responseWithError(string $msg)
136
    {
137
        return [
138 5
            'success' => 0,
139 5
            'message' => $msg,
140
        ];
141
    }
142
143
    /**
144
     * @return DataMapper|DataMapImp|NullDataMapper
145
     *
146
     * @author duc <[email protected]>
147
     */
148 7
    public function getDataMapper()
149
    {
150 7
        $response = $this->getOriginalInfo();
151
152 7
        if (! $response['success']) {
153 4
            return (new NullDataMapper())->setInfo(['ip' => $this->getIp()]);
154
        }
155
156 3
        if (! $this->dataMapper) {
157 3
            $this->dataMapper = new DataMapper();
158
159 3
            return $this->dataMapper->setInfo($response);
160
        }
161
162 1
        return $this->dataMapper->setInfo($response);
163
    }
164
165
    /**
166
     * @return RequestHandlerImp|RequestHandler|null
167
     *
168
     * @author duc <[email protected]>
169
     */
170 11
    public function getRequestHandler()
171
    {
172 11
        if (! $this->requestHandler) {
173 8
            return $this->requestHandler = new RequestHandler();
174
        }
175
176 7
        return $this->requestHandler;
177
    }
178
179
    /**
180
     * @return array|mixed
181
     *
182
     * @author duc <[email protected]>
183
     */
184 9
    public function getOriginalInfo()
185
    {
186
        try {
187 9
            $result = $this->getRequestHandler()
188 9
                ->send($this->resolveProviders(), $this->getIp());
189 5
        } catch (ServerErrorException $e) {
190 5
            return $this->responseWithError($e->getMessage());
191
        }
192
193 5
        return $result;
194
    }
195
196
    /**
197
     * @return array
198
     *
199
     * @author duc <[email protected]>
200
     */
201 3
    public function getErrors(): array
202
    {
203 3
        return $this->getRequestHandler()->getErrors();
204
    }
205
206
    /**
207
     * @return array
208
     *
209
     * @author duc <[email protected]>
210
     */
211 15
    public function getProviders()
212
    {
213 15
        if (is_null($this->providers)) {
214 1
            return [];
215
        }
216
217 15
        if (count($this->providers) === 0) {
218 5
            return $this->providers = $this->getDefaultProviders();
219
        }
220
221 11
        return $this->providers;
222
    }
223
224
    /**
225
     * @return string
226
     * @throws \Exception
227
     *
228
     * @author duc <[email protected]>
229
     */
230 15
    public function getIp()
231
    {
232 15
        if (! $this->ip) {
233 1
            throw new \Exception('请先设置 ip');
234
        }
235
236 14
        return $this->ip;
237
    }
238
239
    /**
240
     * @return array
241
     *
242
     * @author duc <[email protected]>
243
     */
244 5
    public function getDefaultProviders()
245
    {
246
        return [
247 5
            'baidu',
248
            'ali',
249
            'tencent',
250
            'taobao',
251
        ];
252
    }
253
254
    /**
255
     * @param string $provider
256
     *
257
     * @return array|string
258
     */
259 6
    public function getProviderConfig(string $provider)
260
    {
261 6
        if (! isset($this->providerConfig[$provider])) {
262 6
            return [];
263
        }
264
265 1
        return $this->providerConfig[$provider];
266
    }
267
268
    /**
269
     * @return CacheStore|CacheStoreImp
270
     *
271
     * @author duc <[email protected]>
272
     */
273 8
    public function getCacheStore()
274
    {
275 8
        return $this->getRequestHandler()->getCacheStore();
276
    }
277
278
    /**
279
     * @param string $ip
280
     *
281
     * @return $this
282
     *
283
     * @author duc <[email protected]>
284
     */
285 14
    public function setIp(string $ip)
286
    {
287 14
        $this->checkIp($ip);
288
289 14
        $this->ip = $ip;
290
291 14
        return $this;
292
    }
293
294
    /**
295
     * @param string[] ...$provider
296
     *
297
     * @return $this
298
     *
299
     * @author duc <[email protected]>
300
     */
301 11
    public function useProvider(string ...$provider)
302
    {
303 11
        $providers = array_merge($this->providers ?? [], array_filter($provider));
304 11
        $this->providers = array_unique($providers);
305
306 11
        return $this;
307
    }
308
309
    /**
310
     * @param string $provider
311
     * @param array|string $config
312
     *
313
     * @return $this
314
     *
315
     * @author duc <[email protected]>
316
     */
317 2
    public function setProviderConfig(string $provider, $config)
318
    {
319 2
        $this->providerConfig[$provider] = $config;
320
321 2
        return $this;
322
    }
323
324
    /**
325
     * @param DataMapImp $dataMapper
326
     *
327
     * @return $this
328
     *
329
     * @author duc <[email protected]>
330
     */
331 1
    public function setDataMapper(DataMapImp $dataMapper)
332
    {
333 1
        $this->dataMapper = $dataMapper;
334
335 1
        return $this;
336
    }
337
338
    /**
339
     * @param RequestHandlerImp $requestHandler
340
     *
341
     * @return $this
342
     *
343
     * @author duc <[email protected]>
344
     */
345 3
    public function setRequestHandler(RequestHandlerImp $requestHandler)
346
    {
347 3
        $this->requestHandler = $requestHandler;
348
349 3
        return $this;
350
    }
351
352
    /**
353
     * @param CacheStoreImp $cacheStore
354
     *
355
     * @return $this
356
     *
357
     * @author duc <[email protected]>
358
     */
359 2
    public function setCacheStore(CacheStoreImp $cacheStore)
360
    {
361 2
        $this->requestHandler = $this->getRequestHandler()->setCacheStore($cacheStore);
362
363 2
        return $this;
364
    }
365
366
    /**
367
     * @param string $provider
368
     * @param IpImp  $instance
369
     *
370
     * @return $this
371
     *
372
     * @author duc <[email protected]>
373
     */
374 9
    public function bound(string $provider, IpImp $instance)
375
    {
376 9
        $this->instances[$provider] = $instance;
377
378 9
        return $this;
379
    }
380
381
    /**
382
     * @param string[] ...$provider
383
     *
384
     * @return IpClient
385
     *
386
     * @author duc <[email protected]>
387
     */
388 5
    public function use(string ...$provider)
389
    {
390 5
        return $this->useProvider(...$provider);
391
    }
392
393
    /**
394
     * @return $this
395
     *
396
     * @author duc <[email protected]>
397
     */
398 2
    public function clearUse()
399
    {
400 2
        $this->providers = null;
401
402 2
        return $this;
403
    }
404
405
    /**
406
     * @param string $name
407
     *
408
     * @return mixed|null
409
     *
410
     * @author duc <[email protected]>
411
     */
412 1
    public function getInstanceByName(string $name)
413
    {
414 1
        return isset($this->instances[$name]) ? $this->instances[$name] : null;
415
    }
416
417
    /**
418
     * @param string $name
419
     * @param $arguments
420
     *
421
     * @return array
422
     *
423
     * @author duc <[email protected]>
424
     */
425 1
    public function __call(string $name, $arguments)
426
    {
427 1
        return $this->getDataMapper()->{$name}(...$arguments);
428
    }
429
430
    /**
431
     * @param string $name
432
     *
433
     * @return mixed|string
434
     *
435
     * @author duc <[email protected]>
436
     */
437
    public function __get(string $name)
438
    {
439
        return $this->getDataMapper()->{$name};
440
    }
441
}
442