Passed
Push — master ( 9b2be2...a50162 )
by Бабичев
01:53
created

Slice::asArray()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6

Importance

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