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 ( 2a3c26...91a248 )
by Evgeny
10s
created

AbstractList::getResponses()   C

Complexity

Conditions 7
Paths 20

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

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