Completed
Push — master ( 44676f...b7bc18 )
by Jens
13:18
created

JsonObject::initialize()   C

Complexity

Conditions 7
Paths 20

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 33
ccs 20
cts 20
cp 1
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 20
nc 20
nop 1
crap 7
1
<?php
2
/**
3
 * @author @jayS-de <[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 1254
    public function __construct(array $data = [], $context = null)
29
    {
30 1254
        parent::__construct($data, $context);
31 1254
    }
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 925
    public function __call($method, $arguments)
49
    {
50 925
        $action = substr($method, 0, 3);
51 925
        $field = lcfirst(substr($method, 3));
52
53 925
        if (!$this->isValidField($field)) {
54 3
            if ($action == 'get' || $action == 'set') {
55 3
                throw new \BadMethodCallException(
56 3
                    sprintf(Message::UNKNOWN_FIELD, $field, $method, implode(', ', $arguments))
57
                );
58
            } else {
59
                throw new \BadMethodCallException(sprintf(Message::UNKNOWN_METHOD, $method, $field));
60
            }
61
        }
62
        switch ($action) {
63 923
            case 'get':
64 644
                return $this->get($field);
65 873
            case 'set':
66 872
                $this->set($field, isset($arguments[0]) ? $arguments[0] : null);
67 870
                return $this;
68
            default:
69 1
                throw new \BadMethodCallException(sprintf(Message::UNKNOWN_METHOD, $method, $field));
70
        }
71
    }
72
73
    public function __get($field)
74
    {
75
        if (!$this->isValidField($field)) {
76
            throw new \BadMethodCallException(
77
                sprintf(Message::UNKNOWN_FIELD, $field, 'get', $field)
78
            );
79
        }
80
        return $this->get($field);
81
    }
82
83
    /**
84
     * @param $field
85
     * @return bool
86
     */
87 3
    public function hasField($field)
88
    {
89 3
        return isset($this->typeData[$field]);
90
    }
91
92
    /**
93
     * @param string $field
94
     * @return bool
95
     * @internal
96
     */
97 925
    protected function isValidField($field)
98
    {
99 925
        if (isset($this->fieldDefinitions()[$field])) {
100 923
            return true;
101
        }
102 3
        return false;
103
    }
104
105
    /**
106
     * @param string $field
107
     * @return array
108
     * @internal
109
     */
110 923
    protected function fieldDefinition($field)
111
    {
112 923
        return $this->fieldDefinitions()[$field];
113
    }
114
115
    /**
116
     * @param string $field
117
     * @param string $key
118
     * @param $default
119
     * @return bool|string
120
     * @internal
121
     */
122 948
    protected function fieldDefinitionValue($field, $key, $default = false)
123
    {
124 948
        $field = $this->fieldDefinition($field);
125
126 948
        if (isset($field[$key])) {
127 921
            return $field[$key];
128
        }
129
130 939
        return $default;
131
    }
132
133
    /**
134
     * @param string $field
135
     * @return mixed
136
     * @internal
137
     */
138 669
    public function get($field)
139
    {
140 669
        return $this->getTyped($field);
141
    }
142
143 947
    protected function fieldDefinitionType($field)
144
    {
145 947
        return $this->fieldDefinitionValue($field, static::TYPE);
146
    }
147
    /**
148
     * @param string $field
149
     * @internal
150
     */
151 620
    protected function initialize($field)
152
    {
153 620
        $type = $this->fieldDefinitionType($field);
154 620
        if ($this->isPrimitive($type) !== false) {
155 579
            $value = $this->getRaw($field);
156 437
        } elseif ($this->isTypeableType($type)) {
157
            /**
158
             * @var TypeableInterface $type
159
             */
160 15
            $value = $type::ofTypeAndData(
161 15
                $this->fieldDefinitionValue($field, static::ELEMENT_TYPE),
162 15
                $this->getRaw($field, []),
163 15
                $this->getContextCallback()
164
            );
165 424
        } elseif ($this->isDeserializableType($type)) {
166
            /**
167
             * @var JsonDeserializeInterface $type
168
             */
169 390
            $value = $this->getRaw($field, null);
170 390
            if (!is_null($value)) {
171 390
                $value = $type::fromArray($value, $this->getContextCallback());
172
            }
173
        } else {
174 80
            $value = $this->getRaw($field);
175
        }
176 620
        if ($value instanceof ObjectTreeInterface) {
177 361
            $value->parentSet($this);
178 361
            $value->rootSet($this->rootGet());
179
        }
180 620
        $this->typeData[$field] = !is_null($value) ? $this->decorateField($field, $value) : null;
181
182 620
        $this->initialized[$field] = true;
183 620
    }
184
185 2
    public function isOptional($field)
186
    {
187 2
        return $this->fieldDefinitionValue($field, static::OPTIONAL, false);
188
    }
189
190 941
    protected function decorateField($field, $value)
191
    {
192 941
        if ($decorator = $this->fieldDefinitionValue($field, static::DECORATOR)) {
193 12
            $value = new $decorator($value);
194
        }
195
196 941
        return $value;
197
    }
198
199
    /**
200
     * @param string $field
201
     * @param mixed $value
202
     * @return $this
203
     * @internal
204
     */
205 873
    public function set($field, $value)
206
    {
207 873
        $type = $this->fieldDefinitionType($field);
208 873
        if (!$this->isValidType($type, $value)) {
209 1
            throw new \InvalidArgumentException(sprintf(Message::WRONG_TYPE, $field, $type));
210
        }
211 872
        if ($value === null && !$this->isOptional($field)) {
212 1
            throw new \InvalidArgumentException(sprintf(Message::EXPECTS_PARAMETER, $field, $type));
213
        }
214 871
        if ($value instanceof ContextAwareInterface) {
215 503
            $value->setContext($this->getContextCallback());
216
        }
217 871
        if ($value instanceof ObjectTreeInterface) {
218 434
            $value->parentSet($this);
219 434
            $value->rootSet($this->rootGet());
220
        }
221 871
        $this->typeData[$field] = $this->decorateField($field, $value);
222
223 871
        $this->initialized[$field] = true;
224
225 871
        return $this;
226
    }
227
}
228