Collection::getOffset()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 3
c 0
b 0
f 0
ccs 0
cts 0
cp 0
rs 10
cc 1
eloc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace Palladium\Component;
4
5
use Palladium\Contract\HasId;
6
7
/**
8
 * Class for handling sets of domain entities.
9
 * To use it, it needs to be extended with `buildEntity()` method implemented. This method
10
 * must return an instance of that domain entity.
11
 */
12
13
14
abstract class Collection implements \Iterator, \ArrayAccess, \Countable
15
{
16
17
    abstract protected function buildEntity(): HasId;
18
19
    private $pool = [];
20
    private $indexed = [];
21
22
    private $map = [];
23
24
    private $position = 0;
25
26
    private $total = 0;
27
    private $offset = 0;
28
    private $limit = 10;
29
30
31
    /**
32
     * Add new domain entity, that is constructed using array as values. Each array key
33
     * will be attempted top match with entity's setter method and provided with
34
     * the respective array value. It returns the newly created entity.
35
     *
36
     * @param array $parameters
37
     *
38
     * @return HasId
39
     */
40 1
    public function addBlueprint(array $parameters)
41
    {
42 1
        $instance = $this->buildEntity();
43 1
        $this->populateEntity($instance, $parameters);
44
45 1
        $this->addEntity($instance);
46
47 1
        return $instance;
48
    }
49
50
51
    /** code that does the actual population of data from the given array in blueprint */
52 1
    private function populateEntity($instance, array $parameters)
53
    {
54 1
        foreach ($parameters as $key => $value) {
55 1
            $method = 'set' . str_replace('_', '', $key);
56 1
            if (method_exists($instance, $method)) {
57 1
                $instance->{$method}($value);
58
            }
59
        }
60 1
    }
61
62
63
    /**
64
     * Method for adding already existing domain entity to the collection.
65
     *
66
     * @param HasId $entity
67
     */
68 13
    public function addEntity(HasId $entity, $key = null)
69
    {
70
71 13
        if (is_null($key) === false) {
72 2
            $this->replaceEntity($entity, $key);
73 2
            return;
74
        }
75
76 12
        $entityId = $entity->getId();
77
78 12
        $this->pool[] = $entity;
79
80 12
        $this->indexed[$entityId] = $entity;
81 12
        $this->map[$entityId] = $this->retrieveLastPoolKey();
82 12
    }
83
84
85 1
    public function removeEntityById($key)
86
    {
87 1
        unset($this->pool[$this->map[$key]]);
88 1
        $this->removeIndexEntry($key);
89 1
        $this->pool = array_values($this->pool);
90 1
    }
91
92
93 2
    private function replaceEntity(HasId $entity, $key)
94
    {
95 2
        if (isset($this->pool[$key])) {
96 1
            $this->removeIndexEntry($this->pool[$key]->getId());
97
        }
98
99 2
        $entityId = $entity->getId();
100
101 2
        $this->pool[$key] = $entity;
102 2
        $this->indexed[$entityId] = $entity;
103 2
        $this->map[$entityId] = $key;
104 2
    }
105
106
107 5
    private function removeIndexEntry($key)
108
    {
109 5
        unset($this->indexed[$key]);
110 5
        unset($this->map[$key]);
111 5
    }
112
113
114 12
    private function retrieveLastPoolKey()
115
    {
116 12
        end($this->pool);
117 12
        return key($this->pool);
118
    }
119
120
121
    /**
122
     * Method for getting an ordered list of IDs for items in the collection.
123
     *
124
     * @return array
125
     */
126 5
    public function getIds()
127
    {
128 5
        $keys = array_keys($this->indexed);
129 5
        sort($keys);
130 5
        return $keys;
131
    }
132
133
134
    /**
135
     * Replaces all of the domain entities with a content of some other collection
136
     *
137
     * @param Collection $replacement
138
     */
139 1
    public function replaceWith(Collection $replacement)
140
    {
141 1
        $this->pool = [];
142 1
        $this->map = [];
143 1
        $this->indexed = [];
144
145 1
        foreach ($replacement as $entity) {
146 1
            $this->addEntity($entity);
147
        }
148 1
    }
149
150
151
    /**
152
     * Removes an entity from collection.
153
     *
154
     * @param HasId $entity
155
     */
156 3
    public function removeEntity(HasId $entity)
157
    {
158 3
        $key = $entity->getId();
159
160 3
        if ($key !== null) {
161 3
            unset($this->pool[$this->map[$key]]);
162 3
            $this->removeIndexEntry($key);
163
        }
164 3
    }
165
166
167
    /**
168
     * Removes all of the content of the collection and resets it to pristine state.
169
     */
170 1
    public function purge()
171
    {
172 1
        $this->pool = [];
173 1
        $this->indexed = [];
174 1
        $this->map = [];
175 1
        $this->position = 0;
176 1
    }
177
178
179
    // implementing Countable
180 2
    public function count()
181
    {
182 2
        return count($this->pool);
183
    }
184
185
186
    // implementing Iterator
187 2
    public function rewind()
188
    {
189 2
        $this->position = 0;
190 2
    }
191
192
193 2
    public function current()
194
    {
195 2
        return $this->pool[$this->position];
196
    }
197
198
199
    /**
200
     * @codeCoverageIgnore
201
     */
202
    public function key()
203
    {
204
        return $this->position;
205
    }
206
207
208 2
    public function next()
209
    {
210 2
        ++$this->position;
211 2
    }
212
213
214 2
    public function valid()
215
    {
216 2
        return isset($this->pool[$this->position]);
217
    }
218
219
220
    // implementing ArrayAccess
221 10
    public function offsetSet($offset, $value)
222
    {
223 10
        $this->addEntity($value, $offset);
224 10
    }
225
226
227 1
    public function offsetExists($offset)
228
    {
229 1
        return isset($this->pool[$offset]);
230
    }
231
232
233 3
    public function offsetUnset($offset)
234
    {
235 3
        $this->removeEntity($this->pool[$offset]);
236 3
    }
237
238
239 5
    public function offsetGet($offset)
240
    {
241 5
        if (isset($this->pool[$offset])) {
242 5
            return $this->pool[$offset];
243
        }
244
245 2
        return null;
246
    }
247
248
249
    // pagination
250
251 1
    public function setOffset($offset)
252
    {
253 1
        $data = (int) $offset;
254
255 1
        if ($data < 0) {
256 1
            $data = 0;
257
        }
258
259 1
        $this->offset = $data;
260 1
    }
261
262
263
    /**
264
     * @codeCoverageIgnore
265
     */
266
    public function getOffset()
267
    {
268
        return $this->offset;
269
    }
270
271
272 1
    public function setLimit($limit)
273
    {
274 1
        $data = (int) $limit;
275
276 1
        if ($data < 0) {
277 1
            $data = 0;
278
        }
279
280 1
        $this->limit = $data;
281 1
    }
282
283
284
    /**
285
     * @codeCoverageIgnore
286
     */
287
    public function getLimit()
288
    {
289
        return $this->limit;
290
    }
291
292
293 1
    public function setTotal($total)
294
    {
295 1
        $data = (int) $total;
296
297 1
        if ($data < 0) {
298 1
            $data = 0;
299
        }
300
301 1
        $this->total = $data;
302 1
    }
303
304
305
    /**
306
     * @codeCoverageIgnore
307
     */
308
    public function getTotal()
309
    {
310
        return $this->total;
311
    }
312
}
313