Completed
Push — master ( e48a70...7a3b29 )
by Adrian
06:03
created

Helper::extractFromSymfonyFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Sirius\Upload\Util;
5
6
class Helper
7
{
8
    const PSR7_UPLOADED_FILE_CLASS = '\Psr\Http\Message\UploadedFileInterface';
9
    const SYMFONY_UPLOADED_FILE_CLASS = 'Symfony\Component\HttpFoundation\File\UploadedFile';
10
11
    /**
12
     * We do not type-hint or import the class since it may not be used
13
     *
14
     * @param \Psr\Http\Message\UploadedFileInterface $file
15
     *
16
     * @return array
17
     */
18
    public static function extractFromUploadedFileInterface($file)
19
    {
20
        /** @var \Psr\Http\Message\UploadedFileInterface $file */
21
        $tempName = tempnam(sys_get_temp_dir(), 'srsupld_');
22
        $file->moveTo($tempName);
23
        $result = [
24
            'name'     => $file->getClientFilename(),
25
            'tmp_name' => $tempName,
26
            'type'     => $file->getClientMediaType(),
27
            'error'    => $file->getError(),
28
            'size'     => $file->getSize()
29
        ];
30
31
        return $result;
32
    }
33
34
    public static function extractFromSymfonyFile($file)
35
    {
36
        /** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
37
38
        $result = [
39
            'name'     => $file->getClientOriginalName(),
40
            'tmp_name' => $file->getPathname(),
41
            'type'     => $file->getMimeType(),
42
            'error'    => $file->getError(),
43
            'size'     => $file->getSize()
44
        ];
45
46
        return $result;
47
    }
48
49
    public static function remapFilesArray(array $files): array
50
    {
51
        $result = [];
52
        foreach (array_keys($files['name']) as $k) {
53
            $result[$k] = [
54
                'name'     => $files['name'][$k],
55
                'type'     => @$files['type'][$k],
56
                'size'     => @$files['size'][$k],
57
                'error'    => @$files['error'][$k],
58
                'tmp_name' => $files['tmp_name'][$k]
59
            ];
60
        }
61
62
        return $result;
63
    }
64
65
    /**
66
     * Fixes the $_FILES array problem and ensures the result is an array of files
67
     *
68
     * PHP's $_FILES variable is not properly formated for iteration when
69
     * multiple files are uploaded under the same name
70
     * @see http://www.php.net/manual/en/features.file-upload.php
71
     *
72
     * @param array|Symfony\Component\HttpFoundation\File\UploadedFile|\Psr\Http\Message\UploadedFileInterface $files
73
     *
74
     * @return array
75
     */
76
    public static function normalizeFiles($files): array
77
    {
78
        if (empty($files)) {
79
            return [];
80
        }
81
82
        if (is_object($files)) {
83
            if (is_subclass_of($files, self::PSR7_UPLOADED_FILE_CLASS)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if self::PSR7_UPLOADED_FILE_CLASS can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
84
                return [self::extractFromUploadedFileInterface($files)];
85
            }
86
            if (get_class($files) == self::SYMFONY_UPLOADED_FILE_CLASS) {
87
                return [self::extractFromSymfonyFile($files)];
88
            }
89
        }
90
91
        if (is_array($files) && is_object($files[0])) {
92
            if (is_subclass_of($files[0], self::PSR7_UPLOADED_FILE_CLASS)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if self::PSR7_UPLOADED_FILE_CLASS can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
93
                $result = [];
94
                foreach ($files as $file) {
95
                    $result[] = self::extractFromUploadedFileInterface($file);
96
                }
97
98
                return $result;
99
            }
100
101
            if (get_class($files[0]) == self::SYMFONY_UPLOADED_FILE_CLASS) {
102
                $result = [];
103
                foreach ($files as $file) {
104
                    $result[] = self::extractFromSymfonyFile($file);
105
                }
106
107
                return $result;
108
            }
109
        }
110
111
112
113
114
115
116
        // The caller passed $_FILES['some_field_name']
117
        if (isset($files['name'])) {
118
            // we have a single file
119
            if (! is_array($files['name'])) {
120
                return [$files];
121
            } else {
122
                // we have list of files, which PHP messes up
123
                return Helper::remapFilesArray($files);
0 ignored issues
show
Bug introduced by
It seems like $files defined by parameter $files on line 76 can also be of type object<Psr\Http\Message\UploadedFileInterface>; however, Sirius\Upload\Util\Helper::remapFilesArray() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
124
            }
125
        } else {
126
            // The caller passed $_FILES
127
            $keys = array_keys($files);
128
            if (isset($keys[0]) && isset($files[$keys[0]]['name'])) {
129
                if (! is_array($files[$keys[0]]['name'])) {
130
                    // $files is in the correct format already, even in the
131
                    // case it contains a single element.
132
                    return $files;
133
                } else {
134
                    // we have list of files, which PHP messes up
135
                    return Helper::remapFilesArray($files[$keys[0]]);
136
                }
137
            }
138
        }
139
140
        // if we got here, the $file argument is wrong
141
        return [];
142
    }
143
}
144