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.

AbstractList::processingResponses()   B
last analyzed

Complexity

Conditions 5
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 5
nc 3
nop 1
1
<?php
2
3
namespace SimaLand\API;
4
5
use GuzzleHttp\Psr7\Response;
6
use SimaLand\API\Rest\Client;
7
use SimaLand\API\Rest\Request;
8
use SimaLand\API\Rest\ResponseException;
9
use GuzzleHttp\Exception\RequestException;
10
11
/**
12
 * Абстрактный класс для загрузки данных сущности.
13
 *
14
 * Класс реализует интерфейс Iterator.
15
 *
16
 * @property $getParams GET параметры запроса.
17
 */
18
abstract class AbstractList extends Object implements \Iterator
19
{
20
    /**
21
     * Кол-во потоков.
22
     *
23
     * @var int
24
     */
25
    public $countThreads = 5;
26
27
    /**
28
     * GET параметр отвечающий за поток.
29
     *
30
     * @var string
31
     */
32
    public $keyThreads = 'p';
33
34
    /**
35
     * GET параметры запроса.
36
     *
37
     * @var array
38
     */
39
    protected $_getParams = [];
40
41
    /**
42
     * Кол-во повторов обращение к ресурсу при ошибках.
43
     *
44
     * @var int
45
     */
46
    public $repeatTimeout = 30;
47
48
    /**
49
     * Время в секундак до следующего обращения к ресурсу.
50
     *
51
     * @var int
52
     */
53
    public $repeatCount = 30;
54
55
56
    /**
57
     * SimaLand кдиент для запросов.
58
     *
59
     * @var \SimaLand\API\Rest\Client
60
     */
61
    private $client;
62
63
    /**
64
     * Список запросов.
65
     *
66
     * @var Request[]
67
     */
68
    private $requests = [];
69
70
    /**
71
     * Список данных полученные по API.
72
     *
73
     * @var array
74
     */
75
    private $values = [];
76
77
    /**
78
     * Ключ текущей записи.
79
     *
80
     * @var int
81
     */
82
    private $key;
83
84
    /**
85
     * Текущая запись.
86
     *
87
     * @var mixed
88
     */
89
    private $current;
90
91
    /**
92
     * Кол-во итераций. В одной итерации может быть несколько обращений к API, см countThreads.
93
     *
94
     * @var int
95
     */
96
    private $countIteration = 0;
97
98
    /**
99
     * @param Client $client
100
     * @param array $options
101
     */
102
    public function __construct(Client $client, array $options = [])
103
    {
104
        $this->client = $client;
105
        parent::__construct($options);
106
    }
107
108
    /**
109
     * Получить наименование сущности.
110
     *
111
     * @return string
112
     */
113
    abstract public function getEntity();
114
115
    /**
116
     * Добавить get параметры.
117
     *
118
     * @param array $params
119
     * @return AbstractList
120
     */
121
    public function addGetParams(array $params)
122
    {
123
        $this->setGetParams(array_merge($this->_getParams, $params));
124
        return $this;
125
    }
126
127
    /**
128
     * Назначить следующую страницу запросу.
129
     *
130
     * @param Request $request
131
     */
132
    public function assignPage(Request &$request)
133
    {
134
        $currentPage = 1;
135
        if (!is_array($request->getParams)) {
136
            $request->getParams = (array)$request->getParams;
137
        }
138
        if (isset($request->getParams[$this->keyThreads])) {
139
            $currentPage = (int)$request->getParams[$this->keyThreads];
140
        }
141
        $request->getParams[$this->keyThreads] = $currentPage + $this->countThreads;
142
    }
143
144
    /**
145
     * Назначить номер потока для запроса.
146
     *
147
     * @param Request $request
148
     * @param int $number
149
     */
150
    public function assignThreadsNumber(Request &$request, $number = 0)
151
    {
152
        if (!is_array($request->getParams)) {
153
            $request->getParams = (array)$request->getParams;
154
        }
155
        if (!isset($request->getParams[$this->keyThreads])) {
156
            $request->getParams[$this->keyThreads] = 1;
157
        }
158
        $request->getParams[$this->keyThreads] += $number;
159
    }
160
161
    /**
162
     * Палучить набор данных сущности.
163
     *
164
     * @return Response[]
165
     * @throws \Exception
166
     */
167
    public function get()
168
    {
169
        return $this->client->batchQuery($this->getRequests());
170
    }
171
172
    /**
173
     * Установить запросы к API.
174
     *
175
     * @param Request[] $requests
176
     * @throws \Exception
177
     */
178
    public function setRequests(array $requests)
179
    {
180
        $this->requests = [];
181
        foreach ($requests as $request) {
182
            if (!$request instanceof Request) {
183
                throw new \Exception('Request must be implement "\SimaLand\API\Rest\Request"');
184
            }
185
            $this->requests[] = $request;
186
        }
187
    }
188
189
    /**
190
     * Получить запросы к API.
191
     *
192
     * @return array|Rest\Request[]
193
     */
194
    public function getRequests()
195
    {
196
        if (empty($this->requests)) {
197
            $requests = [];
198
            if (!is_null($this->keyThreads) && $this->countThreads > 1) {
199
                for ($i = 0; $i < $this->countThreads; $i++) {
200
                    $requests[$i] = new Request([
201
                        'entity' => $this->getEntity(),
202
                        'getParams' => $this->_getParams,
203
                    ]);
204
                    $this->assignThreadsNumber($requests[$i], $i);
205
                }
206
            } else {
207
                $requests[] = new Request([
208
                    'entity' => $this->getEntity(),
209
                    'getParams' => $this->_getParams,
210
                ]);
211
            }
212
            $this->requests = $requests;
213
        }
214
        return $this->requests;
215
    }
216
217
    /**
218
     * @inheritdoc
219
     */
220
    public function current()
221
    {
222
        return $this->current;
223
    }
224
225
    /**
226
     * @inheritdoc
227
     */
228
    public function next()
229
    {
230
        if (empty($this->values)) {
231
            $this->getData();
232
        }
233
        $this->current = array_shift($this->values);
234
    }
235
236
    /**
237
     * @inheritdoc
238
     */
239
    public function key()
240
    {
241
        return $this->key++;
242
    }
243
244
    /**
245
     * @inheritdoc
246
     */
247
    public function valid()
248
    {
249
        return !empty($this->current);
250
    }
251
252
    /**
253
     * @inheritdoc
254
     */
255
    public function rewind()
256
    {
257
        $this->values = [];
258
        $this->current = null;
259
        $this->key = 0;
260
        $this->next();
261
    }
262
263
    /**
264
     * Обработка ответов от API.
265
     *
266
     * @param Response[] $responses
267
     * @throws ResponseException
268
     */
269
    private function processingResponses(array $responses)
270
    {
271
        foreach ($responses as $response) {
272
            $statusCode = $response->getStatusCode();
273
            if (($statusCode < 200 || $statusCode >= 300) && $statusCode != 404) {
274
                throw new ResponseException($response);
275
            }
276
        }
277
    }
278
279
    /**
280
     * Получение ответов от API
281
     *
282
     * @return \GuzzleHttp\Psr7\Response[]
283
     * @throws \Exception
284
     */
285
    private function getResponses()
286
    {
287
        $i = 0;
288
        $responses = [];
289
        $logger = $this->getLogger();
290
        do {
291
            $e = null;
292
            if ($i > 0) {
293
                $logger->info("Wait time {$this->repeatTimeout} second to the next request");
294
                sleep($this->repeatTimeout);
295
                $attempt = $i + 1;
296
                $logger->info("Attempt {$attempt} of {$this->repeatCount}");
297
            }
298
            try {
299
                $responses = $this->get();
300
                $this->processingResponses($responses);
301
            } catch (\Exception $e) {
302
                if (
303
                    ($e instanceof RequestException) ||
304
                    ($e instanceof ResponseException)
305
                ) {
306
                    $logger->warning($e->getMessage(), ['code' => $e->getCode()]);
307
                } else {
308
                    throw $e;
309
                }
310
            }
311
            $i++;
312
        } while ($i <= $this->repeatCount && !is_null($e));
313
        if ($e) {
314
            $logger->error($e->getMessage(), ['code' => $e->getCode()]);
315
            throw new Exception($e->getMessage(), $e->getCode(), $e);
316
        }
317
        return $responses;
318
    }
319
320
    /**
321
     * Получить тело ответа от API.
322
     *
323
     * @param Response $response
324
     * @return bool
325
     */
326
    private function getBody(Response $response)
327
    {
328
        $body = json_decode($response->getBody(), true);
329
        if (!$body || $response->getStatusCode() != 200) {
330
            return false;
331
        }
332
        return $body;
333
    }
334
335
    /**
336
     * Получить набор данных от API.
337
     *
338
     * @throws Exception
339
     */
340
    private function getData()
341
    {
342
        $this->countIteration++;
343
        $responses = $this->getResponses();
344
        $requests = $this->getRequests();
345
        foreach ($responses as $key => $response) {
346
            $body = $this->getBody($response);
347
            if (!$body) {
348
                unset($requests[$key]);
349
                continue;
350
            }
351
352
            $this->values = array_merge($this->values, $body);
353
            $this->assignPage($requests[$key]);
354
        }
355
        $this->setRequests($requests);
356
    }
357
358
    /**
359
     * Установить GET параметры запроса.
360
     *
361
     * @param array $value
362
     */
363
    public function setGetParams(array $value)
364
    {
365
        $this->_getParams = $value;
366
    }
367
368
    /**
369
     * Получить GET параметры запроса.
370
     *
371
     * @return array
372
     */
373
    public function getGetParams()
374
    {
375
        return $this->_getParams;
376
    }
377
378
    /**
379
     * Установить кол-во итераций.
380
     *
381
     * @param int $value
382
     */
383
    public function setCountIteration($value)
384
    {
385
        $this->countIteration = (int)$value;
386
    }
387
388
    /**
389
     * Получить кол-во итераций.
390
     *
391
     * @return int
392
     */
393
    public function getCountIteration()
394
    {
395
        return $this->countIteration;
396
    }
397
}
398