EntityCollection   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 13
eloc 33
dl 0
loc 96
c 0
b 0
f 0
rs 10
ccs 33
cts 33
cp 1

8 Methods

Rating   Name   Duplication   Size   Complexity  
A rewind() 0 3 1
A valid() 0 3 2
A current() 0 5 1
A key() 0 3 1
A loadPage() 0 16 3
A count() 0 3 1
A next() 0 6 3
A __construct() 0 12 1
1
<?php
2
3
// ---------------------------------------------------------------------
4
//
5
//  Copyright (C) 2018-2024 Artem Rodygin
6
//
7
//  You should have received a copy of the MIT License along with
8
//  this file. If not, see <https://opensource.org/licenses/MIT>.
9
//
10
// ---------------------------------------------------------------------
11
12
namespace Linode;
13
14
use Psr\Http\Message\ResponseInterface;
15
16
/**
17
 * A collection of Linode entities.
18
 */
19
final class EntityCollection implements \Countable, \Iterator
20
{
21
    /** @var callable */
22
    private $apiHandler;
23
24
    /** @var callable */
25
    private $entityFactory;
26
27
    /** @var int Current page (one-based index). */
28
    private int $currentPage;
29
30
    /** @var int Current entity (zero-based index). */
31
    private int $currentEntity;
32
33
    /** @var int Total number of entities. */
34
    private int $totalEntities;
35
36
    /** @var int Number of loaded entities. */
37
    private int $loadedEntities;
38
39
    /** @var null|\SplFixedArray Entities (JSON objects). */
40
    private ?\SplFixedArray $entitiesData;
41
42
    /**
43
     * @param callable $apiHandler    Function to make an API call.
44
     * @param callable $entityFactory Function to create entities using JSON (@see AbstractRepository::jsonToEntity).
45
     */
46 2
    public function __construct(callable $apiHandler, callable $entityFactory)
47
    {
48 2
        $this->apiHandler    = $apiHandler;
49 2
        $this->entityFactory = $entityFactory;
50
51 2
        $this->currentPage    = 0;
52 2
        $this->currentEntity  = 0;
53 2
        $this->totalEntities  = 0;
54 2
        $this->loadedEntities = 0;
55 2
        $this->entitiesData   = null;
56
57 2
        $this->loadPage();
58
    }
59
60 1
    public function count(): int
61
    {
62 1
        return $this->totalEntities;
63
    }
64
65 1
    public function key(): int
66
    {
67 1
        return $this->currentEntity;
68
    }
69
70 1
    public function current(): mixed
71
    {
72 1
        $json = $this->entitiesData[$this->currentEntity];
73
74 1
        return ($this->entityFactory)($json);
75
    }
76
77 1
    public function valid(): bool
78
    {
79 1
        return $this->currentEntity >= 0 && $this->currentEntity < $this->totalEntities;
80
    }
81
82 1
    public function next(): void
83
    {
84 1
        $this->currentEntity++;
85
86 1
        if ($this->currentEntity >= $this->loadedEntities && $this->loadedEntities < $this->totalEntities) {
87 1
            $this->loadPage();
88
        }
89
    }
90
91 1
    public function rewind(): void
92
    {
93 1
        $this->currentEntity = 0;
94
    }
95
96
    /**
97
     * Loads next page of data.
98
     */
99 1
    private function loadPage(): void
100
    {
101
        /** @var ResponseInterface $response */
102 1
        $response = ($this->apiHandler)(++$this->currentPage);
103 1
        $contents = $response->getBody()->getContents();
104 1
        $json     = json_decode($contents, true);
105
106
        // Whether we are loading for the first time.
107 1
        if (null === $this->entitiesData) {
108 1
            $this->totalEntities = $json['results'] ?? 0;
109
110 1
            $this->entitiesData = new \SplFixedArray($this->totalEntities);
111
        }
112
113 1
        foreach ($json['data'] ?? [] as $entry) {
114 1
            $this->entitiesData[$this->loadedEntities++] = $entry;
115
        }
116
    }
117
}
118