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
Pull Request — master (#34)
by Evgeny
02:19
created

AbstractList::setGetParams()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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