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.
Test Failed
Pull Request — master (#240)
by Sean
16:48
created

Request   A

Complexity

Total Complexity 40

Size/Duplication

Total Lines 418
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 115
c 2
b 0
f 0
dl 0
loc 418
ccs 121
cts 121
cp 1
rs 9.2
wmc 40

21 Methods

Rating   Name   Duplication   Size   Complexity  
A cleanQuery() 0 4 3
A request() 0 14 3
A appendUserAgent() 0 9 2
A format() 0 5 1
A accept() 0 5 1
A withUserAgent() 0 5 1
A withHttpClient() 0 4 1
A response() 0 16 3
A jsonBody() 0 10 3
A __construct() 0 17 3
A host() 0 5 1
A contentType() 0 5 1
A method() 0 5 1
A cleanFormParams() 0 4 3
A resolveOption() 0 16 2
A client() 0 5 1
A isDebug() 0 11 3
A scheme() 0 6 1
A createClient() 0 26 4
A body() 0 5 1
A requestAsync() 0 8 1

How to fix   Complexity   

Complex Class

Complex classes like Request often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Request, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace AlibabaCloud\Client\Request;
4
5
use AlibabaCloud\Client\AlibabaCloud;
6
use AlibabaCloud\Client\Credentials\Providers\CredentialsProvider;
7
use AlibabaCloud\Client\Encode;
8
use AlibabaCloud\Client\Exception\ClientException;
9
use AlibabaCloud\Client\Exception\ServerException;
10
use AlibabaCloud\Client\Filter\ApiFilter;
11
use AlibabaCloud\Client\Filter\ClientFilter;
12
use AlibabaCloud\Client\Filter\Filter;
13
use AlibabaCloud\Client\Filter\HttpFilter;
14
use AlibabaCloud\Client\Request\Traits\AcsTrait;
15
use AlibabaCloud\Client\Request\Traits\ClientTrait;
16
use AlibabaCloud\Client\Request\Traits\DeprecatedTrait;
17
use AlibabaCloud\Client\Request\Traits\RetryTrait;
18
use AlibabaCloud\Client\Result\Result;
19
use AlibabaCloud\Client\SDK;
20
use AlibabaCloud\Client\Traits\ArrayAccessTrait;
21
use AlibabaCloud\Client\Traits\HttpTrait;
22
use AlibabaCloud\Client\Traits\ObjectAccessTrait;
23
use AlibabaCloud\Client\Traits\RegionTrait;
24
use ArrayAccess;
25
use Exception;
26
use GuzzleHttp\Client;
27
use GuzzleHttp\Exception\GuzzleException;
28
use GuzzleHttp\HandlerStack;
29
use GuzzleHttp\MessageFormatter;
30
use GuzzleHttp\Middleware;
31
use GuzzleHttp\Promise\PromiseInterface;
32
use GuzzleHttp\Psr7\Uri;
33
use Psr\Http\Message\ResponseInterface;
34
35
/**
36
 * Class Request
37
 *
38
 * @package   AlibabaCloud\Client\Request
39
 *
40
 * @method string stringToSign()
41
 * @method string resolveParameter()
42
 */
43
abstract class Request implements ArrayAccess
44
{
45
    use DeprecatedTrait;
46
    use HttpTrait;
47
    use RegionTrait;
48
    use ClientTrait;
49
    use AcsTrait;
50
    use ArrayAccessTrait;
51
    use ObjectAccessTrait;
52
    use RetryTrait;
53
54
    /**
55
     * Request Connect Timeout
56
     */
57
    const CONNECT_TIMEOUT = 5;
58
59
    /**
60
     * Request Timeout
61
     */
62
    const TIMEOUT = 10;
63
64
    /**
65
     * @var string HTTP Method
66
     */
67
    public $method = 'GET';
68
69
    /**
70
     * @var string
71
     */
72
    public $format = 'JSON';
73
74
    /**
75
     * @var string HTTP Scheme
76
     */
77
    protected $scheme = 'http';
78
79
    /**
80
     * @var string
81
     */
82
    public $client;
83
84
    /**
85
     * @var \AlibabaCloud\Client\Clients\Client
86
     */
87
    public $httpClient;
88
89
    /**
90
     * @var Uri
91
     */
92
    public $uri;
93
94
    /**
95
     * @var array The original parameters of the request.
96
     */
97
    public $data = [];
98
99
    /**
100
     * @var array
101
     */
102
    private $userAgent = [];
103
104
    /**
105
     * Request constructor.
106 199
     *
107
     * @param array $options
108 199
     *
109 199
     * @throws ClientException
110 199
     */
111 199
    public function __construct(array $options = [])
112 199
    {
113 199
        $this->client                     = CredentialsProvider::getDefaultName();
114
        $this->uri                        = new Uri();
115
        $this->uri                        = $this->uri->withScheme($this->scheme);
116 199
        $this->options['http_errors']     = false;
117 101
        $this->options['connect_timeout'] = self::CONNECT_TIMEOUT;
118 101
        $this->options['timeout']         = self::TIMEOUT;
119
120
        // Turn on debug mode based on environment variable.
121 199
        if (strtolower(\AlibabaCloud\Client\env('DEBUG')) === 'sdk') {
0 ignored issues
show
Bug introduced by
It seems like env('DEBUG') can also be of type boolean and null; however, parameter $string of strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

121
        if (strtolower(/** @scrutinizer ignore-type */ \AlibabaCloud\Client\env('DEBUG')) === 'sdk') {
Loading history...
122 1
            $this->options['debug'] = true;
123 1
        }
124 199
125
        // Rewrite configuration if the user has a configuration.
126
        if ($options !== []) {
127
            $this->options($options);
128
        }
129
    }
130
131
    /**
132
     * @param string $name
133 5
     * @param string $value
134
     *
135 5
     * @return $this
136
     * @throws ClientException
137 3
     */
138 3
    public function appendUserAgent($name, $value)
139 1
    {
140
        $filter_name = Filter::name($name);
141 1
142
        if (!UserAgent::isGuarded($filter_name)) {
143
            $this->userAgent[$filter_name] = Filter::value($value);
144
        }
145
146
        return $this;
147
    }
148
149 2
    /**
150
     * @param array $userAgent
151 2
     *
152
     * @return $this
153 2
     */
154
    public function withUserAgent(array $userAgent)
155
    {
156
        $this->userAgent = UserAgent::clean($userAgent);
157
158
        return $this;
159
    }
160
161
    /**
162
     * Set Accept format.
163
     *
164 14
     * @param string $format
165
     *
166 14
     * @return $this
167
     * @throws ClientException
168 12
     */
169
    public function format($format)
170
    {
171
        $this->format = ApiFilter::format($format);
172
173
        return $this;
174
    }
175
176
    /**
177 1
     * @param $contentType
178
     *
179 1
     * @return $this
180
     * @throws ClientException
181 1
     */
182 1
    public function contentType($contentType)
183
    {
184
        $this->options['headers']['Content-Type'] = HttpFilter::contentType($contentType);
185
186
        return $this;
187
    }
188
189
    /**
190 2
     * @param string $accept
191
     *
192 2
     * @return $this
193
     * @throws ClientException
194 2
     */
195
    public function accept($accept)
196
    {
197
        $this->options['headers']['Accept'] = HttpFilter::accept($accept);
198
199
        return $this;
200
    }
201
202
    /**
203
     * Set the request body.
204
     *
205 5
     * @param string $body
206
     *
207 5
     * @return $this
208
     * @throws ClientException
209 3
     */
210
    public function body($body)
211
    {
212
        $this->options['body'] = HttpFilter::body($body);
213
214
        return $this;
215
    }
216
217
    /**
218
     * Set the json as body.
219
     *
220 3
     * @param array|object $content
221
     *
222 3
     * @return $this
223 1
     * @throws ClientException
224 1
     */
225
    public function jsonBody($content)
226 1
    {
227
        if (!\is_array($content) && !\is_object($content)) {
228
            throw new ClientException(
229 2
                'jsonBody only accepts an array or object',
230
                SDK::INVALID_ARGUMENT
231
            );
232
        }
233
234
        return $this->body(\json_encode($content));
235
    }
236
237
    /**
238
     * Set the request scheme.
239
     *
240 17
     * @param string $scheme
241
     *
242 17
     * @return $this
243 15
     * @throws ClientException
244
     */
245 15
    public function scheme($scheme)
246
    {
247
        $this->scheme = HttpFilter::scheme($scheme);
248
        $this->uri    = $this->uri->withScheme($scheme);
249
250
        return $this;
251
    }
252
253
    /**
254
     * Set the request host.
255
     *
256 28
     * @param string $host
257
     *
258 28
     * @return $this
259
     * @throws ClientException
260 26
     */
261
    public function host($host)
262
    {
263
        $this->uri = $this->uri->withHost(HttpFilter::host($host));
264
265
        return $this;
266
    }
267
268
    /**
269 54
     * @param string $method
270
     *
271 54
     * @return $this
272
     * @throws ClientException
273 52
     */
274
    public function method($method)
275
    {
276
        $this->method = HttpFilter::method($method);
277
278
        return $this;
279
    }
280
281
    /**
282 67
     * @param string $clientName
283
     *
284 67
     * @return $this
285
     * @throws ClientException
286 65
     */
287
    public function client($clientName)
288
    {
289
        $this->client = ClientFilter::clientName($clientName);
290
291
        return $this;
292
    }
293 1
294
295 1
    /**
296 1
     *
297
     *
298
     * @param \AlibabaCloud\Client\Clients\Client $client
299 1
     * @return $this
300 1
     */
301
    public function withHttpClient(\AlibabaCloud\Client\Clients\Client  $client)
302
    {
303 1
        $this->httpClient = $client;
304
        return $this;
305
    }
306
307
    /**
308
     * @return bool
309
     * @throws ClientException
310 71
     */
311
    public function isDebug()
312 71
    {
313
        if (isset($this->options['debug'])) {
314 71
            return $this->options['debug'] === true;
315 71
        }
316 71
317 68
        if (isset($this->httpClient()->options['debug'])) {
318
            return $this->httpClient()->options['debug'] === true;
319 65
        }
320 32
321 32
        return false;
322 32
    }
323 32
324
    /**
325 65
     * @throws ClientException
326 65
     * @throws ServerException
327
     */
328
    public function resolveOption()
329
    {
330
        $this->options['headers']['User-Agent'] = UserAgent::toString($this->userAgent);
331
332
        $this->cleanQuery();
333 69
        $this->cleanFormParams();
334
        $this->resolveHost();
335 69
        $this->resolveParameter();
336 63
337
        if (isset($this->options['form_params'])) {
338 56
            $this->options['form_params'] = \GuzzleHttp\Psr7\parse_query(
0 ignored issues
show
Deprecated Code introduced by
The function GuzzleHttp\Psr7\parse_query() has been deprecated: parse_query will be removed in guzzlehttp/psr7:2.0. Use Query::parse instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

338
            $this->options['form_params'] = /** @scrutinizer ignore-deprecated */ \GuzzleHttp\Psr7\parse_query(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
339 2
                Encode::create($this->options['form_params'])->toString()
340
            );
341
        }
342 56
343 22
        $this->mergeOptionsIntoClient();
344
    }
345
346 35
    /**
347
     * @return Result
348
     * @throws ClientException
349
     * @throws ServerException
350
     */
351
    public function request()
352
    {
353 2
        $this->resolveOption();
354
        $result = $this->response();
355 2
356
        if ($this->shouldServerRetry($result)) {
357 2
            return $this->request();
358 2
        }
359 2
360 2
        if (!$result->isSuccess()) {
0 ignored issues
show
Bug introduced by
The method isSuccess() does not exist on Psr\Http\Message\ResponseInterface. It seems like you code against a sub-type of Psr\Http\Message\ResponseInterface such as AlibabaCloud\Client\Result\Result. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

360
        if (!$result->/** @scrutinizer ignore-call */ isSuccess()) {
Loading history...
361 2
            throw new ServerException($result);
362
        }
363
364
        return $result;
365
    }
366
367
    /***
368
     * @return PromiseInterface
369
     * @throws Exception
370 75
     */
371
    public function requestAsync()
372 75
    {
373 22
        $this->resolveOption();
374 22
375 53
        return self::createClient($this)->requestAsync(
376
            $this->method,
377
            (string)$this->uri,
378 75
            $this->options
379 40
        );
380 40
    }
381
382 75
    /**
383 2
     * @param Request $request
384 2
     *
385 2
     * @return Client
386 2
     * @throws Exception
387 2
     */
388
    public static function createClient(Request $request = null)
389 75
    {
390 61
        if (AlibabaCloud::hasMock()) {
391 75
            $stack = HandlerStack::create(AlibabaCloud::getMock());
392
        } else {
393 75
            $stack = HandlerStack::create();
394
        }
395 75
396
        if (AlibabaCloud::isRememberHistory()) {
397
            $stack->push(Middleware::history(AlibabaCloud::referenceHistory()));
398
        }
399
400
        if (AlibabaCloud::getLogger()) {
401
            $stack->push(Middleware::log(
402 63
                AlibabaCloud::getLogger(),
403
                new MessageFormatter(AlibabaCloud::getLogFormat())
404
            ));
405 63
        }
406 63
407 63
        $stack->push(Middleware::mapResponse(static function (ResponseInterface $response) use ($request) {
408 63
            return new Result($response, $request);
409 63
        }));
410 8
411 7
        self::$config['handler'] = $stack;
412 2
413
        return new Client(self::$config);
414 7
    }
415 7
416 7
    /**
417
     * @throws ClientException
418 7
     * @throws Exception
419
     */
420
    private function response()
421
    {
422
        try {
423
            return self::createClient($this)->request(
424
                $this->method,
425
                (string)$this->uri,
426
                $this->options
427
            );
428
        } catch (GuzzleException $exception) {
429
            if ($this->shouldClientRetry($exception)) {
430
                return $this->response();
431
            }
432
            throw new ClientException(
433
                $exception->getMessage(),
434
                SDK::SERVER_UNREACHABLE,
435
                $exception
436
            );
437
        }
438
    }
439
440
    /**
441
     * Remove redundant Query
442
     *
443
     * @codeCoverageIgnore
444
     */
445
    private function cleanQuery()
446
    {
447
        if (isset($this->options['query']) && $this->options['query'] === []) {
448
            unset($this->options['query']);
449
        }
450
    }
451
452
    /**
453
     * Remove redundant Headers
454
     *
455
     * @codeCoverageIgnore
456
     */
457
    private function cleanFormParams()
458
    {
459
        if (isset($this->options['form_params']) && $this->options['form_params'] === []) {
460
            unset($this->options['form_params']);
461
        }
462
    }
463
}
464