Passed
Push — master ( 971cb9...ca1cf6 )
by du
01:55
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\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 7
    public function getProviderConfig(string $provider)
260
    {
261 7
        if (! isset($this->providerConfig[$provider])) {
262 7
            return [];
263
        }
264
265 2
        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[] ...$names
280
     *
281
     * @return array
282
     *
283
     * @author duc <[email protected]>
284
     */
285 1
    public function getConfigs(string ...$names)
286
    {
287 1
        $result = [];
288 1
        foreach ($names as $provider) {
289 1
            $result[$provider] = $this->getProviderConfig($provider);
290
        }
291
292 1
        return $result;
293
    }
294
295
    /**
296
     * @param string $ip
297
     *
298
     * @return $this
299
     *
300
     * @author duc <[email protected]>
301
     */
302 14
    public function setIp(string $ip)
303
    {
304 14
        $this->checkIp($ip);
305
306 14
        $this->ip = $ip;
307
308 14
        return $this;
309
    }
310
311
    /**
312
     * @param string[] ...$provider
313
     *
314
     * @return $this
315
     *
316
     * @author duc <[email protected]>
317
     */
318 11
    public function useProvider(string ...$provider)
319
    {
320 11
        $providers = array_merge($this->providers ?? [], array_filter($provider));
321 11
        $this->providers = array_unique($providers);
322
323 11
        return $this;
324
    }
325
326
    /**
327
     * @param string $provider
328
     * @param array|string $config
329
     *
330
     * @return $this
331
     *
332
     * @author duc <[email protected]>
333
     */
334 3
    public function setProviderConfig(string $provider, $config)
335
    {
336 3
        $this->providerConfig[$provider] = $config;
337
338 3
        return $this;
339
    }
340
341
    /**
342
     * @param array $configs
343
     *
344
     * @return $this
345
     *
346
     * @author duc <[email protected]>
347
     */
348 1
    public function setConfigs(array $configs)
349
    {
350 1
        foreach ($configs as $provider => $config) {
351 1
            $this->setProviderConfig($provider, $config);
352
        }
353
354 1
        return $this;
355
    }
356
357
    /**
358
     * @param DataMapImp $dataMapper
359
     *
360
     * @return $this
361
     *
362
     * @author duc <[email protected]>
363
     */
364 1
    public function setDataMapper(DataMapImp $dataMapper)
365
    {
366 1
        $this->dataMapper = $dataMapper;
367
368 1
        return $this;
369
    }
370
371
    /**
372
     * @param RequestHandlerImp $requestHandler
373
     *
374
     * @return $this
375
     *
376
     * @author duc <[email protected]>
377
     */
378 3
    public function setRequestHandler(RequestHandlerImp $requestHandler)
379
    {
380 3
        $this->requestHandler = $requestHandler;
381
382 3
        return $this;
383
    }
384
385
    /**
386
     * @param CacheStoreImp $cacheStore
387
     *
388
     * @return $this
389
     *
390
     * @author duc <[email protected]>
391
     */
392 2
    public function setCacheStore(CacheStoreImp $cacheStore)
393
    {
394 2
        $this->requestHandler = $this->getRequestHandler()->setCacheStore($cacheStore);
395
396 2
        return $this;
397
    }
398
399
    /**
400
     * @param string $provider
401
     * @param IpImp  $instance
402
     *
403
     * @return $this
404
     *
405
     * @author duc <[email protected]>
406
     */
407 9
    public function bound(string $provider, IpImp $instance)
408
    {
409 9
        $this->instances[$provider] = $instance;
410
411 9
        return $this;
412
    }
413
414
    /**
415
     * @param string[] ...$provider
416
     *
417
     * @return IpClient
418
     *
419
     * @author duc <[email protected]>
420
     */
421 5
    public function use(string ...$provider)
422
    {
423 5
        return $this->useProvider(...$provider);
424
    }
425
426
    /**
427
     * @return $this
428
     *
429
     * @author duc <[email protected]>
430
     */
431 2
    public function clearUse()
432
    {
433 2
        $this->providers = null;
434
435 2
        return $this;
436
    }
437
438
    /**
439
     * @param string $name
440
     *
441
     * @return mixed|null
442
     *
443
     * @author duc <[email protected]>
444
     */
445 1
    public function getInstanceByName(string $name)
446
    {
447 1
        return isset($this->instances[$name]) ? $this->instances[$name] : null;
448
    }
449
450
    /**
451
     * @param string $name
452
     * @param $arguments
453
     *
454
     * @return array
455
     *
456
     * @author duc <[email protected]>
457
     */
458 1
    public function __call(string $name, $arguments)
459
    {
460 1
        return $this->getDataMapper()->{$name}(...$arguments);
461
    }
462
463
    /**
464
     * @param string $name
465
     *
466
     * @return mixed|string
467
     *
468
     * @author duc <[email protected]>
469
     */
470
    public function __get(string $name)
471
    {
472
        return $this->getDataMapper()->{$name};
473
    }
474
}
475