Passed
Push — master ( 10b845...c93f04 )
by du
01:52
created

IpClient::getDataMapper()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 15
ccs 8
cts 8
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 0
crap 3
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 ['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 4
    public function responseWithError($msg)
139
    {
140
        return [
141 4
            'success' => 0,
142 4
            '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 3
            return (new NullDataMapper())->setInfo(['ip' => $this->getIp()]);
157
        }
158
159 3
        if (! $this->dataMapper) {
160 2
            $this->dataMapper = new DataMapper();
161
162 2
            return $this->dataMapper->setInfo($response);
163
        }
164
165 2
        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 4
        } catch (ServerErrorException $e) {
197 4
            return $this->responseWithError($e->getMessage());
198
        } catch (\Exception $e) {
199
            return $this->responseWithError($e->getMessage());
200
        }
201
202 4
        $this->getCacheStore()->put($this->getIp(), $result);
203
204 4
        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 (count($this->providers) === 0) {
225 6
            return $this->providers = $this->getDefaultProviders();
226
        }
227
228 7
        return $this->providers;
229
    }
230
231
    /**
232
     * @return CacheStore
233
     *
234
     * @author duc <[email protected]>
235
     */
236 11
    public function getDefaultCacheDriver()
237
    {
238 11
        return new CacheStore();
239
    }
240
241
    /**
242
     * @return string
243
     * @throws \Exception
244
     *
245
     * @author duc <[email protected]>
246
     */
247 12
    public function getIp()
248
    {
249 12
        if (is_null($this->ip)) {
0 ignored issues
show
introduced by
The condition is_null($this->ip) is always false.
Loading history...
250 1
            throw new \Exception('请先设置 ip');
251
        }
252
253 11
        return $this->ip;
254
    }
255
256
    /**
257
     * @return array
258
     *
259
     * @author duc <[email protected]>
260
     */
261 6
    public function getDefaultProviders()
262
    {
263
        return [
264 6
            'baidu',
265
            'taobao',
266
        ];
267
    }
268
269
    /**
270
     * @param string $provider
271
     *
272
     * @return array
273
     */
274 7
    public function getProviderConfig(string $provider): array
275
    {
276 7
        if (! isset($this->providerConfig[$provider])) {
277 7
            return [];
278
        }
279
280 1
        return $this->providerConfig[$provider];
281
    }
282
283
    /**
284
     * @return CacheStore|CacheStoreImp
285
     *
286
     * @author duc <[email protected]>
287
     */
288 12
    public function getCacheStore()
289
    {
290 12
        if ($this->cacheStore instanceof CacheStoreImp) {
291 5
            return $this->cacheStore;
292
        }
293
294 11
        return $this->cacheStore = $this->getDefaultCacheDriver();
295
    }
296
297
    /**
298
     * @param string $ip
299
     *
300
     * @return $this
301
     *
302
     * @author duc <[email protected]>
303
     */
304 11
    public function setIp(string $ip)
305
    {
306 11
        $this->checkIp($ip);
307
308 11
        $this->ip = $ip;
309
310 11
        return $this;
311
    }
312
313
    /**
314
     * @param string $provider
315
     *
316
     * @return $this
317
     *
318
     * @author duc <[email protected]>
319
     */
320 7
    public function useProvider(string $provider)
321
    {
322 7
        $this->providers[] = $provider;
323
324 7
        $this->providers = array_unique($this->providers);
325
326 7
        return $this;
327
    }
328
329
    /**
330
     * @param       $provider
331
     * @param array $config
332
     *
333
     * @return $this
334
     *
335
     * @author duc <[email protected]>
336
     */
337 1
    public function setProviderConfig($provider, array $config)
338
    {
339 1
        $this->providerConfig[$provider] = $config;
340
341 1
        return $this;
342
    }
343
344
    /**
345
     * @param DataMapImp $dataMapper
346
     *
347
     * @return $this
348
     *
349
     * @author duc <[email protected]>
350
     */
351 1
    public function setDataMapper(DataMapImp $dataMapper)
352
    {
353 1
        $this->dataMapper = $dataMapper;
354
355 1
        return $this;
356
    }
357
358
    /**
359
     * @param RequestHandlerImp $requestHandler
360
     *
361
     * @return $this
362
     *
363
     * @author duc <[email protected]>
364
     */
365 1
    public function setRequestHandler(RequestHandlerImp $requestHandler)
366
    {
367 1
        $this->requestHandler = $requestHandler;
368
369 1
        return $this;
370
    }
371
372
    /**
373
     * @param CacheStoreImp $cacheStore
374
     *
375
     * @return $this
376
     *
377
     * @author duc <[email protected]>
378
     */
379 1
    public function setCacheStore(CacheStoreImp $cacheStore)
380
    {
381 1
        $this->cacheStore = $cacheStore;
382
383 1
        return $this;
384
    }
385
386
    /**
387
     * @param string $provider
388
     * @param IpImp  $instance
389
     *
390
     * @return $this
391
     *
392
     * @author duc <[email protected]>
393
     */
394 6
    public function bound(string $provider, IpImp $instance)
395
    {
396 6
        $this->instances[$provider] = $instance;
397
398 6
        return $this;
399
    }
400
401
    /**
402
     * @param string $provider
403
     *
404
     * @return IpClient
405
     *
406
     * @author duc <[email protected]>
407
     */
408 1
    public function use(string $provider)
409
    {
410 1
        return $this->useProvider($provider);
411
    }
412
413
    /**
414
     * @param string $name
415
     *
416
     * @return mixed|null
417
     *
418
     * @author duc <[email protected]>
419
     */
420 1
    public function getInstanceByName(string $name)
421
    {
422 1
        return isset($this->instances[$name]) ? $this->instances[$name] : null;
423
    }
424
425
    /**
426
     * @param string $name
427
     * @param $arguments
428
     *
429
     * @return array
430
     *
431
     * @author duc <[email protected]>
432
     */
433
    public function __call(string $name, $arguments)
434
    {
435
        return $this->getDataMapper()->{$name}(...$arguments);
436
    }
437
438
    /**
439
     * @param string $name
440
     *
441
     * @return mixed|string
442
     *
443
     * @author duc <[email protected]>
444
     */
445
    public function __get(string $name)
446
    {
447
        return $this->getDataMapper()->{$name};
448
    }
449
}
450