Passed
Push — develop ( 0a8b55...80d7ca )
by Mikaël
06:50
created

AbstractObjectContainer::getObjectKey()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 0
Metric Value
cc 3
eloc 7
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 13
ccs 7
cts 8
cp 0.875
crap 3.0175
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WsdlToPhp\PackageGenerator\Container;
6
7
use ArrayAccess;
8
use Countable;
9
use InvalidArgumentException;
10
use Iterator;
11
use JsonSerializable;
12
use WsdlToPhp\PackageGenerator\Generator\AbstractGeneratorAware;
13
14
abstract class AbstractObjectContainer extends AbstractGeneratorAware implements ArrayAccess, Iterator, Countable, JsonSerializable
15
{
16
    public const PROPERTY_NAME = 'name';
17
18
    protected array $objects = [];
19
20
    protected int $offset = 0;
21
22 20
    public function offsetExists($offset): bool
23
    {
24 20
        $element = array_slice($this->objects, $offset, 1);
25
26 20
        return !empty($element);
27
    }
28
29 20
    public function offsetGet($offset)
30
    {
31 20
        $element = array_slice($this->objects, $offset, 1);
32
33 20
        return $this->offsetExists($offset) ? array_shift($element) : null;
34
    }
35
36 2
    public function offsetSet($offset, $value)
37
    {
38 2
        throw new InvalidArgumentException('This method can\'t be used as object are stored with a string as array index', __LINE__);
39
    }
40
41 2
    public function offsetUnset($offset)
42
    {
43 2
        if ($this->offsetExists($offset)) {
44 2
            unset($this->objects[$this->getObjectKey($this->offsetGet($offset))]);
45
        }
46 2
    }
47
48 320
    public function current()
49
    {
50 320
        $current = array_slice($this->objects, $this->offset, 1);
51
52 320
        return array_shift($current);
53
    }
54
55 320
    public function next()
56
    {
57 320
        ++$this->offset;
58 320
    }
59
60 104
    public function key()
61
    {
62 104
        return $this->offset;
63
    }
64
65 348
    public function valid(): bool
66
    {
67 348
        return 0 < count(array_slice($this->objects, $this->offset, 1));
68
    }
69
70 348
    public function rewind()
71
    {
72 348
        $this->offset = 0;
73 348
    }
74
75 336
    public function count()
76
    {
77 336
        return count($this->objects);
78
    }
79
80 510
    public function add(object $object): self
81
    {
82 510
        $this->beforeObjectIsStored($object);
83 498
        $this->objects[$this->getObjectKey($object)] = $object;
84
85 496
        return $this;
86
    }
87
88 552
    public function get($value)
89
    {
90 552
        if (!is_scalar($value)) {
91 2
            throw new InvalidArgumentException(sprintf('Value "%s" can\'t be used to get an object from "%s"', is_object($value) ? get_class($value) : var_export($value, true), get_class($this)), __LINE__);
92
        }
93
94 550
        return array_key_exists($value, $this->objects) ? $this->objects[$value] : null;
95
    }
96
97 4
    public function jsonSerialize(): array
98
    {
99 4
        return array_values($this->objects);
100
    }
101
102
    /**
103
     * Must return the object class name that this container is made to contain.
104
     */
105
    abstract protected function objectClass(): string;
106
107
    /**
108
     * Must return the object class name that this container is made to contain.
109
     */
110
    abstract protected function objectProperty(): string;
111
112
    /**
113
     * This method is called before the object has been stored.
114
     *
115
     * @param mixed $object
116
     *
117
     * @throws InvalidArgumentException
118
     */
119 510
    protected function beforeObjectIsStored(object $object): void
120
    {
121 510
        $objectClass = $this->objectClass();
122
123 510
        if (!$object instanceof $objectClass) {
124 12
            throw new InvalidArgumentException(sprintf('Model of type "%s" does not match the object contained by this class: "%s"', get_class($object), $objectClass), __LINE__);
125
        }
126 498
    }
127
128 498
    protected function getObjectKey(object $object)
129
    {
130 498
        $get = sprintf('get%s', ucfirst($this->objectProperty()));
131 498
        if (!method_exists($object, $get)) {
132 2
            throw new InvalidArgumentException(sprintf('Method "%s" is required in "%s" in order to be stored in "%s"', $get, get_class($object), get_class($this)), __LINE__);
133
        }
134
135 496
        $key = $object->{$get}();
136 496
        if (!is_scalar($key)) {
137
            throw new InvalidArgumentException(sprintf('Property "%s" of "%s" must be scalar, "%s" returned', $this->objectProperty(), get_class($object), gettype($key)), __LINE__);
138
        }
139
140 496
        return $key;
141
    }
142
}
143