Passed
Push — master ( fa224c...2f97ae )
by Бабичев
01:45
created

Slice::__call()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 2
1
<?php
2
3
namespace Bavix\Slice;
4
5
use Bavix\Exceptions;
6
use Bavix\Helpers\Arr;
7
use Bavix\Helpers\Str;
8
use Bavix\Iterator\Iterator;
9
10
/**
11
 * Class Slice
12
 *
13
 * @package Bavix\Slice
14
 *
15
 * @method int getInt($offset)
16
 * @method float getFloat($offset)
17
 * @method bool getBool($offset)
18
 * @method string getEmail($offset)
19
 * @method string getIP($offset)
20
 * @method string getURL($offset)
21
 */
22
class Slice extends Iterator
23
{
24
25
    /**
26
     * Slice constructor.
27
     *
28
     * @param array       $data
29
     * @param array|Slice $parameters
30
     */
31 12
    public function __construct(array $data, $parameters = null)
32
    {
33 12
        parent::__construct($data);
34
35 12
        if (null !== $parameters)
36
        {
37 12
            $this->walk($parameters);
38
        }
39 12
    }
40
41
    /**
42
     * @param array|\Traversable $data
43
     *
44
     * @return self
45
     */
46 1
    public static function from($data): self
47
    {
48 1
        if ($data instanceof self)
49
        {
50 1
            return $data;
51
        }
52
53 1
        return new static(
54 1
            Arr::iterator($data)
55
        );
56
    }
57
58
    /**
59
     * @param int|bool $depth
60
     *
61
     * @return array
62
     */
63 5
    public function asArray($depth = INF)
64
    {
65 5
        if (!$depth || $depth <= 0)
66
        {
67 1
            return $this->data;
68
        }
69
70 5
        $results = [];
71
72 5
        foreach (parent::asArray() as $key => $data)
73
        {
74 5
            $results[$key] =
75 5
                $data instanceof self ?
76 1
                    $data->asArray(\is_bool($depth) ? INF : --$depth) :
77 5
                    $data;
78
        }
79
80 5
        return $results;
81
    }
82
83
    /**
84
     * @param Slice|array $slice
85
     */
86 12
    protected function walk($slice)
87
    {
88 12
        if (\is_array($slice))
89
        {
90 12
            $slice = $this->make($slice);
91
        }
92
93 12
        Arr::walkRecursive($this->data, function (&$value) use ($slice) {
94
95 12
            if (\is_object($value) && $value instanceof Raw)
96
            {
97 12
                $value = $value->getData();
98
99 12
                return;
100
            }
101
102 12
            if (empty($value) || !\is_string($value))
103
            {
104
                return;
105
            }
106
107 12
            if (Str::first($value) === '%' &&
108 12
                Str::last($value) === '%' &&
109 12
                \substr_count($value, '%') === 2)
110
            {
111 12
                $path  = Str::sub($value, 1, -1);
112 12
                $value = $slice->getRequired($path);
113
            }
114
115 12
        });
116 12
    }
117
118
    /**
119
     * @param string $name
120
     * @param array  $arguments
121
     *
122
     * @return mixed
123
     */
124
    public function __call($name, $arguments)
125
    {
126
        return Filter::$name($this, ...$arguments);
127
    }
128
129
    /**
130
     * @return \Generator|Slice[]
131
     */
132 1
    public function asGenerator()
133
    {
134 1
        foreach ($this->data as $key => $object)
135
        {
136 1
            yield $key => $this->make($object);
137
        }
138 1
    }
139
140
    /**
141
     * @return array
142
     */
143 1
    public function keys()
144
    {
145 1
        return Arr::getKeys($this->data);
146
    }
147
148
    /**
149
     * @return Slice[]
150
     */
151 1
    public function asObject()
152
    {
153 1
        return Arr::iterator($this->asGenerator());
154
    }
155
156
    /**
157
     * @param array $data
158
     *
159
     * @return static
160
     */
161 12
    public function setData(array $data)
162
    {
163 12
        $this->data = $data;
164
165 12
        return $this;
166
    }
167
168
    /**
169
     * @param string $offset
170
     * @param mixed  $default
171
     *
172
     * @return mixed
173
     */
174 2
    public function getData($offset, $default = null)
175
    {
176 2
        return Arr::get($this->data, $offset, $default);
177
    }
178
179
    /**
180
     * @param string $offset
181
     *
182
     * @return Slice
183
     */
184 1
    public function getSlice($offset)
185
    {
186 1
        return $this->make($this->getRequired($offset));
187
    }
188
189
    /**
190
     * @param array $data
191
     *
192
     * @return Slice
193
     */
194 12
    public function make(array $data)
195
    {
196 12
        return (clone $this)->setData($data);
197
    }
198
199
    /**
200
     * @param string $offset
201
     *
202
     * @return array|mixed
203
     */
204 12
    public function getRequired($offset)
205
    {
206 12
        return Arr::getRequired($this->data, $offset);
207
    }
208
209
    /**
210
     * @inheritdoc
211
     */
212 1
    public function offsetExists($offset)
213
    {
214 1
        return Arr::get($this->data, $offset) !== null;
215
    }
216
217
    /**
218
     * @inheritdoc
219
     */
220 4
    public function offsetGet($offset)
221
    {
222 4
        return $this->getRequired($offset);
223
    }
224
225
    /**
226
     * @inheritdoc
227
     */
228 3
    public function offsetSet($offset, $value)
229
    {
230 3
        if (null === $offset)
231
        {
232 1
            throw new Exceptions\Invalid('Slice does not support NULL');
233
        }
234
235 2
        Arr::set($this->data, $offset, $value);
236 2
    }
237
238
    /**
239
     * @inheritdoc
240
     */
241 2
    public function offsetUnset($offset)
242
    {
243 2
        Arr::remove($this->data, $offset);
244 2
    }
245
246
}
247