GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 17da4d...ef06e4 )
by
unknown
03:02
created

ApiClient::request()   B

Complexity

Conditions 9
Paths 16

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 13.0498

Importance

Changes 0
Metric Value
dl 0
loc 52
ccs 24
cts 38
cp 0.6316
rs 7.4917
c 0
b 0
f 0
cc 9
nc 16
nop 3
crap 13.0498

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Lingxi\ApiClient;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Middleware;
7
use GuzzleHttp\HandlerStack;
8
use Psr\Log\LoggerInterface;
9
use GuzzleHttp\TransferStats;
10
use GuzzleHttp\RequestOptions;
11
use GuzzleHttp\ClientInterface;
12
use GuzzleHttp\MessageFormatter;
13
use Lingxi\Signature\Authenticator;
14
use Psr\Http\Message\ResponseInterface;
15
use GuzzleHttp\Exception\RequestException;
16
use GuzzleHttp\Exception\BadResponseException;
17
use Lingxi\ApiClient\Exceptions\ApiClientInitException;
18
use Lingxi\ApiClient\Exceptions\ResponseDataParseException;
19
20
/**
21
 * Class ApiClient
22
 * @package Lingxi\Packages\ApiClient
23
 */
24
class ApiClient
25
{
26
    /**
27
     * @var
28
     */
29
    protected $httpClient;
30
    /**
31
     * @var mixed|string
32
     */
33
    protected $baseUri;
34
    /**
35
     * @var float|mixed
36
     */
37
    protected $outTime;
38
    /**
39
     * @var mixed|string
40
     */
41
    protected $apiKey;
42
43
    /**
44
     * @var mixed|string
45
     */
46
    protected $apiSecret;
47
48
    /**
49
     * @var mixed|string
50
     */
51
    protected $apiVersion;
52
    /**
53
     * @var \Psr\Http\Message\RequestInterface
54
     */
55
    protected $request;
56
    /**
57
     * @var \Psr\Http\Message\ResponseInterface
58
     */
59
    protected $response;
60
    /**
61
     * @var array
62
     */
63
    protected $requestData;
64
    /**
65
     * @var int
66
     */
67
    protected $responseCode;
68
    /**
69
     * @var array
70
     */
71
    protected $responseBody;
72
    /**
73
     * @var
74
     */
75
    protected $authenticator;
76
    /**
77
     * @var string
78
     */
79
    protected $lastUrl = '';
80
    /**
81
     * @var double
82
     */
83
    protected $transferTime = 0;
84
    /**
85
     * @var callable
86
     */
87
    protected $completeCallBack;
88
    /**
89
     * @var bool
90
     */
91
    protected $log = false;
92
    /**
93
     * @var $handlerStack
94
     */
95
    protected $handlerStack;
96
97
    /**
98
     * ApiClient constructor.
99
     *
100
     * @param array $options
101
     */
102 18
    public function __construct(array $options = [])
103
    {
104 18
        $this->baseUri = key_exists('base_uri', $options) ? $options['base_uri'] : '';
105 18
        $this->outTime = key_exists('time_out', $options) ? $options['time_out'] : 5.0;
106 18
        $this->apiKey = key_exists('api_key', $options) ? $options['api_key'] : '';
107 18
        $this->apiSecret = key_exists('api_secret', $options) ? $options['api_secret'] : '';
108 18
        $this->apiVersion = key_exists('api_version', $options) ? $options['api_version'] : 'v1';
109 18
    }
110
111
    /**
112
     * 设置 base uri
113
     *
114
     * @param $baseUri
115
     *
116
     * @return $this
117
     */
118 1
    public function setBaseUri($baseUri)
119
    {
120 1
        $this->baseUri = $baseUri;
121
122 1
        return $this;
123
    }
124
125
    /**
126
     * 获取 base uri
127
     *
128
     * @return string
129
     */
130 1
    public function getBaseUri()
131
    {
132 1
        return $this->baseUri;
133
    }
134
135
    /**
136
     * 设置 api key 和 api secret
137
     *
138
     * @param $apiKey
139
     * @param $apiSecret
140
     *
141
     * @return $this
142
     */
143 1
    public function setCustomer($apiKey, $apiSecret)
144
    {
145 1
        $this->apiKey = $apiKey;
146 1
        $this->apiSecret = $apiSecret;
147
148 1
        return $this;
149
    }
150
151
    /**
152
     * 获取 api key
153
     *
154
     * @return string
155
     */
156 1
    public function getApiKey()
157
    {
158 1
        return $this->apiKey;
159
    }
160
161
    /**
162
     * 设置 api key
163
     *
164
     * @param mixed|string $apiKey
165
     */
166 1
    public function setApiKey($apiKey)
167
    {
168 1
        $this->apiKey = $apiKey;
169 1
    }
170
171
    /**
172
     * 获取 api secret
173
     *
174
     * @return string
175
     */
176 1
    public function getApiSecret()
177
    {
178 1
        return $this->apiSecret;
179
    }
180
181
    /**
182
     * 设置 api secret
183
     *
184
     * @param mixed|string $apiSecret
185
     */
186 1
    public function setApiSecret($apiSecret)
187
    {
188 1
        $this->apiSecret = $apiSecret;
189 1
    }
190
191
    /**
192
     * 获取 api version
193
     *
194
     * @return mixed|string
195
     */
196 1
    public function getApiVersion()
197
    {
198 1
        return $this->apiVersion;
199
    }
200
201
    /**
202
     * 设置 api version
203
     *
204
     * @param $apiVersion
205
     *
206
     * @return $this
207
     */
208 1
    public function setApiVersion($apiVersion)
209
    {
210 1
        $this->apiVersion = $apiVersion;
211
212 1
        return $this;
213
    }
214
215
    /**
216
     * 设置超时时间
217
     *
218
     * @param $time
219
     *
220
     * @return $this
221
     */
222 1
    public function setOutTime($time)
223
    {
224 1
        $this->outTime = $time;
225
226 1
        return $this;
227
    }
228
229
    /**
230
     * 获取当前设置的超时时间
231
     *
232
     * @return float|mixed
233
     */
234 1
    public function getOutTime()
235
    {
236 1
        return $this->outTime;
237
    }
238
239
    /**
240
     * get a response code
241
     *
242
     * @return int
243
     */
244 1
    public function getResponseCode()
245
    {
246 1
        return $this->getResponse()->getStatusCode();
247
    }
248
249
    /**
250
     * 获取请求的数据
251
     * @return array
252
     */
253 1
    public function getRequestData()
254
    {
255 1
        return $this->requestData;
256
    }
257
258
    /**
259
     * @return array
260
     * @throws ResponseDataParseException
261
     */
262 2
    public function getResponseData()
263
    {
264 2
        $responseBody = (string) $this->getResponse()->getBody();
265
266 2
        $this->responseBody = json_decode($responseBody, true);
0 ignored issues
show
Documentation Bug introduced by
It seems like json_decode($responseBody, true) of type * is incompatible with the declared type array of property $responseBody.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
267
268 2
        if (JSON_ERROR_NONE !== json_last_error()) {
269
            throw new ResponseDataParseException('Failed to parse JSON: ' . json_last_error_msg());
270
        }
271
272 2
        return $this->responseBody;
273
    }
274
275
    /**
276
     * @return \Psr\Http\Message\ResponseInterface \GuzzleHttp\Psr7\RequestInterface
277
     */
278 4
    public function getResponse()
279
    {
280 4
        return $this->response;
281
    }
282
283
    /**
284
     * @return \Psr\Http\Message\RequestInterface \GuzzleHttp\Psr7\Request
285
     */
286 1
    public function getRequest()
287
    {
288 1
        return $this->request;
289
    }
290
291
    /**
292
     * @return Client|ClientInterface
293
     * @throws ApiClientInitException
294
     */
295 10
    public function getHttpClient()
296
    {
297 10
        if (!$this->baseUri) {
298 1
            throw new ApiClientInitException('没有配置有效的 BaseUri');
299
        }
300 9
        if (!($this->httpClient instanceof ClientInterface)) {
301 9
            $this->httpClient = new Client([
302 9
                'base_uri' => rtrim($this->baseUri, '/') . '/',
303 9
                'time_out' => $this->outTime,
304
            ]);
305
        }
306
307 9
        return $this->httpClient;
308
    }
309
310
    /**
311
     * Call a Get Request
312
     *
313
     * @param string $uri
314
     * @param array  $query
315
     *
316
     * @return mixed|null
317
     */
318 9
    public function get($uri, $query = [])
319
    {
320 9
        return $this->request('GET', $uri, $query);
321
    }
322
323
    /**
324
     * Call a Post Request
325
     *
326
     * @param string $uri
327
     * @param array  $data
328
     *
329
     * @return mixed|null
330
     */
331
    public function post($uri, $data = [])
332
    {
333
        return $this->request('POST', $uri, $data);
334
    }
335
336
    /**
337
     * Call a Put Request
338
     *
339
     * @param string $uri
340
     * @param array  $data
341
     *
342
     * @return mixed|null
343
     */
344
    public function put($uri, $data = [])
345
    {
346
        return $this->request('PUT', $uri, $data);
347
    }
348
349
    /**
350
     * Call a delete Request
351
     *
352
     * @param string $uri
353
     * @param array  $query
354
     *
355
     * @return ApiClient
356
     */
357
    public function delete($uri, $query = [])
358
    {
359
        return $this->request('DELETE', $uri, $query);
360
    }
361
362
    /**
363
     * Call a patch Request
364
     *
365
     * @param string $uri
366
     * @param array  $data
367
     *
368
     * @return ApiClient
369
     */
370
    public function patch($uri, $data = [])
371
    {
372
        return $this->request('PATCH', $uri, $data);
373
    }
374
375
    /**
376
     * Call a Request
377
     *
378
     * @param string $method
379
     * @param string $uri
380
     * @param array  $optionals
381
     *
382
     * @return $this
383
     * @throws \Exception
384
     */
385 9
    public function request($method, $uri, $optionals = [])
386
    {
387 9
        $options = $this->extractOptionalParameters($uri, $optionals);
388 9
        $uri = $this->compileRoute($uri, $optionals);
389 9
        $data = [];
390 9
        $method = strtoupper($method);
391
392 9
        $paramType = $method === 'POST' ? RequestOptions::FORM_PARAMS : RequestOptions::QUERY;
393 9
        if (key_exists(RequestOptions::JSON, $options)) {
394
            $json = $options[RequestOptions::JSON];
395
            unset($options[RequestOptions::JSON]);
396
            $data[RequestOptions::JSON] = $json;
397
            $paramType = RequestOptions::QUERY;
398
        }
399 9
        $data[$paramType] = $this->getAuthParams($options);
400 9
        $this->requestData = $data;
401
        $data[RequestOptions::ON_STATS] = function (TransferStats $stats) {
402 9
            $this->lastUrl = (string) $stats->getEffectiveUri();
403 9
            $this->request = $stats->getRequest();
404 9
            $this->transferTime = $stats->getTransferTime();
405 9
        };
406 9
        if ($this->log) {
407
            $data['handler'] = $this->handlerStack;
408
        }
409 9
        if ($this->apiVersion) {
410 9
            $uri = $this->apiVersion . $uri;
411
        }
412 9
        $promise = $this->getHttpClient()->requestAsync($method, $uri, $data);
413 9
        $promise->then(
414
            function (ResponseInterface $response) {
415 9
                $this->response = $response;
416 9
                if ($this->completeCallBack) {
417
                    call_user_func($this->completeCallBack);
418
                }
419 9
            },
420
            function ($e) {
421
                if ($e instanceof BadResponseException) {
422
                    $this->request = $e->getRequest();
423
                    $this->response = $e->getResponse();
424
                } elseif ($e instanceof RequestException) {
425
                    $this->request = $e->getRequest();
426
                    if ($e->hasResponse()) {
427
                        $this->response = $e->getResponse();
428
                    }
429
                }
430
                throw $e;
431 9
            }
432
        );
433 9
        $promise->wait();
434
435 9
        return $this;
436
    }
437
438
    /**
439
     * 获取最后一次请求的 URL
440
     *
441
     * @return string
442
     */
443 1
    public function getLastUrl()
444
    {
445 1
        return (string) $this->lastUrl;
446
    }
447
448
    /**
449
     * 获取请求时间
450
     *
451
     * @return double
452
     */
453 1
    public function getTransferTime()
454
    {
455 1
        return $this->transferTime;
456
    }
457
458
    /**
459
     * 设置日志
460
     *
461
     * @param LoggerInterface $logger
462
     * @param mixed           $format
463
     */
464
    public function setLogger(LoggerInterface $logger, $format = null)
465
    {
466
        $this->log = true;
467
        $this->handlerStack = HandlerStack::create();
468
        if (is_array($format)) {
469
            foreach ($format as $item) {
470
                $this->handlerStack->unshift($this->createGuzzleLoggingMiddleware($logger, $item));
471
            }
472
        } else {
473
            $this->handlerStack->push($this->createGuzzleLoggingMiddleware($logger, $format));
474
        }
475
    }
476
477
    /**
478
     * 创建一个日志中间件
479
     *
480
     * @param $logger
481
     * @param $Format
482
     *
483
     * @return callable
484
     */
485
    private function createGuzzleLoggingMiddleware($logger, $Format)
486
    {
487
        return Middleware::log($logger, new MessageFormatter($Format));
488
    }
489
490
    /**
491
     * 将所有请求参数转为字符串
492
     *
493
     * @param array $param
494
     *
495
     * @return array
496
     */
497 10
    public function standardizeParam($param)
498
    {
499
        return array_map(function ($item) {
500 1
            if (is_array($item)) {
501 1
                return $this->standardizeParam($item);
502
            } else {
503 1
                return (string) $item;
504
            }
505 10
        }, $param);
506
    }
507
508
    /**
509
     * 获取 auth param
510
     *
511
     * @param array $options
512
     *
513
     * @return mixed
514
     */
515 9
    private function getAuthParams($options)
516
    {
517 9
        $this->validateApiOptions();
518
519 9
        if (!$this->authenticator instanceof Authenticator) {
520 9
            $this->authenticator = new Authenticator($this->apiKey, $this->apiSecret);
521
        }
522
523 9
        $options = $this->standardizeParam($options);
524
525 9
        return $this->authenticator->getAuthParams($options);
526
    }
527
528
    /**
529
     * 验证 api 必须的是否已经被初始化
530
     *
531
     * @throws ApiClientInitException
532
     */
533 9
    private function validateApiOptions()
534
    {
535 9
        if (!$this->apiKey) {
536
            throw new ApiClientInitException('没有配置有效的 apiKey');
537
        }
538 9
        if (!$this->apiSecret) {
539
            throw new ApiClientInitException('没有配置有效的 apiSecret');
540
        }
541 9
    }
542
543
    /**
544
     * 替换 url 中的变量
545
     *
546
     * @param string $uri
547
     * @param array  $optionals
548
     *
549
     * @return string
550
     */
551
    protected function compileRoute($uri, $optionals)
552
    {
553 9
        return preg_replace_callback('/\{(\w+?)\??\}/', function ($matches) use ($optionals) {
554 1
            return isset($optionals[$matches[1]]) ? $optionals[$matches[1]] : '';
555 9
        }, $uri);
556
    }
557
558
    /**
559
     * 去掉 uri 中已存在的变量
560
     *
561
     * @param string $uri
562
     * @param array  $optionals
563
     *
564
     * @return array
565
     */
566 9
    protected function extractOptionalParameters($uri, $optionals)
567
    {
568 9
        preg_match_all('/\{(\w+?)\??\}/', $uri, $matches);
569
570 9
        return array_except($optionals, $matches[1]);
571
    }
572
}
573