Passed
Push — master ( 35c885...2ba443 )
by Filipe
01:25
created

UploadedFilesFactory::normalize()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 17
nc 3
nop 1
dl 0
loc 27
rs 9.7
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Slick\Http\Message\Server;
6
7
use Psr\Http\Message\UploadedFileInterface as PSRFile;
8
9
/**
10
 * UploadedFilesFactory
11
 *
12
 * @package Slick\Http\Message\Server
13
 */
14
final class UploadedFilesFactory
15
{
16
    /**
17
     * Creates the uploaded file objects within a normalized files tree.
18
     *
19
     * @return array<string, array<int|string, array<int|string, PSRFile>|PSRFile>|UploadedFile>
20
     * @SuppressWarnings(PHPMD)
21
     */
22
    public static function createFiles(): array
23
    {
24
        $factory = new self();
25
        return $factory->normalize($_FILES);
26
    }
27
28
    /**
29
     * Converts $_FILES to UploadedFile instances.
30
     *
31
     * If the $_FILES array is multidimensional, it will return an array of UploadedFile instances.
32
     * It will preserve the keys of the original array.
33
     *
34
     * @param array<string, array{
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{ at position 2 could not be parsed: the token is null at position 2.
Loading history...
35
     *     tmp_name: string|array<string|int, string|array<string|int, string>>,
36
     *     size: int|array<string|int, int|array<string|int, int>>,
37
     *     error: int|array<string|int, int|array<string|int, int>>,
38
     *     name: string|array<string|int, string|array<string|int, string>>,
39
     *     type: string|array<string|int, string|array<string|int, string>>
40
     * }> $files
41
     * @return array<string, array<int|string, array<int|string, PSRFile>|PSRFile>|UploadedFile>
42
     * @SuppressWarnings(PHPMD)
43
     */
44
    private function normalize(array $files): array
45
    {
46
        $normalized = [];
47
48
        foreach ($files as $field => $fileData) {
49
            if (\is_string($fileData['tmp_name'])) {
50
                /** @var array{tmp_name: string, size: int, error: int, name: string|null, type: string|null} $fileData */
51
                $normalized[$field] = UploadedFile::create([
52
                    'tmp_name' => (string) $fileData['tmp_name'],
53
                    'size'     => (int) $fileData['size'],
54
                    'error'    => (int) $fileData['error'],
55
                    'name'     => (string) $fileData['name'],
56
                    'type'     => (string) $fileData['type'],
57
                ]);
58
                continue;
59
            }
60
61
            $normalized[$field] = $this->normalizeNestedFiles(
62
                (array) $fileData['tmp_name'],
63
                (array) $fileData['size'],
64
                (array) $fileData['error'],
65
                (array) $fileData['name'],
66
                (array) $fileData['type']
67
            );
68
        }
69
70
        return $normalized;
71
    }
72
73
    /**
74
     * Normalizes a nested set of uploaded files (recursively)
75
     *
76
     * @param array<string|int, string|array<string|int, string>> $tmpNames
77
     * @param array<string|int, int|array<string|int, int>> $sizes
78
     * @param array<string|int, int|array<string|int, int>> $errors
79
     * @param array<string|int, string|array<string|int, string>> $names
80
     * @param array<string|int, string|array<string|int, string>> $types
81
     *
82
     * @return array<string, array<int|string, array<int|string, PSRFile>|PSRFile>|UploadedFile>
83
     */
84
    private function normalizeNestedFiles(
85
        array $tmpNames,
86
        array $sizes,
87
        array $errors,
88
        array $names,
89
        array $types
90
    ): array {
91
        $normalized = [];
92
93
        foreach ($tmpNames as $key => $tmpName) {
94
            if (\is_array($tmpName)) {
95
                $normalized[$key] = $this->normalizeNestedFiles(
96
                    $tmpName,
97
                    (array) ($sizes[$key] ?? []),
98
                    (array) ($errors[$key] ?? []),
99
                    (array) ($names[$key] ?? []),
100
                    (array) ($types[$key] ?? [])
101
                );
102
                continue;
103
            }
104
105
            /** @var array{tmp_name: string, size: int, error: int, name: string|null, type: string|null} $fileUploadData */
106
            $fileUploadData = [
107
                'tmp_name' => $tmpName,
108
                'size' => (int) ($sizes[$key] ?? 0),
109
                'error' => (int) ($errors[$key] ?? 0),
110
                'name' => (string) (!\is_array($names[$key]) ? $names[$key] : ''),
111
                'type' => (string) (!\is_array($types[$key]) ? $types[$key] : ''),
112
            ];
113
            $normalized[$key] = UploadedFile::create($fileUploadData);
114
        }
115
116
        return $normalized;
117
    }
118
}
119