Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.77% covered (success)
96.77%
30 / 31
93.33% covered (success)
93.33%
14 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractObjectContainer
96.77% covered (success)
96.77%
30 / 31
93.33% covered (success)
93.33%
14 / 15
23
0.00% covered (danger)
0.00%
0 / 1
 offsetExists
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 offsetGet
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 offsetSet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 offsetUnset
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 current
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 next
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 key
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 valid
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 rewind
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 count
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 add
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
4
 jsonSerialize
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 objectClass
n/a
0 / 0
n/a
0 / 0
0
 objectProperty
n/a
0 / 0
n/a
0 / 0
0
 beforeObjectIsStored
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getObjectKey
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
1<?php
2
3declare(strict_types=1);
4
5namespace WsdlToPhp\PackageGenerator\Container;
6
7use WsdlToPhp\PackageGenerator\Generator\AbstractGeneratorAware;
8
9abstract class AbstractObjectContainer extends AbstractGeneratorAware implements \ArrayAccess, \Iterator, \Countable, \JsonSerializable
10{
11    public const PROPERTY_NAME = 'name';
12
13    protected array $objects = [];
14
15    protected int $offset = 0;
16
17    public function offsetExists($offset): bool
18    {
19        $element = array_slice($this->objects, $offset, 1);
20
21        return !empty($element);
22    }
23
24    /**
25     * @param mixed $offset
26     *
27     * @return mixed
28     */
29    #[\ReturnTypeWillChange]
30    public function offsetGet($offset)
31    {
32        $element = array_slice($this->objects, $offset, 1);
33
34        return $this->offsetExists($offset) ? array_shift($element) : null;
35    }
36
37    /**
38     * @param mixed $offset
39     * @param mixed $value
40     *
41     * @return mixed
42     */
43    #[\ReturnTypeWillChange]
44    public function offsetSet($offset, $value)
45    {
46        throw new \InvalidArgumentException('This method can\'t be used as object are stored with a string as array index', __LINE__);
47    }
48
49    #[\ReturnTypeWillChange]
50    public function offsetUnset($offset): void
51    {
52        if ($this->offsetExists($offset)) {
53            unset($this->objects[$this->getObjectKey($this->offsetGet($offset))]);
54        }
55    }
56
57    /**
58     * @return mixed
59     */
60    #[\ReturnTypeWillChange]
61    public function current()
62    {
63        $current = array_slice($this->objects, $this->offset, 1);
64
65        return array_shift($current);
66    }
67
68    #[\ReturnTypeWillChange]
69    public function next(): void
70    {
71        ++$this->offset;
72    }
73
74    #[\ReturnTypeWillChange]
75    public function key(): int
76    {
77        return $this->offset;
78    }
79
80    public function valid(): bool
81    {
82        return 0 < count(array_slice($this->objects, $this->offset, 1));
83    }
84
85    #[\ReturnTypeWillChange]
86    public function rewind(): void
87    {
88        $this->offset = 0;
89    }
90
91    #[\ReturnTypeWillChange]
92    public function count(): int
93    {
94        return count($this->objects);
95    }
96
97    public function add(object $object): self
98    {
99        $this->beforeObjectIsStored($object);
100        $this->objects[$this->getObjectKey($object)] = $object;
101
102        return $this;
103    }
104
105    public function get($value)
106    {
107        if (!is_scalar($value)) {
108            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__);
109        }
110
111        return array_key_exists($value, $this->objects) ? $this->objects[$value] : null;
112    }
113
114    public function jsonSerialize(): array
115    {
116        return array_values($this->objects);
117    }
118
119    /**
120     * Must return the object class name that this container is made to contain.
121     */
122    abstract protected function objectClass(): string;
123
124    /**
125     * Must return the object's property name that this container is using to store the object.
126     */
127    abstract protected function objectProperty(): string;
128
129    /**
130     * This method is called before the object has been stored.
131     *
132     * @throws \InvalidArgumentException
133     */
134    protected function beforeObjectIsStored(object $object): void
135    {
136        $objectClass = $this->objectClass();
137
138        if (!$object instanceof $objectClass) {
139            throw new \InvalidArgumentException(sprintf('Model of type "%s" does not match the object contained by this class: "%s"', get_class($object), $objectClass), __LINE__);
140        }
141    }
142
143    protected function getObjectKey(object $object)
144    {
145        $get = sprintf('get%s', ucfirst($this->objectProperty()));
146        if (!method_exists($object, $get)) {
147            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__);
148        }
149
150        $key = $object->{$get}();
151        if (!is_scalar($key)) {
152            throw new \InvalidArgumentException(sprintf('Property "%s" of "%s" must be scalar, "%s" returned', $this->objectProperty(), get_class($object), gettype($key)), __LINE__);
153        }
154
155        return $key;
156    }
157}