Completed
Push — develop ( c6f9f9...59e20d )
by Jens
09:32
created

Collection::getById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * @author @jayS-de <[email protected]>
4
 */
5
6
namespace Commercetools\Core\Model\Common;
7
8
use Commercetools\Core\Error\Message;
9
10
/**
11
 * @package Commercetools\Core\Model\Common
12
 */
13
class Collection extends AbstractJsonDeserializeObject implements \Iterator, \JsonSerializable, \Countable, \ArrayAccess
14
{
15
    const ID = 'id';
16
    use ContextTrait;
17
18
    /**
19
     * @var string
20
     */
21
    protected $type;
22
23
    protected $pos = 0;
24
25
    protected $keys = [];
26
27
    protected $index = [];
28
29
    /**
30
     * @param array $data
31
     * @param Context|callable $context
32
     */
33 294
    final public function __construct(array $data = [], $context = null)
34
    {
35 294
        parent::__construct($data, $context);
36 294
        $this->indexData();
37 294
    }
38
39
    /**
40
     * @return string
41
     */
42 228
    public function getType()
43
    {
44 228
        return $this->type;
45
    }
46
47
    /**
48
     * @param string $type
49
     * @internal
50
     * @return $this
51
     */
52 18
    public function setType($type)
53
    {
54 18
        $this->type = $type;
55
56 18
        return $this;
57
    }
58
59 294
    protected function indexData()
60
    {
61 294
        $this->keys = array_keys($this->rawData);
62 294
        foreach ($this->rawData as $offset => $row) {
63 173
            $this->indexRow($offset, $row);
64
        }
65 294
    }
66
67
    /**
68
     * @param array $rawData
69
     * @internal
70
     * @return $this
71
     */
72 6
    public function setRawData(array $rawData)
73
    {
74 6
        parent::setRawData($rawData);
75 6
        $this->indexData();
76
77 6
        return $this;
78
    }
79
80
    /**
81
     * @param string $indexName
82
     * @param int $offset
83
     * @param $key
84
     */
85 257
    protected function addToIndex($indexName, $offset, $key)
86
    {
87 257
        if (!is_null($key)) {
88 153
            $this->index[$indexName][$key] = $offset;
89
        }
90 257
    }
91
92 165 View Code Duplication
    protected function indexRow($offset, $row)
0 ignored issues
show
Duplication introduced by
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.

Loading history...
93
    {
94 165
        $id = null;
95 165
        if ($row instanceof Resource) {
96 1
            $id = $row->getId();
97 164
        } elseif (is_array($row)) {
98 86
            $id = isset($row[static::ID]) ? $row[static::ID] : null;
99
        }
100 165
        $this->addToIndex(static::ID, $offset, $id);
101 165
    }
102
103
    /**
104
     * @param $id
105
     * @return static
106
     */
107 24
    public function getById($id)
108
    {
109 24
        return $this->getBy(static::ID, $id);
110
    }
111
112
    /**
113
     * @param $indexName
114
     * @param $key
115
     * @return mixed|null
116
     */
117 45
    public function getBy($indexName, $key)
118
    {
119 45
        if (isset($this->index[$indexName][$key])) {
120 43
            $key = $this->index[$indexName][$key];
121
122 43
            return $this->getAt($key);
123
        }
124 4
        return null;
125
    }
126
127 154
    public function add($object)
128
    {
129 154
        $this->setAt(null, $object);
130
131 153
        return $this;
132
    }
133
134
    /**
135
     * @param $offset
136
     * @internal
137
     */
138 137
    protected function initialize($offset)
139
    {
140 137
        $type = $this->getType();
141 137
        if ($this->isDeserializableType($type)) {
142
            /**
143
             * @var JsonDeserializeInterface $type
144
             */
145 136
            $value = $type::fromArray($this->getRaw($offset), $this->getContextCallback());
146 136
            if ($value instanceof ObjectTreeInterface) {
147 136
                $value->parentSet($this);
148 136
                $value->rootSet($this->rootGet());
149
            }
150 136
            $this->typeData[$offset] = $value;
151
        }
152 137
        $this->initialized[$offset] = true;
153 137
    }
154
155
    /**
156
     * @return array
157
     */
158
    public function toArray()
159
    {
160
        $values = [];
161
        foreach ($this->typeData as $key => $value) {
162
            if ($value instanceof JsonDeserializeInterface) {
163
                $values[$key] = $value->toArray();
164
            } else {
165
                $values[$key] = $value;
166
            }
167
        }
168
169
        return $values;
170
    }
171
172
    /**
173
     * @param $offset
174
     * @return mixed
175
     */
176 152
    public function getAt($offset)
177
    {
178 152
        return $this->getTyped($offset);
179
    }
180
181
    /**
182
     * @param $offset
183
     * @param mixed $default
184
     * @return array
185
     */
186 136
    protected function getRaw($offset, $default = [])
187
    {
188 136
        return parent::getRaw($offset, $default);
189
    }
190
191
    /**
192
     * @param $offset
193
     * @param $object
194
     * @return $this
195
     */
196 158
    public function setAt($offset, $object)
197
    {
198 158
        $type = $this->getType();
199 158
        if (!$this->isValidType($type, $object)) {
200 1
            throw new \InvalidArgumentException(sprintf(Message::WRONG_TYPE, $offset, $type));
201
        }
202
203 157
        if ($object instanceof ContextAwareInterface) {
204 152
            $object->setContext($this->getContextCallback());
205
        }
206 157
        if ($object instanceof ObjectTreeInterface) {
207 152
            $object->parentSet($this);
208 152
            $object->rootSet($this->rootGet());
209
        }
210 157
        if (is_null($offset)) {
211 155
            $this->typeData[] = $object;
212 155
            $offset = count($this->typeData) - 1;
213
        } else {
214 3
            $this->typeData[$offset] = $object;
215
        }
216 157
        $this->initialized[$offset] = true;
217 157
        if (!in_array($offset, $this->keys)) {
218 157
            $this->keys[] = $offset;
219
        }
220 157
        $this->indexRow($offset, $object);
221
222 157
        return $this;
223
    }
224
225
    /**
226
     * (PHP 5 &gt;= 5.1.0)<br/>
227
     * Count elements of an object
228
     * @link http://php.net/manual/en/countable.count.php
229
     * @return int The custom count as an integer.
230
     * </p>
231
     * <p>
232
     * The return value is cast to an integer.
233
     */
234 81
    public function count()
235
    {
236 81
        $rawKeys = array_keys($this->rawData);
237 81
        $typeKeys = array_keys($this->typeData);
238 81
        $keys = array_merge($rawKeys, $typeKeys);
239 81
        $uniqueKeys = array_unique($keys);
240 81
        return count($uniqueKeys);
241
    }
242
243
244
    /**
245
     * (PHP 5 &gt;= 5.0.0)<br/>
246
     * Return the current element
247
     * @link http://php.net/manual/en/iterator.current.php
248
     * @return mixed Can return any type.
249
     */
250 78
    public function current()
251
    {
252 78
        if (isset($this->keys[$this->pos])) {
253 78
            return $this->getAt($this->keys[$this->pos]);
254
        }
255
        return null;
256
    }
257
258
    /**
259
     * (PHP 5 &gt;= 5.0.0)<br/>
260
     * Move forward to next element
261
     * @link http://php.net/manual/en/iterator.next.php
262
     * @return void Any returned value is ignored.
263
     */
264 18
    public function next()
265
    {
266 18
        $this->pos++;
267 18
    }
268
269
    /**
270
     * (PHP 5 &gt;= 5.0.0)<br/>
271
     * Return the key of the current element
272
     * @link http://php.net/manual/en/iterator.key.php
273
     * @return mixed scalar on success, or null on failure.
274
     */
275 4
    public function key()
276
    {
277 4
        if (isset($this->keys[$this->pos])) {
278 4
            return $this->keys[$this->pos];
279
        }
280
        return null;
281
    }
282
283
    /**
284
     * (PHP 5 &gt;= 5.0.0)<br/>
285
     * Checks if current position is valid
286
     * @link http://php.net/manual/en/iterator.valid.php
287
     * @return boolean The return value will be casted to boolean and then evaluated.
288
     * Returns true on success or false on failure.
289
     */
290 20
    public function valid()
291
    {
292 20
        if (isset($this->keys[$this->pos])) {
293 18
            return $this->offsetExists($this->keys[$this->pos]);
294
        }
295 20
        return false;
296
    }
297
298
    /**
299
     * (PHP 5 &gt;= 5.0.0)<br/>
300
     * Rewind the Iterator to the first element
301
     * @link http://php.net/manual/en/iterator.rewind.php
302
     * @return void Any returned value is ignored.
303
     */
304 20
    public function rewind()
305
    {
306 20
        $this->pos = 0;
307 20
    }
308
309
    /**
310
     * (PHP 5 &gt;= 5.0.0)<br/>
311
     * Whether a offset exists
312
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
313
     * @param mixed $offset <p>
314
     * An offset to check for.
315
     * </p>
316
     * @return boolean true on success or false on failure.
317
     * </p>
318
     * <p>
319
     * The return value will be casted to boolean if non-boolean was returned.
320
     */
321 23
    public function offsetExists($offset)
322
    {
323 23
        return isset($this->rawData[$offset]) || isset($this->typeData[$offset]);
324
    }
325
326
    /**
327
     * (PHP 5 &gt;= 5.0.0)<br/>
328
     * Offset to retrieve
329
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
330
     * @param mixed $offset <p>
331
     * The offset to retrieve.
332
     * </p>
333
     * @return mixed Can return all value types.
334
     */
335 5
    public function offsetGet($offset)
336
    {
337 5
        return $this->getAt($offset);
338
    }
339
340
    /**
341
     * (PHP 5 &gt;= 5.0.0)<br/>
342
     * Offset to set
343
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
344
     * @param mixed $offset <p>
345
     * The offset to assign the value to.
346
     * </p>
347
     * @param mixed $value <p>
348
     * The value to set.
349
     * </p>
350
     * @return void
351
     */
352 3
    public function offsetSet($offset, $value)
353
    {
354 3
        $this->setAt($offset, $value);
355 3
    }
356
357
    /**
358
     * (PHP 5 &gt;= 5.0.0)<br/>
359
     * Offset to unset
360
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
361
     * @param mixed $offset <p>
362
     * The offset to unset.
363
     * </p>
364
     * @return void
365
     */
366 1
    public function offsetUnset($offset)
367
    {
368 1
        unset($this->rawData[$offset]);
369 1
        unset($this->typeData[$offset]);
370 1
    }
371
}
372