Completed
Push — develop ( 61213d...79f8cb )
by Jens
09:21
created

Collection::setRawData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
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
    use ContextTrait;
16
17
    /**
18
     * @var string
19
     */
20
    protected $type;
21
22
    protected $pos = 0;
23
24
    protected $keys = [];
25
26
    protected $index = [];
27
28
    /**
29
     * @param array $data
30
     * @param Context|callable $context
31
     */
32 185
    final public function __construct(array $data = [], $context = null)
33
    {
34 185
        parent::__construct($data, $context);
35 185
        $this->indexData();
36 185
    }
37
38
    /**
39
     * @return string
40
     */
41 120
    public function getType()
42
    {
43 120
        return $this->type;
44
    }
45
46
    /**
47
     * @param string $type
48
     * @internal
49
     * @return $this
50
     */
51 18
    public function setType($type)
52
    {
53 18
        $this->type = $type;
54
55 18
        return $this;
56
    }
57
58 185
    protected function indexData()
59
    {
60 185
        $this->keys = array_keys($this->rawData);
61 185
        foreach ($this->rawData as $offset => $row) {
62 109
            $this->indexRow($offset, $row);
63 185
        }
64 185
    }
65
66
    /**
67
     * @param array $rawData
68
     * @internal
69
     * @return $this
70
     */
71 6
    public function setRawData(array $rawData)
72
    {
73 6
        parent::setRawData($rawData);
74 6
        $this->indexData();
75
76 6
        return $this;
77
    }
78
79
    /**
80
     * @param $offset
81
     * @param $row
82
     */
83 103
    protected function indexRow($offset, $row)
84
    {
85 103
    }
86
87
    /**
88
     * @param string $indexName
89
     * @param int $offset
90
     * @param $key
91
     */
92 51
    protected function addToIndex($indexName, $offset, $key)
93
    {
94 51
        $this->index[$indexName][$key] = $offset;
95 51
    }
96
97
    /**
98
     * @param $indexName
99
     * @param $key
100
     * @return mixed|null
101
     */
102 27
    public function getBy($indexName, $key)
103
    {
104 27
        if (isset($this->index[$indexName][$key])) {
105 25
            $key = $this->index[$indexName][$key];
106
107 25
            return $this->getAt($key);
108
        }
109 2
        return null;
110
    }
111
112 60
    public function add($object)
113
    {
114 60
        $this->setAt(null, $object);
115
116 59
        return $this;
117
    }
118
119
    /**
120
     * @param $offset
121
     * @internal
122
     */
123 73
    protected function initialize($offset)
124
    {
125 73
        $type = $this->getType();
126 73
        if ($this->isDeserializableType($type)) {
127
            /**
128
             * @var JsonDeserializeInterface $type
129
             */
130 72
            $value = $type::fromArray($this->getRaw($offset), $this->getContextCallback());
131 72
            if ($value instanceof ObjectTreeInterface) {
132 72
                $value->parentSet($this);
133 72
                $value->rootSet($this->rootGet());
134 72
            }
135 72
            $this->typeData[$offset] = $value;
136 72
        }
137 73
        $this->initialized[$offset] = true;
138 73
    }
139
140
    /**
141
     * @return array
142
     */
143
    public function toArray()
144
    {
145
        $values = [];
146
        foreach ($this->typeData as $key => $value) {
147
            if ($value instanceof JsonDeserializeInterface) {
148
                $values[$key] = $value->toArray();
149
            } else {
150
                $values[$key] = $value;
151
            }
152
        }
153
154
        return $values;
155
    }
156
157
    /**
158
     * @param $offset
159
     * @return mixed
160
     */
161 88
    public function getAt($offset)
162
    {
163 88
        return $this->getTyped($offset);
164
    }
165
166
    /**
167
     * @param $offset
168
     * @param mixed $default
169
     * @return array
170
     */
171 72
    protected function getRaw($offset, $default = [])
172
    {
173 72
        return parent::getRaw($offset, $default);
174
    }
175
176
    /**
177
     * @param $offset
178
     * @param $object
179
     * @return $this
180
     */
181 64
    public function setAt($offset, $object)
182
    {
183 64
        $type = $this->getType();
184 64
        if (!$this->isValidType($type, $object)) {
185 1
            throw new \InvalidArgumentException(sprintf(Message::WRONG_TYPE, $offset, $type));
186
        }
187
188 63
        if ($object instanceof ContextAwareInterface) {
189 59
            $object->setContext($this->getContextCallback());
190 59
        }
191 63
        if ($object instanceof ObjectTreeInterface) {
192 59
            $object->parentSet($this);
193 59
            $object->rootSet($this->rootGet());
194 59
        }
195 63
        if (is_null($offset)) {
196 61
            $this->typeData[] = $object;
197 61
            $offset = count($this->typeData) - 1;
198 61
        } else {
199 2
            $this->typeData[$offset] = $object;
200
        }
201 63
        $this->initialized[$offset] = true;
202 63
        if (!in_array($offset, $this->keys)) {
203 63
            $this->keys[] = $offset;
204 63
        }
205 63
        $this->indexRow($offset, $object);
206
207 63
        return $this;
208
    }
209
210
    /**
211
     * (PHP 5 &gt;= 5.1.0)<br/>
212
     * Count elements of an object
213
     * @link http://php.net/manual/en/countable.count.php
214
     * @return int The custom count as an integer.
215
     * </p>
216
     * <p>
217
     * The return value is cast to an integer.
218
     */
219 58
    public function count()
220
    {
221 58
        $rawKeys = array_keys($this->rawData);
222 58
        $typeKeys = array_keys($this->typeData);
223 58
        $keys = array_merge($rawKeys, $typeKeys);
224 58
        $uniqueKeys = array_unique($keys);
225 58
        return count($uniqueKeys);
226
    }
227
228
229
    /**
230
     * (PHP 5 &gt;= 5.0.0)<br/>
231
     * Return the current element
232
     * @link http://php.net/manual/en/iterator.current.php
233
     * @return mixed Can return any type.
234
     */
235 24
    public function current()
236
    {
237 24
        if (isset($this->keys[$this->pos])) {
238 24
            return $this->getAt($this->keys[$this->pos]);
239
        }
240
        return null;
241
    }
242
243
    /**
244
     * (PHP 5 &gt;= 5.0.0)<br/>
245
     * Move forward to next element
246
     * @link http://php.net/manual/en/iterator.next.php
247
     * @return void Any returned value is ignored.
248
     */
249 16
    public function next()
250
    {
251 16
        $this->pos++;
252 16
    }
253
254
    /**
255
     * (PHP 5 &gt;= 5.0.0)<br/>
256
     * Return the key of the current element
257
     * @link http://php.net/manual/en/iterator.key.php
258
     * @return mixed scalar on success, or null on failure.
259
     */
260 4
    public function key()
261
    {
262 4
        if (isset($this->keys[$this->pos])) {
263 4
            return $this->keys[$this->pos];
264
        }
265
        return null;
266
    }
267
268
    /**
269
     * (PHP 5 &gt;= 5.0.0)<br/>
270
     * Checks if current position is valid
271
     * @link http://php.net/manual/en/iterator.valid.php
272
     * @return boolean The return value will be casted to boolean and then evaluated.
273
     * Returns true on success or false on failure.
274
     */
275 17
    public function valid()
276
    {
277 17
        if (isset($this->keys[$this->pos])) {
278 16
            return $this->offsetExists($this->keys[$this->pos]);
279
        }
280 17
        return false;
281
    }
282
283
    /**
284
     * (PHP 5 &gt;= 5.0.0)<br/>
285
     * Rewind the Iterator to the first element
286
     * @link http://php.net/manual/en/iterator.rewind.php
287
     * @return void Any returned value is ignored.
288
     */
289 17
    public function rewind()
290
    {
291 17
        $this->pos = 0;
292 17
    }
293
294
    /**
295
     * (PHP 5 &gt;= 5.0.0)<br/>
296
     * Whether a offset exists
297
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
298
     * @param mixed $offset <p>
299
     * An offset to check for.
300
     * </p>
301
     * @return boolean true on success or false on failure.
302
     * </p>
303
     * <p>
304
     * The return value will be casted to boolean if non-boolean was returned.
305
     */
306 20
    public function offsetExists($offset)
307
    {
308 20
        return isset($this->rawData[$offset]) || isset($this->typeData[$offset]);
309
    }
310
311
    /**
312
     * (PHP 5 &gt;= 5.0.0)<br/>
313
     * Offset to retrieve
314
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
315
     * @param mixed $offset <p>
316
     * The offset to retrieve.
317
     * </p>
318
     * @return mixed Can return all value types.
319
     */
320 5
    public function offsetGet($offset)
321
    {
322 5
        return $this->getAt($offset);
323
    }
324
325
    /**
326
     * (PHP 5 &gt;= 5.0.0)<br/>
327
     * Offset to set
328
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
329
     * @param mixed $offset <p>
330
     * The offset to assign the value to.
331
     * </p>
332
     * @param mixed $value <p>
333
     * The value to set.
334
     * </p>
335
     * @return void
336
     */
337 3
    public function offsetSet($offset, $value)
338
    {
339 3
        $this->setAt($offset, $value);
340 3
    }
341
342
    /**
343
     * (PHP 5 &gt;= 5.0.0)<br/>
344
     * Offset to unset
345
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
346
     * @param mixed $offset <p>
347
     * The offset to unset.
348
     * </p>
349
     * @return void
350
     */
351 1
    public function offsetUnset($offset)
352
    {
353 1
        unset($this->rawData[$offset]);
354 1
        unset($this->typeData[$offset]);
355 1
    }
356
}
357