Completed
Push — feature/issue-101 ( 426b61...bb6cdd )
by Mikaël
49:18
created

AbstractObjectContainer::jsonSerialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace WsdlToPhp\PackageGenerator\Container;
4
5
use WsdlToPhp\PackageGenerator\Generator\AbstractGeneratorAware;
6
7
abstract class AbstractObjectContainer extends AbstractGeneratorAware implements \ArrayAccess, \Iterator, \Countable, \JsonSerializable
8
{
9
    /**
10
     * @var string
11
     */
12
    const PROPERTY_NAME = 'name';
13
    /**
14
     * @var array
15
     */
16
    protected $objects = array();
17
    /**
18
     * @var int
19
     */
20
    protected $offset = 0;
21
    /**
22
     * @param string $offset
23
     * @return bool
24
     */
25
    public function offsetExists($offset)
26
    {
27
        $element = array_slice($this->objects, $offset, 1);
28
        return !empty($element);
29
    }
30
    /**
31
     * @param int $offset
32
     * @return mixed
33
     */
34
    public function offsetGet($offset)
35
    {
36
        $element = array_slice($this->objects, $offset, 1);
37
        return $this->offsetExists($offset) ? array_shift($element) : null;
38
    }
39
    /**
40
     * @param string $offset
41
     * @param mixed $value
42
     * @return AbstractObjectContainer
43
     */
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
     * @param string $offset
50
     * @return AbstractObjectContainer
51
     */
52
    public function offsetUnset($offset)
53
    {
54
        if ($this->offsetExists($offset)) {
55
            unset($this->objects[$this->getObjectKey($this->offsetGet($offset))]);
56
        }
57
        return $this;
58
    }
59
    /**
60
     * @return mixed
61
     */
62
    public function current()
63
    {
64
        $current = array_slice($this->objects, $this->offset, 1);
65
        return array_shift($current);
66
    }
67
    /**
68
     * @return void
69
     */
70
    public function next()
71
    {
72
        $this->offset++;
73
    }
74
    /**
75
     * @return int
76
     */
77
    public function key()
78
    {
79
        return $this->offset;
80
    }
81
    /**
82
     * @return bool
83
     */
84
    public function valid()
85
    {
86
        return count(array_slice($this->objects, $this->offset, 1)) > 0;
87
    }
88
    /**
89
     * @return AbstractObjectContainer
90
     */
91
    public function rewind()
92
    {
93
        $this->offset = 0;
94
        return $this;
95
    }
96
    /**
97
     * @return int
98
     */
99
    public function count()
100
    {
101
        return count($this->objects);
102
    }
103
    /**
104
     * Must return the object class name that this container is made to contain
105
     * @return string
106
     */
107
    abstract protected function objectClass();
108
    /**
109
     * Must return the object class name that this container is made to contain
110
     * @return string
111
     */
112
    abstract protected function objectProperty();
113
    /**
114
     * This method is called before the object has been stored
115
     * @throws \InvalidArgumentException
116
     * @param mixed $object
117
     */
118
    protected function beforeObjectIsStored($object)
119
    {
120
        if (!is_object($object)) {
121
            throw new \InvalidArgumentException(sprintf('You must only pass object to this container (%s), "%s" passed as parameter!', get_called_class(), gettype($object)), __LINE__);
122
        }
123
        $instanceOf = $this->objectClass();
124
        if (get_class($object) !== $this->objectClass() && !$object instanceof $instanceOf) {
125
            throw new \InvalidArgumentException(sprintf('Model of type "%s" does not match the object contained by this class: "%s"', get_class($object), $this->objectClass()), __LINE__);
126
        }
127
    }
128
    /**
129
     * @param object $object
130
     * @throws \InvalidArgumentException
131
     * @return string
132
     */
133
    private function getObjectKey($object)
134
    {
135
        $get = sprintf('get%s', ucfirst($this->objectProperty()));
136
        if (!method_exists($object, $get)) {
137
            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__);
138
        }
139
        $key = $object->$get();
140
        if (!is_scalar($key)) {
141
            throw new \InvalidArgumentException(sprintf('Property "%s" of "%s" must be scalar, "%s" returned', $this->objectProperty(), get_class($object), gettype($key)), __LINE__);
142
        }
143
        return $key;
144
    }
145
    /**
146
     * @throws \InvalidArgumentException
147
     * @param mixed $object
148
     * @return AbstractObjectContainer
149
     */
150
    public function add($object)
151
    {
152
        $this->beforeObjectIsStored($object);
153
        $this->objects[$this->getObjectKey($object)] = $object;
154
        return $this;
155
    }
156
    /**
157
     * @param string $value
158
     * @return mixed
159
     */
160
    public function get($value)
161
    {
162
        if (!is_string($value) && !is_int($value)) {
163
            throw new \InvalidArgumentException(sprintf('Value "%s" can\'t be used to get an object from "%s"', var_export($value, true), get_class($this)), __LINE__);
164
        }
165
        return array_key_exists($value, $this->objects) ? $this->objects[$value] : null;
166
    }
167
    public function jsonSerialize()
168
    {
169
        return array_values($this->objects);
170
    }
171
}
172