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
![]() |
|||
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 |