|
3 | 3 | namespace Bref\Event\Http; |
4 | 4 |
|
5 | 5 | use Bref\Context\Context; |
| 6 | +use Bref\Support\MultipartArray; |
6 | 7 | use Nyholm\Psr7\ServerRequest; |
7 | 8 | use Nyholm\Psr7\Stream; |
8 | 9 | use Nyholm\Psr7\UploadedFile; |
|
13 | 14 |
|
14 | 15 | use function str_starts_with; |
15 | 16 |
|
16 | | -// Polyfill for array_is_list (PHP 8.1+) to support PHP 8.0 |
17 | | -if (! function_exists('array_is_list')) { |
18 | | - function array_is_list(array $array): bool |
19 | | - { |
20 | | - $i = 0; |
21 | | - foreach ($array as $key => $value) { |
22 | | - if ($key !== $i++) { |
23 | | - return false; |
24 | | - } |
25 | | - } |
26 | | - return true; |
27 | | - } |
28 | | -} |
29 | | - |
30 | 17 | /** |
31 | 18 | * Bridges PSR-7 requests and responses with API Gateway or ALB event/response formats. |
32 | 19 | */ |
@@ -138,102 +125,17 @@ private static function parseBodyAndUploadedFiles(HttpRequestEvent $event): arra |
138 | 125 | } |
139 | 126 | file_put_contents($tmpPath, $part->getBody()); |
140 | 127 | $file = new UploadedFile($tmpPath, filesize($tmpPath), UPLOAD_ERR_OK, $part->getFileName(), $part->getMimeType()); |
141 | | - self::parseKeyAndInsertValueInArray($files, $part->getName(), $file); |
| 128 | + $files = MultipartArray::setValue($files, $part->getName(), $file); |
142 | 129 | } else { |
143 | 130 | if ($parsedBody === null) { |
144 | 131 | $parsedBody = []; |
145 | 132 | } |
146 | | - self::parseKeyAndInsertValueInArray($parsedBody, $part->getName(), $part->getBody()); |
| 133 | + $parsedBody = MultipartArray::setValue($parsedBody, $part->getName(), $part->getBody()); |
147 | 134 | } |
148 | 135 | } |
149 | 136 | return [$files, $parsedBody]; |
150 | 137 | } |
151 | 138 |
|
152 | | - /** |
153 | | - * Parse a string key like "files[id_cards][jpg][]" and do $array['files']['id_cards']['jpg'][] = $value |
154 | | - */ |
155 | | - private static function parseKeyAndInsertValueInArray(array &$array, string $key, mixed $value): void |
156 | | - { |
157 | | - $parsed = []; |
158 | | - // We use parse_str to parse the key in the same way PHP does natively |
159 | | - // We use "=mock" because the value can be an object (in case of uploaded files) |
160 | | - parse_str(urlencode($key) . '=mock', $parsed); |
161 | | - // Replace `mock` with the actual value |
162 | | - array_walk_recursive($parsed, fn (&$v) => $v = $value); |
163 | | - |
164 | | - // Use a custom merge that handles both structured arrays and regular arrays |
165 | | - $array = self::mergeRecursivePreserveNumeric($array, $parsed); |
166 | | - } |
167 | | - |
168 | | - private static function mergeRecursivePreserveNumeric(array $a, array $b): array |
169 | | - { |
170 | | - foreach ($b as $key => $bVal) { |
171 | | - if (! array_key_exists($key, $a)) { |
172 | | - $a[$key] = $bVal; |
173 | | - continue; |
174 | | - } |
175 | | - |
176 | | - $aVal = $a[$key]; |
177 | | - |
178 | | - if (is_array($aVal) && is_array($bVal)) { |
179 | | - $aIsList = array_is_list($aVal); |
180 | | - $bIsList = array_is_list($bVal); |
181 | | - |
182 | | - if ($aIsList && $bIsList) { |
183 | | - // Determine whether list items are arrays (objects) -> merge-by-index |
184 | | - $mergeByIndex = false; |
185 | | - foreach ($aVal as $item) { |
186 | | - if (is_array($item)) { |
187 | | - $mergeByIndex = true; |
188 | | - break; |
189 | | - } |
190 | | - } |
191 | | - if (! $mergeByIndex) { |
192 | | - foreach ($bVal as $item) { |
193 | | - if (is_array($item)) { |
194 | | - $mergeByIndex = true; |
195 | | - break; |
196 | | - } |
197 | | - } |
198 | | - } |
199 | | - |
200 | | - if ($mergeByIndex) { |
201 | | - $max = max(count($aVal), count($bVal)); |
202 | | - $merged = []; |
203 | | - for ($i = 0; $i < $max; $i++) { |
204 | | - $hasA = array_key_exists($i, $aVal); |
205 | | - $hasB = array_key_exists($i, $bVal); |
206 | | - if ($hasA && $hasB) { |
207 | | - if (is_array($aVal[$i]) && is_array($bVal[$i])) { |
208 | | - $merged[$i] = self::mergeRecursivePreserveNumeric($aVal[$i], $bVal[$i]); |
209 | | - } else { |
210 | | - // if one is scalar, b wins |
211 | | - $merged[$i] = $bVal[$i]; |
212 | | - } |
213 | | - } elseif ($hasA) { |
214 | | - $merged[$i] = $aVal[$i]; |
215 | | - } else { |
216 | | - $merged[$i] = $bVal[$i]; |
217 | | - } |
218 | | - } |
219 | | - $a[$key] = $merged; |
220 | | - } else { |
221 | | - // both lists of scalars -> append |
222 | | - $a[$key] = array_merge($aVal, $bVal); |
223 | | - } |
224 | | - } else { |
225 | | - // At least one side is associative -> merge recursively by key |
226 | | - $a[$key] = self::mergeRecursivePreserveNumeric($aVal, $bVal); |
227 | | - } |
228 | | - } else { |
229 | | - // Non-array or conflicting types -> b wins |
230 | | - $a[$key] = $bVal; |
231 | | - } |
232 | | - } |
233 | | - |
234 | | - return $a; |
235 | | - } |
236 | | - |
237 | 139 | /** |
238 | 140 | * Cleanup previously uploaded files. |
239 | 141 | */ |
|
0 commit comments