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.
Completed
Push — master ( a47fdd...83abd3 )
by
unknown
11s
created

AbstractList::setGetParams()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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