Slice::asGenerator()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 2
rs 10
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 12
            $this->walk($parameters);
44
        }
45 12
    }
46
47
    /**
48
     * @param array|\Traversable $data
49
     *
50
     * @return self
51
     */
52 1
    public static function from($data): self
53
    {
54 1
        if ($data instanceof self) {
55 1
            return $data;
56
        }
57
58 1
        return new static(
59 1
            Arr::iterator($data)
60
        );
61
    }
62
63
    /**
64
     * @param int|bool $depth
65
     *
66
     * @return array
67
     */
68 5
    public function asArray($depth = INF)
69
    {
70 5
        if (!$depth || $depth <= 0) {
71 1
            return $this->data;
72
        }
73
74 5
        $results = [];
75
76 5
        foreach (parent::asArray() as $key => $data) {
77 5
            $results[$key] =
78 5
                $data instanceof self ?
79 1
                    $data->asArray(\is_bool($depth) ? INF : --$depth) :
0 ignored issues
show
Bug introduced by
It seems like is_bool($depth) ? Bavix\Slice\INF : --$depth can also be of type double; however, parameter $depth of Bavix\Slice\Slice::asArray() does only seem to accept boolean|integer, 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

79
                    $data->asArray(/** @scrutinizer ignore-type */ \is_bool($depth) ? INF : --$depth) :
Loading history...
80 5
                    $data;
81
        }
82
83 5
        return $results;
84
    }
85
86
    /**
87
     * @param Slice|array $slice
88
     */
89 12
    protected function walk($slice)
90
    {
91 12
        if (\is_array($slice)) {
92 12
            $slice = $this->make($slice);
93
        }
94
95 12
        Arr::walkRecursive($this->data, function (&$value) use ($slice) {
96
97 12
            if (\is_object($value) && $value instanceof Raw) {
98 12
                $value = $value->getData();
99
100 12
                return;
101
            }
102
103 12
            if (empty($value) || !\is_string($value)) {
104
                return;
105
            }
106
107 12
            if (Str::first($value) === '%' &&
108 12
                Str::last($value) === '%' &&
109 12
                \substr_count($value, '%') === 2) {
110 12
                $path  = Str::sub($value, 1, -1);
111 12
                $value = $slice->getRequired($path);
112
            }
113 12
        });
114 12
    }
115
116
    /**
117
     * @param string $name
118
     * @param array  $arguments
119
     *
120
     * @return mixed
121
     */
122
    public function __call($name, $arguments)
123
    {
124
        list($offset) = $arguments;
125
126
        if (\strpos($name, 'Required') !== false) {
127
            $name = \str_replace('Required', '', $name);
128
            return Filter::$name($this->getRequired($offset));
129
        }
130
131
        return Filter::$name($this->getData($offset));
132
    }
133
134
    /**
135
     * @return \Generator|Slice[]
136
     */
137 1
    public function asGenerator()
138
    {
139 1
        foreach ($this->data as $key => $object) {
140 1
            yield $key => $this->make($object);
141
        }
142 1
    }
143
144
    /**
145
     * @return array
146
     */
147 1
    public function keys()
148
    {
149 1
        return Arr::getKeys($this->data);
150
    }
151
152
    /**
153
     * @return Slice[]
154
     */
155 1
    public function asObject()
156
    {
157 1
        return Arr::iterator($this->asGenerator());
158
    }
159
160
    /**
161
     * @param array $data
162
     *
163
     * @return static
164
     */
165 12
    public function setData(array $data)
166
    {
167 12
        $this->data = $data;
168
169 12
        return $this;
170
    }
171
172
    /**
173
     * @param string $offset
174
     * @param mixed  $default
175
     *
176
     * @return mixed
177
     */
178 2
    public function getData($offset, $default = null)
179
    {
180 2
        return Arr::get($this->data, $offset, $default);
181
    }
182
183
    /**
184
     * @param string $offset
185
     *
186
     * @return Slice
187
     */
188 1
    public function getSlice($offset)
189
    {
190 1
        return $this->make($this->getRequired($offset));
191
    }
192
193
    /**
194
     * @param array $data
195
     *
196
     * @return Slice
197
     */
198 12
    public function make(array $data)
199
    {
200 12
        return (clone $this)->setData($data);
201
    }
202
203
    /**
204
     * @param string $offset
205
     *
206
     * @return array|mixed
207
     */
208 12
    public function getRequired($offset)
209
    {
210 12
        return Arr::getRequired($this->data, $offset);
211
    }
212
213
    /**
214
     * @inheritdoc
215
     */
216 1
    public function offsetExists($offset)
217
    {
218 1
        return Arr::get($this->data, $offset) !== null;
219
    }
220
221
    /**
222
     * @inheritdoc
223
     */
224 4
    public function offsetGet($offset)
225
    {
226 4
        return $this->getRequired($offset);
227
    }
228
229
    /**
230
     * @inheritdoc
231
     */
232 3
    public function offsetSet($offset, $value)
233
    {
234 3
        if (null === $offset) {
235 1
            throw new Exceptions\Invalid('Slice does not support NULL');
236
        }
237
238 2
        Arr::set($this->data, $offset, $value);
239 2
    }
240
241
    /**
242
     * @inheritdoc
243
     */
244 2
    public function offsetUnset($offset)
245
    {
246 2
        Arr::remove($this->data, $offset);
247 2
    }
248
}
249