Passed
Push — master ( c6c34e...4dd018 )
by du
01:58
created

IpClient::use()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
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;
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 2
    public function try(int $times)
69
    {
70 2
        $this->requestHandler = $this->getRequestHandler()->setTryTimes($times);
71
72 2
        return $this;
73
    }
74
75
    /**
76
     * @param string $ip
77
     *
78
     * @throws InvalidIpAddress
79
     *
80
     * @author duc <[email protected]>
81
     */
82 10
    public function checkIp(string $ip)
83
    {
84 10
        $b = preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip);
85
86 10
        if (! $b) {
87 1
            throw new InvalidIpAddress;
88
        }
89 9
    }
90
91
    /**
92
     * @return array
93
     *
94
     * @author duc <[email protected]>
95
     */
96 8
    public function resolveProviders()
97
    {
98 8
        foreach ($this->getProviders() as $provider) {
99 8
            if (! isset($this->instances[$provider])) {
100 8
                $this->instances[$provider] = $this->createProvider($provider);
101
            }
102
        }
103
104 7
        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 5
    public function createProvider($provider)
117
    {
118 5
        $config = $this->getProviderConfig($provider);
119
120 5
        $shortName = ucfirst(strtolower($provider)) . 'Ip';
121
122 5
        $class = __NAMESPACE__ . "\Strategies\\{$shortName}";
123
124 5
        if (! class_exists($class)) {
125 1
            throw new IpProviderClassNotExistException("{$class} 不存在");
126
        }
127
128 4
        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 5
    public function getDataMapper()
152
    {
153 5
        $response = $this->getOriginalInfo();
154
155 5
        if (! $response['success']) {
156 3
            return new NullDataMapper(['ip' => $this->getIp()]);
157
        }
158
159 2
        if (! $this->dataMapper) {
160 2
            return $this->dataMapper = new DataMapper($response);
161
        }
162
163 1
        return $this->dataMapper;
164
    }
165
166
    /**
167
     * @return RequestHandlerImp|RequestHandler|null
168
     *
169
     * @author duc <[email protected]>
170
     */
171 1
    public function getRequestHandler()
172
    {
173 1
        if (! $this->requestHandler) {
174 1
            return $this->requestHandler = new RequestHandler();
175
        }
176
177 1
        return $this->requestHandler;
178
    }
179
180
    /**
181
     * @return array
182
     *
183
     * @author duc <[email protected]>
184
     */
185 5
    public function getOriginalInfo()
186
    {
187 5
        if ($info = $this->getCacheStore()->get($this->getIp())) {
188
            return $info;
189
        }
190
191
        try {
192 5
            $result = $this->getRequestHandler()
193 5
                ->send($this->resolveProviders(), $this->getIp());
194 5
        } catch (ServerErrorException $e) {
195 5
            return $this->responseWithError($e->getMessage());
196
        } catch (NetworkErrorException $e) {
197
            return $this->responseWithError($e->getMessage());
198
        }
199
200 1
        $this->cacheStore->put($this->getIp(), $result);
201
202 1
        return $result;
203
    }
204
205
    /**
206
     * @return array
207
     *
208
     * @author duc <[email protected]>
209
     */
210 1
    public function getErrors(): array
211
    {
212 1
        return $this->getRequestHandler()->getErrors();
213
    }
214
215
    /**
216
     * @return array
217
     *
218
     * @author duc <[email protected]>
219
     */
220 10
    public function getProviders()
221
    {
222 10
        if (count($this->providers) === 0) {
223 5
            return $this->providers = $this->getDefaultProviders();
224
        }
225
226 5
        return $this->providers;
227
    }
228
229
    /**
230
     * @return CacheStore
231
     *
232
     * @author duc <[email protected]>
233
     */
234 10
    public function getDefaultCacheDriver()
235
    {
236 10
        return new CacheStore();
237
    }
238
239
    /**
240
     * @return string
241
     * @throws \Exception
242
     *
243
     * @author duc <[email protected]>
244
     */
245 9
    public function getIp()
246
    {
247 9
        if (is_null($this->ip)) {
0 ignored issues
show
introduced by
The condition is_null($this->ip) is always false.
Loading history...
248
            throw new \Exception('请先设置 ip');
249
        }
250
251 9
        return $this->ip;
252
    }
253
254
    /**
255
     * @return array
256
     *
257
     * @author duc <[email protected]>
258
     */
259 5
    public function getDefaultProviders()
260
    {
261
        return [
262 5
            'baidu',
263
            'taobao',
264
        ];
265
    }
266
267
    /**
268
     * @param string $provider
269
     *
270
     * @return array
271
     */
272 5
    public function getProviderConfig(string $provider): array
273
    {
274 5
        if (! isset($this->providerConfig[$provider])) {
275 5
            return [];
276
        }
277
278
        return $this->providerConfig[$provider];
279
    }
280
281
    /**
282
     * @return CacheStore|CacheStoreImp
283
     *
284
     * @author duc <[email protected]>
285
     */
286 10
    public function getCacheStore()
287
    {
288 10
        if ($this->cacheStore instanceof CacheStoreImp) {
289 2
            return $this->cacheStore;
290
        }
291
292 10
        return $this->cacheStore = $this->getDefaultCacheDriver();
293
    }
294
295
    /**
296
     * @param string $ip
297
     *
298
     * @return $this
299
     *
300
     * @author duc <[email protected]>
301
     */
302 9
    public function setIp(string $ip)
303
    {
304 9
        $this->checkIp($ip);
305
306 9
        $this->ip = $ip;
307
308 9
        return $this;
309
    }
310
311
    /**
312
     * @param string $provider
313
     *
314
     * @return $this
315
     *
316
     * @author duc <[email protected]>
317
     */
318 5
    public function useProvider(string $provider)
319
    {
320 5
        $this->providers[] = $provider;
321
322 5
        $this->providers = array_unique($this->providers);
323
324 5
        return $this;
325
    }
326
327
    /**
328
     * @param       $provider
329
     * @param array $config
330
     *
331
     * @return $this
332
     *
333
     * @author duc <[email protected]>
334
     */
335
    public function setProviderConfig($provider, array $config)
336
    {
337
        $this->providerConfig[$provider] = $config;
338
339
        return $this;
340
    }
341
342
    /**
343
     * @param DataMapImp $dataMapper
344
     *
345
     * @return $this
346
     *
347
     * @author duc <[email protected]>
348
     */
349
    public function setDataMapper(DataMapImp $dataMapper)
350
    {
351
        $this->dataMapper = $dataMapper;
352
353
        return $this;
354
    }
355
356
    /**
357
     * @param RequestHandlerImp $requestHandler
358
     *
359
     * @return $this
360
     *
361
     * @author duc <[email protected]>
362
     */
363
    public function setRequestHandler(RequestHandlerImp $requestHandler)
364
    {
365
        $this->requestHandler = $requestHandler;
366
367
        return $this;
368
    }
369
370
    /**
371
     * @param CacheStoreImp $cacheStore
372
     *
373
     * @return $this
374
     *
375
     * @author duc <[email protected]>
376
     */
377
    public function setCacheStore(CacheStoreImp $cacheStore)
378
    {
379
        $this->cacheStore = $cacheStore;
380
381
        return $this;
382
    }
383
384
    /**
385
     * @param string $provider
386
     * @param IpImp  $instance
387
     *
388
     * @return $this
389
     *
390
     * @author duc <[email protected]>
391
     */
392 5
    public function bound(string $provider, IpImp $instance)
393
    {
394 5
        $this->instances[$provider] = $instance;
395
396 5
        return $this;
397
    }
398
399
    /**
400
     * @param string $provider
401
     *
402
     * @return IpClient
403
     *
404
     * @author duc <[email protected]>
405
     */
406
    public function use(string $provider)
407
    {
408
        return $this->useProvider($provider);
409
    }
410
411
    /**
412
     * @param string $name
413
     *
414
     * @return mixed|null
415
     *
416
     * @author duc <[email protected]>
417
     */
418 1
    public function getInstanceByName(string $name)
419
    {
420 1
        return isset($this->instances[$name]) ? $this->instances[$name] : null;
421
    }
422
423
    /**
424
     * @param string $name
425
     * @param $arguments
426
     *
427
     * @return array
428
     *
429
     * @author duc <[email protected]>
430
     */
431
    public function __call(string $name, $arguments)
432
    {
433
        return $this->getDataMapper()->{$name}(...$arguments);
434
    }
435
436
    /**
437
     * @param string $name
438
     *
439
     * @return mixed|string
440
     *
441
     * @author duc <[email protected]>
442
     */
443
    public function __get(string $name)
444
    {
445
        return $this->getDataMapper()->{$name};
446
    }
447
}
448