Passed
Push — master ( c93f04...a214e6 )
by du
02:10
created

IpClient::clearUse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 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\NetworkErrorException;
0 ignored issues
show
Bug introduced by
The type DucCnzj\Ip\Exceptions\NetworkErrorException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

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