Test Failed
Push — master ( e3b5b4...43c430 )
by Kirill
04:55
created

ValueObject   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 262
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 262
rs 10
c 0
b 0
f 0
wmc 30
lcom 1
cbo 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A get() 0 8 3
A set() 0 13 6
A setAttributes() 0 8 2
A getAttributes() 0 4 1
A toArray() 0 4 1
A toObject() 0 4 1
A jsonSerialize() 0 12 3
A toJson() 0 4 1
A offsetExists() 0 4 1
A offsetGet() 0 4 1
A offsetSet() 0 4 1
A offsetUnset() 0 4 1
A __call() 0 6 2
A __get() 0 4 1
A __set() 0 4 1
A __isset() 0 4 1
A __unset() 0 4 1
A __debugInfo() 0 4 1
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\SDL\Frontend;
11
12
/**
13
 * Class ValueObject
14
 */
15
class ValueObject implements \ArrayAccess, \JsonSerializable
16
{
17
    /**
18
     * @var int
19
     */
20
    public const KEEP_ALL = 0x00;
21
22
    /**
23
     * @var int
24
     */
25
    public const SKIP_NULL = 0x01;
26
27
    /**
28
     * @var int
29
     */
30
    public const SKIP_EMPTY = 0x02;
31
32
    /**
33
     * All of the attributes set on the container.
34
     *
35
     * @var array
36
     */
37
    protected $attributes = [];
38
39
    /**
40
     * @var bool
41
     */
42
    protected $skip;
43
44
    /**
45
     * Create a new ValueObject container instance.
46
     *
47
     * @param iterable $attributes
48
     * @param int $skip
49
     */
50
    public function __construct(iterable $attributes = [], int $skip = self::KEEP_ALL)
51
    {
52
        $this->setAttributes($attributes);
53
        $this->skip = $skip;
0 ignored issues
show
Documentation Bug introduced by
The property $skip was declared of type boolean, but $skip is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
54
    }
55
56
    /**
57
     * Get an attribute from the container.
58
     *
59
     * @param string $key
60
     * @param mixed $default
61
     * @return mixed
62
     */
63
    public function get(string $key, $default = null)
64
    {
65
        if (\array_key_exists($key, $this->attributes)) {
66
            return $this->attributes[$key];
67
        }
68
69
        return \is_callable($default) ? $default() : $default;
70
    }
71
72
    /**
73
     * Set an attribute to the container.
74
     *
75
     * @param string|int $key
76
     * @param mixed $value
77
     * @return $this
78
     */
79
    public function set($key, $value): self
80
    {
81
        $skipNullable = $this->skip === static::SKIP_NULL && $value === null;
82
83
        $skipEmpty = $this->skip === static::SKIP_EMPTY && ! $value;
84
85
        if (! $skipEmpty && ! $skipNullable) {
86
            $this->attributes[$key ?? \count($this->attributes)] =
87
                \is_iterable($value) ? new self($value) : $value;
88
        }
89
90
        return $this;
91
    }
92
93
    /**
94
     * Set the attributes to the container.
95
     *
96
     * @param iterable $attributes
97
     * @return $this
98
     */
99
    public function setAttributes(iterable $attributes = []): self
100
    {
101
        foreach ($attributes as $key => $value) {
102
            $this->set($key, $value);
103
        }
104
105
        return $this;
106
    }
107
108
    /**
109
     * Get the attributes from the container.
110
     *
111
     * @return array
112
     */
113
    public function getAttributes(): array
114
    {
115
        return $this->attributes;
116
    }
117
118
    /**
119
     * Convert the ValueObject instance to an array.
120
     *
121
     * @return array
122
     */
123
    public function toArray(): array
124
    {
125
        return $this->attributes;
126
    }
127
128
    /**
129
     * @return mixed|object
130
     */
131
    public function toObject()
132
    {
133
        return \json_decode(\json_encode($this));
134
    }
135
136
    /**
137
     * Convert the object into something JSON serializable.
138
     *
139
     * @return array|mixed
140
     */
141
    public function jsonSerialize()
142
    {
143
        $applicator = function ($value) {
144
            if (\is_object($value) && \method_exists($value, '__toString')) {
145
                return (string)$value;
146
            }
147
148
            return $value;
149
        };
150
151
        return \array_map($applicator, $this->toArray());
152
    }
153
154
    /**
155
     * Convert the ValueObject instance to JSON.
156
     *
157
     * @param int $options
158
     * @return string
159
     */
160
    public function toJson(int $options = 0): string
161
    {
162
        return (string)\json_encode($this->jsonSerialize(), $options);
163
    }
164
165
    /**
166
     * Determine if the given offset exists.
167
     *
168
     * @param string $offset
169
     * @return bool
170
     */
171
    public function offsetExists($offset): bool
172
    {
173
        return isset($this->attributes[$offset]);
174
    }
175
176
    /**
177
     * Get the value for a given offset.
178
     *
179
     * @param string|int $offset
180
     * @return mixed
181
     */
182
    public function offsetGet($offset)
183
    {
184
        return $this->get($offset);
185
    }
186
187
    /**
188
     * Set the value at the given offset.
189
     *
190
     * @param string|int $offset
191
     * @param mixed $value
192
     * @return void
193
     */
194
    public function offsetSet($offset, $value): void
195
    {
196
        $this->set($offset, $value);
197
    }
198
199
    /**
200
     * Unset the value at the given offset.
201
     *
202
     * @param string $offset
203
     * @return void
204
     */
205
    public function offsetUnset($offset): void
206
    {
207
        unset($this->attributes[$offset]);
208
    }
209
210
    /**
211
     * Handle dynamic calls to the container to set attributes.
212
     *
213
     * @param string $method
214
     * @param array $parameters
215
     * @return $this
216
     */
217
    public function __call(string $method, array $parameters = []): self
218
    {
219
        $this->attributes[$method] = \count($parameters) > 0 ? $parameters[0] : true;
220
221
        return $this;
222
    }
223
224
    /**
225
     * Dynamically retrieve the value of an attribute.
226
     *
227
     * @param string $key
228
     * @return mixed
229
     */
230
    public function __get(string $key)
231
    {
232
        return $this->get($key);
233
    }
234
235
    /**
236
     * Dynamically set the value of an attribute.
237
     *
238
     * @param string $key
239
     * @param mixed $value
240
     * @return void
241
     */
242
    public function __set(string $key, $value): void
243
    {
244
        $this->offsetSet($key, $value);
245
    }
246
247
    /**
248
     * Dynamically check if an attribute is set.
249
     *
250
     * @param string $key
251
     * @return bool
252
     */
253
    public function __isset(string $key): bool
254
    {
255
        return $this->offsetExists($key);
256
    }
257
258
    /**
259
     * Dynamically unset an attribute.
260
     *
261
     * @param string $key
262
     * @return void
263
     */
264
    public function __unset(string $key): void
265
    {
266
        $this->offsetUnset($key);
267
    }
268
269
    /**
270
     * @return array
271
     */
272
    public function __debugInfo()
273
    {
274
        return $this->attributes;
275
    }
276
}
277