This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Class BookCollection |
||
4 | * |
||
5 | * @author Denis Shestakov <[email protected]> |
||
6 | * @copyright Copyright (c) 2017, Lan Publishing |
||
7 | * @license MIT |
||
8 | */ |
||
9 | |||
10 | namespace Lan\Ebs\Sdk\Classes; |
||
11 | |||
12 | use ArrayObject; |
||
13 | use Exception; |
||
14 | use Lan\Ebs\Sdk\Client; |
||
15 | use Lan\Ebs\Sdk\Collection\ArticleCollection; |
||
16 | use Lan\Ebs\Sdk\Collection\IssueCollection; |
||
17 | use Lan\Ebs\Sdk\Common; |
||
18 | use ReflectionClass; |
||
19 | |||
20 | /** |
||
21 | * Абстрактный класс для всех коллекций (+ итерируемый) |
||
22 | * |
||
23 | * @package Lan\Ebs |
||
24 | * @subpackage Sdk |
||
25 | * @category Classes |
||
26 | */ |
||
27 | abstract class Collection extends ArrayObject implements Common |
||
28 | { |
||
29 | /** |
||
30 | * Инстанс клиента API |
||
31 | * |
||
32 | * @var Client |
||
33 | */ |
||
34 | private $client; |
||
35 | |||
36 | /** |
||
37 | * Флаг, сигнализирующий что коллекция загружена |
||
38 | * |
||
39 | * @var int |
||
40 | */ |
||
41 | private $loadStatus = 0; |
||
42 | |||
43 | /** |
||
44 | * Имена полей, подлежаших получению через API |
||
45 | * |
||
46 | * @var array |
||
47 | */ |
||
48 | private $fields = array(); |
||
49 | |||
50 | /** |
||
51 | * Класс модели |
||
52 | * |
||
53 | * @var Model|string |
||
54 | */ |
||
55 | private $class = null; |
||
56 | |||
57 | /** |
||
58 | * Лимит получаемых моделей коллекции через API |
||
59 | * |
||
60 | * @var int |
||
61 | */ |
||
62 | private $limit = null; |
||
63 | |||
64 | /** |
||
65 | * Смещение выборки моделей через API |
||
66 | * |
||
67 | * @var int |
||
68 | */ |
||
69 | private $offset = null; |
||
70 | |||
71 | /** |
||
72 | * Всего элементов без учета лимита |
||
73 | * |
||
74 | * @var int |
||
75 | */ |
||
76 | private $fullCount = null; |
||
77 | |||
78 | /** |
||
79 | * Конструктор коллекции |
||
80 | * |
||
81 | * @param Client $client Инстанс клиента |
||
82 | * @param array $fields Поля для выборки |
||
83 | * @param string $class Класс модели |
||
84 | * @param int $limit Лимит выборки |
||
85 | * @param int $offset Смещение выборки |
||
86 | * |
||
87 | * Пример: |
||
88 | * ```php |
||
89 | * $token = '7c0c2193d27108a509abd8ea84a8750c82b3a520'; // токен для тестового подписчика |
||
90 | * |
||
91 | * $client = new Client($token); // инициализация клиента |
||
92 | * |
||
93 | * $bookCollection = new BookCollection($client, [], '\Lan\Ebs\Sdk\Model\Book', 5, 10); // инициализация коллекции книг |
||
94 | * ``` |
||
95 | * |
||
96 | * @throws Exception |
||
97 | * |
||
98 | * @see ArticleCollection::__construct |
||
99 | * @see BookCollection::__construct |
||
100 | * @see IssueCollection::__construct |
||
101 | * @see JournalCollection::__construct |
||
102 | * @see UserCollection::__construct |
||
103 | */ |
||
104 | 3 | public function __construct(Client $client, array $fields, $class, $limit, $offset) |
|
105 | { |
||
106 | 3 | if (!$client) { |
|
107 | throw new Exception('Клиент не инициализирован'); |
||
108 | } |
||
109 | |||
110 | 3 | if (!is_array($fields)) { |
|
111 | throw new Exception('Fields for model of collection mast be array'); |
||
112 | } |
||
113 | |||
114 | 3 | $reflectionClass = new ReflectionClass($class); |
|
115 | |||
116 | 3 | if (!$reflectionClass->isSubclassOf(Model::class)) { |
|
117 | throw new Exception('Class of model collection not subclass for Model'); |
||
118 | } |
||
119 | |||
120 | 3 | $this->client = $client; |
|
121 | 3 | $this->fields = $fields; |
|
122 | 3 | $this->class = $class; |
|
123 | |||
124 | 3 | $this->setLimit($limit); |
|
125 | 3 | $this->setOffset($offset); |
|
126 | 3 | } |
|
127 | |||
128 | /** |
||
129 | * Установка лимита выборки |
||
130 | * |
||
131 | * Установка/изменение лимита выборки коллекции. Вызывет перезагрузку коллекции если значение лимита изменилось |
||
132 | * |
||
133 | * @param int $limit Значение лимита выборки |
||
134 | * |
||
135 | * Пример: |
||
136 | * ```php |
||
137 | * $token = '7c0c2193d27108a509abd8ea84a8750c82b3a520'; // токен для тестового подписчика |
||
138 | * |
||
139 | * $client = new Client($token); // инициализация клиента |
||
140 | * |
||
141 | * $bookCollection = new BookCollection($client, [], '\Lan\Ebs\Sdk\Model\Book', 5, 100); // инициализация коллекции книг |
||
142 | * |
||
143 | * $bookCollection->setLimit(100); // изменение лимита с 5 до 100 |
||
144 | * ``` |
||
145 | * |
||
146 | * @return $this |
||
147 | * |
||
148 | * Пример: |
||
149 | * ```php |
||
150 | * echo $bookCollection->setLimit(100)->count(); // Выведет количество элементов коллекции |
||
151 | * ``` |
||
152 | * |
||
153 | * @throws Exception |
||
154 | */ |
||
155 | 3 | View Code Duplication | public function setLimit($limit) |
0 ignored issues
–
show
|
|||
156 | { |
||
157 | 3 | $isChanged = $this->limit != $limit; |
|
158 | |||
159 | 3 | $this->limit = $limit; |
|
160 | |||
161 | 3 | if ($isChanged && $this->loadStatus == 200) { |
|
162 | $this->load(true); |
||
163 | } |
||
164 | |||
165 | 3 | return $this; |
|
166 | } |
||
167 | |||
168 | /** |
||
169 | * Загрузка коллекции |
||
170 | * |
||
171 | * Загрузка осуществляется только после вызова зависимого метода (ленивая загрузка) |
||
172 | * |
||
173 | * @param bool $force Заново загружать коллекцию даже если она загружена ранее |
||
174 | * |
||
175 | * Пример: |
||
176 | * ```php |
||
177 | * $token = '7c0c2193d27108a509abd8ea84a8750c82b3a520'; // токен для тестового подписчика |
||
178 | * |
||
179 | * $client = new Client($token); // инициализация клиента |
||
180 | * |
||
181 | * $bookCollection = new BookCollection($client, [], '\Lan\Ebs\Sdk\Model\Book', 5, 100); // инициализация коллекции книг |
||
182 | * |
||
183 | * // Вызова метода загрузки еще небыло.. коллекция пустая |
||
184 | * $bookCollection->load(); // загрузка коллекции данными |
||
185 | * // Запрос к API выполнен.. коллекция загружена |
||
186 | * ``` |
||
187 | * |
||
188 | * @return $this Вернет текущую коллекцию |
||
189 | * |
||
190 | * Пример: |
||
191 | * ```php |
||
192 | * echo $bookCollection->load()->count(); // Выведет количество элементов коллекции |
||
193 | * ``` |
||
194 | * |
||
195 | * @throws Exception |
||
196 | * |
||
197 | * @see Collection::setLimit() |
||
198 | * @see Collection::setOffset() |
||
199 | * @see Collection::getFullCount() |
||
200 | * @see Collection::getCount() |
||
201 | * @see Collection::getData() |
||
202 | * @see Collection::reset() |
||
203 | * @see Collection::end() |
||
204 | * @see CollectionIterator::rewind() |
||
205 | */ |
||
206 | 3 | public function load($force = false) |
|
207 | { |
||
208 | 3 | if ($this->loadStatus == 200 && !$force) { |
|
209 | return $this; |
||
210 | } |
||
211 | |||
212 | $params = array( |
||
213 | 3 | 'limit' => $this->limit, |
|
214 | 3 | 'offset' => $this->offset |
|
215 | ); |
||
216 | |||
217 | 3 | if (!empty($this->fields)) { |
|
218 | $params['fields'] = implode(',', (array)$this->fields); |
||
219 | } |
||
220 | |||
221 | 3 | $response = $this->client->getResponse($this->getUrl(__FUNCTION__), $params); |
|
222 | |||
223 | $this->exchangeArray($response['data']); |
||
224 | |||
225 | $this->loadStatus = $response['status']; |
||
226 | |||
227 | $this->fullCount = $response['count']; |
||
228 | |||
229 | unset($response); |
||
230 | |||
231 | return $this; |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Установка смещения выборки |
||
236 | * |
||
237 | * Установка/изменение смещения выборки коллекции. Вызывет перезагрузку коллекции если значение смещения изменилось |
||
238 | * |
||
239 | * @param int $offset Значение смещения выборки |
||
240 | * |
||
241 | * Пример: |
||
242 | * ```php |
||
243 | * $token = '7c0c2193d27108a509abd8ea84a8750c82b3a520'; // токен для тестового подписчика |
||
244 | * |
||
245 | * $client = new Client($token); // инициализация клиента |
||
246 | * |
||
247 | * $bookCollection = new BookCollection($client, [], '\Lan\Ebs\Sdk\Model\Book', 5, 100); // инициализация коллекции книг |
||
248 | * |
||
249 | * $bookCollection->setOffset(1000); // изменение смещения со 100 до 1000 |
||
250 | * ``` |
||
251 | * |
||
252 | * @return $this Вернет текущую коллекцию |
||
253 | * |
||
254 | * Пример: |
||
255 | * ```php |
||
256 | * echo $bookCollection->setOffset(1000)->count(); // Выведет количество элементов коллекции |
||
257 | * ``` |
||
258 | * |
||
259 | * @throws Exception |
||
260 | */ |
||
261 | 3 | View Code Duplication | public function setOffset($offset) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
262 | { |
||
263 | 3 | $isChanged = $this->offset != $offset; |
|
264 | |||
265 | 3 | $this->offset = $offset; |
|
266 | |||
267 | 3 | if ($isChanged && $this->loadStatus == 200) { |
|
268 | $this->load(true); |
||
269 | } |
||
270 | |||
271 | 3 | return $this; |
|
272 | } |
||
273 | |||
274 | /** |
||
275 | * Получение количества всех элементов без учета лимита |
||
276 | * |
||
277 | * Вернет общее количество элементов необходимое, например, для вычисления постраничной выборки |
||
278 | * |
||
279 | * Пример: |
||
280 | * ```php |
||
281 | * $token = '7c0c2193d27108a509abd8ea84a8750c82b3a520'; // токен для тестового подписчика |
||
282 | * |
||
283 | * $client = new Client($token); // инициализация клиента |
||
284 | * |
||
285 | * $bookCollection = new BookCollection($client, [], '\Lan\Ebs\Sdk\Model\Book', 5, 100); // инициализация коллекции книг |
||
286 | * |
||
287 | * echo $bookCollection->getFullCount(); // Вернет количество элементов без учета лимита |
||
288 | * ``` |
||
289 | * |
||
290 | * @return int |
||
291 | * |
||
292 | * Пример: |
||
293 | * ```php |
||
294 | * echo $bookCollection>getFullCount(); // Вернет, например, 286 |
||
295 | * echo $bookCollection->сount(); // Вернет, например, 5 |
||
296 | * // Итого получаем ceil($bookCollection>getFullCount() / $bookCollection>getLimit()) = 58 страниц |
||
297 | * ``` |
||
298 | * |
||
299 | * @throws Exception |
||
300 | */ |
||
301 | public function getFullCount() |
||
302 | { |
||
303 | $this->load(); |
||
304 | |||
305 | return $this->fullCount; |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * Получение нового инстанса итератора коллекции |
||
310 | * |
||
311 | * Итератор для реализации итерируемой коллекции |
||
312 | * |
||
313 | * @return CollectionIterator Вернет экзепляря итератора текущей коллекции |
||
314 | */ |
||
315 | public function getIterator() |
||
316 | { |
||
317 | return new CollectionIterator($this); |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * Количество моделей в коллекции |
||
322 | * |
||
323 | * Фактическое число моделей в коллекции |
||
324 | * |
||
325 | * Пример: |
||
326 | * ```php |
||
327 | * $token = '7c0c2193d27108a509abd8ea84a8750c82b3a520'; // токен для тестового подписчика |
||
328 | * |
||
329 | * $client = new Client($token); // инициализация клиента |
||
330 | * |
||
331 | * $bookCollection = new BookCollection($client, [], '\Lan\Ebs\Sdk\Model\Book', 5, 100); // инициализация коллекции книг |
||
332 | * |
||
333 | * echo $bookCollection>getFullCount(); // Вернет количество элементов без учета лимита |
||
334 | * ``` |
||
335 | * |
||
336 | * @return int |
||
337 | * |
||
338 | * Пример: |
||
339 | * ```php |
||
340 | * echo $bookCollection->сount(); // Вернет, например, 5 (но не больше 5 - фактическое количество) |
||
341 | * ``` |
||
342 | * |
||
343 | * @throws Exception |
||
344 | */ |
||
345 | 2 | public function count() |
|
346 | { |
||
347 | 2 | $this->load(); |
|
348 | |||
349 | return parent::count(); |
||
350 | } |
||
351 | |||
352 | /** |
||
353 | * Получение коллекции в виде массива |
||
354 | * |
||
355 | * Выгрузка коллекции в массив |
||
356 | * |
||
357 | * Пример: |
||
358 | * ```php |
||
359 | * $token = '7c0c2193d27108a509abd8ea84a8750c82b3a520'; // токен для тестового подписчика |
||
360 | * |
||
361 | * $client = new Client($token); // инициализация клиента |
||
362 | * |
||
363 | * $bookCollection = new BookCollection($client, [], '\Lan\Ebs\Sdk\Model\Book', 1, 10); // инициализация коллекции книг |
||
364 | * |
||
365 | * print_r($bookCollection->getData()); // Вернет количество элементов без учета лимита |
||
366 | * ``` |
||
367 | * |
||
368 | * @return array |
||
369 | * |
||
370 | * Пример: |
||
371 | * ``` |
||
372 | * [ |
||
373 | * 'id' => 22445, |
||
374 | * 'name' => 'Свадьба. Сцена в одном действии', |
||
375 | * 'authors' => 'Чехов А.П.' |
||
376 | * ] |
||
377 | * ``` |
||
378 | * |
||
379 | * @throws Exception |
||
380 | */ |
||
381 | public function getData() |
||
382 | { |
||
383 | $this->load(); |
||
384 | |||
385 | return $this->getArrayCopy(); |
||
386 | } |
||
387 | |||
388 | /** |
||
389 | * Получение первой модели в коллекции |
||
390 | * |
||
391 | * Вернет первую модель коллекции. |
||
392 | * |
||
393 | * @return Model |
||
394 | * |
||
395 | * @throws Exception |
||
396 | */ |
||
397 | 1 | public function reset() |
|
398 | { |
||
399 | 1 | $this->load(); |
|
400 | |||
401 | $data = reset($this); |
||
402 | |||
403 | return $data ? $this->createModel($data) : null; |
||
404 | } |
||
405 | |||
406 | /** |
||
407 | * Создание модели по переданным данным |
||
408 | * |
||
409 | * Создает модель по ее данным |
||
410 | * |
||
411 | * Пример: |
||
412 | * ```php |
||
413 | * $token = '7c0c2193d27108a509abd8ea84a8750c82b3a520'; // токен для тестового подписчика |
||
414 | * |
||
415 | * $client = new Client($token); // инициализация клиента |
||
416 | * |
||
417 | * $bookCollection = new BookCollection($client, [], '\Lan\Ebs\Sdk\Model\Book', 1, 10); // инициализация коллекции книг |
||
418 | * |
||
419 | * $bookData = [ |
||
420 | * 'id' => 22445, |
||
421 | * 'name' => 'Свадьба. Сцена в одном действии', |
||
422 | * 'authors' => 'Чехов А.П.' |
||
423 | * ]; |
||
424 | * |
||
425 | * $book = $bookCollection->createModel($bookData); |
||
426 | * ``` |
||
427 | * |
||
428 | * @param array $data Данные для создания модели |
||
429 | * |
||
430 | * @return Model Вернет модель на основе данных |
||
431 | * |
||
432 | * @throws Exception |
||
433 | */ |
||
434 | public function createModel(array $data = null) |
||
435 | { |
||
436 | $class = $this->class; |
||
437 | |||
438 | /** |
||
439 | * @var Model $model |
||
440 | */ |
||
441 | $model = new $class($this->client, $this->fields); |
||
442 | |||
443 | $model->set($data === null ? current($this) : $data); |
||
444 | |||
445 | return $model; |
||
446 | } |
||
447 | |||
448 | /** |
||
449 | * Получение последней модели в коллекции |
||
450 | * |
||
451 | * Вернет полделнюю модель коллекции. |
||
452 | * |
||
453 | * @return Model |
||
454 | * |
||
455 | * @throws Exception |
||
456 | */ |
||
457 | public function end() |
||
458 | { |
||
459 | $this->load(); |
||
460 | |||
461 | $data = end($this); |
||
462 | |||
463 | return $data ? $this->createModel($data) : null; |
||
464 | } |
||
465 | |||
466 | /** |
||
467 | * Получение инстанса клиента |
||
468 | * |
||
469 | * @return Client |
||
470 | */ |
||
471 | protected function getClient() |
||
472 | { |
||
473 | return $this->client; |
||
474 | } |
||
475 | |||
476 | /** |
||
477 | * Получение текущего лимита коллекции |
||
478 | * |
||
479 | * @return int |
||
480 | */ |
||
481 | public function getLimit() |
||
482 | { |
||
483 | return $this->limit; |
||
484 | } |
||
485 | |||
486 | /** |
||
487 | * |
||
488 | * Получение текущего смещения коллекции |
||
489 | * |
||
490 | * @return int |
||
491 | */ |
||
492 | public function getOffset() |
||
493 | { |
||
494 | return $this->offset; |
||
495 | } |
||
496 | |||
497 | /** |
||
498 | * Общее количество страниц при заданом лимиите на страницу |
||
499 | * |
||
500 | * @return float |
||
501 | * @throws Exception |
||
502 | */ |
||
503 | public function getPages() { |
||
504 | return ceil($this->getFullCount() / $this->getLimit()); |
||
505 | } |
||
506 | } |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.