Passed
Push — main ( 62bcc5...88cf22 )
by Gabriel
13:45
created

Metadata::setDataItem()   B

Complexity

Conditions 8
Paths 4

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 8
eloc 20
c 1
b 0
f 1
nc 4
nop 2
dl 0
loc 34
rs 8.4444
1
<?php
2
3
namespace ByTIC\DataObjects\Casts\Metadata;
4
5
use ArrayObject as BaseArrayObject;
6
use JsonSerializable;
7
use Serializable;
8
9
/**
10
 * Class ArrayObject
11
 * @package ByTIC\DataObjects\Casts\Metadata
12
 */
13
class Metadata extends BaseArrayObject implements JsonSerializable, Serializable
14
{
15
    /**
16
     * @var null|callable
17
     */
18
    protected $observer = null;
19
20
    /**
21
     * @param string $key
22
     * @param $default
23
     * @return mixed
24
     */
25
    public function get(string $key, $default = null)
26
    {
27
        if (strpos($key, '.') === false) {
28
            $value = $this->getByKey($key);
29
        } else {
30
            $value = $this->getByPath($key);
31
        }
32
33
        return $value === null ? $default : $value;
34
    }
35
36
    /**
37
     * @param $name
38
     * @param $value
39
     * @return $this
40
     */
41
    public function set($name, $value)
42
    {
43
        return $this->setDataItem($name, $value);
44
    }
45
46
    /**
47
     * @param string $key
48
     * @return mixed|null
49
     */
50
    public function getByKey($key)
51
    {
52
        if ($this->hasByKey($key)) {
53
            return $this[$key];
54
        }
55
56
        return null;
57
    }
58
59
    /**
60
     * Determine if the given configuration value exists.
61
     *
62
     * @param string $key
63
     * @return bool
64
     */
65
    public function hasByKey($key)
66
    {
67
        return isset($this[$key]);
68
    }
69
70
    /**
71
     * @param string $path
72
     * @return string
73
     */
74
    protected function getByPath(string $path)
75
    {
76
        $segments = explode('.', $path);
77
        $value = $this;
78
        foreach ($segments as $segment) {
79
            if (isset($value[$segment])) {
80
                $value = $value[$segment];
81
            } else {
82
                return null;
83
            }
84
        }
85
86
        return $value;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $value also could return the type ByTIC\DataObjects\Casts\Metadata\Metadata which is incompatible with the documented return type string.
Loading history...
87
    }
88
89
    /**
90
     * @param $name
91
     * @param $value
92
     * @return $this
93
     */
94
    protected function setDataItem($name, $value)
95
    {
96
        if (null === $name) {
97
            $this[] = $value;
98
            return $this;
99
        }
100
101
        if (strpos($name, '.') === false) {
102
            $this[$name] = $value;
103
            return $this;
104
        }
105
        $parts = explode('.', $name);
106
        $ptr =& $this;
107
108
        if (is_array($parts)) {
0 ignored issues
show
introduced by
The condition is_array($parts) is always true.
Loading history...
109
            foreach ($parts as $part) {
110
                if ('[]' == $part) {
111
                    if (is_array($ptr)) {
112
                        $ptr =& $ptr[];
113
                    }
114
                } else {
115
                    if (!isset($ptr[$part])) {
116
                        $ptr[$part] = [];
117
                    }
118
119
                    $ptr =& $ptr[$part];
120
                }
121
            }
122
        }
123
124
        $ptr = $value;
125
        $this->callObserver();
126
127
        return $this;
128
    }
129
130
    /**
131
     * Get the instance as an array.
132
     *
133
     * @return array
134
     */
135
    public function toArray()
136
    {
137
        return $this->getArrayCopy();
138
    }
139
140
    /**
141
     * @inheritDoc
142
     */
143
    public function serialize()
144
    {
145
        return serialize($this->toArray());
146
    }
147
148
    /**
149
     * Constructs the object.
150
     * @link https://php.net/manual/en/serializable.unserialize.php
151
     * @param string $serialized The string representation of the object.
152
     * @return void
153
     */
154
    public function unserialize($data)
155
    {
156
        $data = @unserialize($data);
157
        if (!is_array($data)) {
158
            return;
159
        }
160
        foreach ($data as $property => $value) {
161
            $this[$property] = $value;
162
        }
163
    }
164
165
    /**
166
     * Get the array that should be JSON serialized.
167
     *
168
     * @return array
169
     */
170
    public function jsonSerialize()
171
    {
172
        return $this->getArrayCopy();
173
    }
174
175
    /**
176
     * @inheritDoc
177
     */
178
    public function offsetSet($key, $value)
179
    {
180
        parent::offsetSet($key, $value);
181
        $this->callObserver();
182
    }
183
184
    /**
185
     * @param callable|null $observer
186
     * @return Metadata
187
     */
188
    public function setObserver(?callable $observer): self
189
    {
190
        $this->observer = $observer;
191
        return $this;
192
    }
193
194
    protected function callObserver()
195
    {
196
        call_user_func($this->observer, $this);
0 ignored issues
show
Bug introduced by
It seems like $this->observer can also be of type null; however, parameter $callback of call_user_func() does only seem to accept callable, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

196
        call_user_func(/** @scrutinizer ignore-type */ $this->observer, $this);
Loading history...
197
    }
198
199
}
200