JsonObject::__get()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 8
ccs 0
cts 5
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 6
1
<?php
2
/**
3
 * @author @jenschude <[email protected]>
4
 * @created: 27.01.15, 14:54
5
 */
6
7
namespace Commercetools\Core\Model\Common;
8
9
use Commercetools\Core\Error\Message;
10
11
/**
12
 * @package Commercetools\Core\Model\Common
13
 */
14
class JsonObject extends AbstractJsonDeserializeObject implements \JsonSerializable
15
{
16
    use ContextTrait;
17
18
    const TYPE = 'type';
19
    const OPTIONAL = 'optional';
20
    const INITIALIZED = 'initialized';
21
    const DECORATOR = 'decorator';
22
    const ELEMENT_TYPE = 'elementType';
23
24
    /**
25
     * @param array $data
26
     * @param Context|callable $context
27
     */
28 3094
    public function __construct(array $data = [], $context = null)
29
    {
30 3094
        parent::__construct($data, $context);
31 3094
    }
32
33
    /**
34
     * @return array
35
     * @internal
36
     */
37 1
    public function fieldDefinitions()
38
    {
39 1
        return [];
40
    }
41
42
    /**
43
     * @param $method
44
     * @param $arguments
45
     * @return $this|bool|mixed
46
     * @internal
47
     */
48 2354
    public function __call($method, $arguments)
49
    {
50 2354
        $action = substr($method, 0, 3);
51 2354
        $field = lcfirst(substr($method, 3));
52 2354
        if ($action == 'get' || $action == 'set') {
53 2352
            $validField = $this->isValidField($field);
54
        } else {
55 2
            if ($validField = $this->isValidField($method)) {
56 1
                $field = $method;
57 1
                $action = 'get';
58
            }
59
        }
60
61 2354
        if (!$validField) {
62 4
            if ($action == 'get' || $action == 'set') {
63 3
                throw new \BadMethodCallException(
64 3
                    sprintf(Message::UNKNOWN_FIELD, $field, $method, implode(', ', $arguments))
65
                );
66
            } else {
67 1
                throw new \BadMethodCallException(sprintf(Message::UNKNOWN_METHOD, $method, $field));
68
            }
69
        }
70 2351
        switch ($action) {
71 2351
            case 'get':
72 1385
                return $this->get($field);
73 2287
            case 'set':
74 2287
                $this->set($field, isset($arguments[0]) ? $arguments[0] : null);
75 2285
                return $this;
76
            default:
77
                throw new \BadMethodCallException(sprintf(Message::UNKNOWN_METHOD, $method, $field));
78
        }
79
    }
80
81
    public function __get($field)
82
    {
83
        if (!$this->isValidField($field)) {
84
            throw new \BadMethodCallException(
85
                sprintf(Message::UNKNOWN_FIELD, $field, 'get', $field)
86
            );
87
        }
88
        return $this->get($field);
89
    }
90
91
    /**
92
     * @param $field
93
     * @return bool
94
     */
95 3
    public function hasField($field)
96
    {
97 3
        return isset($this->typeData[$field]);
98
    }
99
100
    /**
101
     * @param string $field
102
     * @return bool
103
     * @internal
104
     */
105 2354
    protected function isValidField($field)
106
    {
107 2354
        if (isset($this->fieldDefinitions()[$field])) {
108 2351
            return true;
109
        }
110 4
        return false;
111
    }
112
113
    /**
114
     * @param string $field
115
     * @return array
116
     * @internal
117
     */
118 2352
    protected function fieldDefinition($field)
119
    {
120 2352
        return $this->fieldDefinitions()[$field];
121
    }
122
123
    /**
124
     * @param string $field
125
     * @param string $key
126
     * @param $default
127
     * @return bool|string
128
     * @internal
129
     */
130 2377
    protected function fieldDefinitionValue($field, $key, $default = false)
131
    {
132 2377
        $field = $this->fieldDefinition($field);
133
134 2377
        if (isset($field[$key])) {
135 2350
            return $field[$key];
136
        }
137
138 2366
        return $default;
139
    }
140
141
    /**
142
     * @param string $field
143
     * @return mixed
144
     * @internal
145
     */
146 1410
    public function get($field)
147
    {
148 1410
        return $this->getTyped($field);
149
    }
150
151 2376
    protected function fieldDefinitionType($field)
152
    {
153 2376
        return $this->fieldDefinitionValue($field, static::TYPE);
154
    }
155
    /**
156
     * @param string $field
157
     * @internal
158
     */
159 859
    protected function initialize($field)
160
    {
161 859
        $type = $this->fieldDefinitionType($field);
162 859
        if ($this->isPrimitive($type) !== false) {
163 817
            $value = $this->getRaw($field);
164 635
        } elseif ($this->isTypeableType($type)) {
165
            /**
166
             * @var TypeableInterface $type
167
             */
168 15
            $value = $type::ofTypeAndData(
169 15
                $this->fieldDefinitionValue($field, static::ELEMENT_TYPE),
170 15
                $this->getRaw($field, []),
171 15
                $this->getContextCallback()
172
            );
173 622
        } elseif ($this->isDeserializableType($type)) {
174
            /**
175
             * @var JsonDeserializeInterface $type
176
             */
177 579
            $value = $this->getRaw($field, null);
178 579
            if (!is_null($value)) {
179 579
                $value = $type::fromArray($value, $this->getContextCallback());
180
            }
181
        } else {
182 109
            $value = $this->getRaw($field);
183
        }
184 859
        if ($value instanceof ObjectTreeInterface) {
185 540
            $value->parentSet($this);
186 540
            $value->rootSet($this->rootGet());
187
        }
188 859
        $this->typeData[$field] = !is_null($value) ? $this->decorateField($field, $value) : null;
189
190 859
        $this->initialized[$field] = true;
191 859
    }
192
193 2
    public function isOptional($field)
194
    {
195 2
        return $this->fieldDefinitionValue($field, static::OPTIONAL, false);
196
    }
197
198 2368
    protected function decorateField($field, $value)
199
    {
200 2368
        if ($decorator = $this->fieldDefinitionValue($field, static::DECORATOR)) {
201 22
            $value = new $decorator($value);
202
        }
203
204 2368
        return $value;
205
    }
206
207
    /**
208
     * @param string $field
209
     * @param mixed $value
210
     * @return $this
211
     * @internal
212
     */
213 2288
    public function set($field, $value)
214
    {
215 2288
        $type = $this->fieldDefinitionType($field);
216 2288
        if (!$this->isValidType($type, $value)) {
217 1
            throw new \InvalidArgumentException(sprintf(Message::WRONG_TYPE, $field, $type));
218
        }
219 2287
        if ($value === null && !$this->isOptional($field)) {
220 1
            throw new \InvalidArgumentException(sprintf(Message::EXPECTS_PARAMETER, $field, $type));
221
        }
222 2286
        if ($value instanceof ContextAwareInterface) {
223 707
            $value->setContext($this->getContextCallback());
224
        }
225 2286
        if ($value instanceof ObjectTreeInterface) {
226 625
            $value->parentSet($this);
227 625
            $value->rootSet($this->rootGet());
228
        }
229 2286
        $this->typeData[$field] = $this->decorateField($field, $value);
230
231 2286
        $this->initialized[$field] = true;
232
233 2286
        return $this;
234
    }
235
}
236