Commit | Line | Data |
---|---|---|
02b12b91 | 1 | <?php |
a9229942 | 2 | |
02b12b91 | 3 | namespace wcf\system\upload; |
a9229942 | 4 | |
35e07ccc | 5 | use wcf\util\FileUtil; |
02b12b91 MW |
6 | |
7 | /** | |
8 | * Handles file uploads. | |
a9229942 TD |
9 | * |
10 | * @author Marcel Werk | |
11 | * @copyright 2001-2019 WoltLab GmbH | |
12 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | |
13 | * @package WoltLabSuite\Core\System\Upload | |
02b12b91 | 14 | */ |
a9229942 TD |
15 | class UploadHandler |
16 | { | |
17 | /** | |
18 | * list of uploaded files | |
19 | * @var UploadFile[] | |
20 | */ | |
21 | protected $files = []; | |
22 | ||
23 | /** | |
24 | * list of validation errors. | |
25 | * @var array | |
26 | */ | |
27 | protected $erroneousFiles = []; | |
28 | ||
29 | /** | |
30 | * Creates a new UploadHandler object. | |
31 | * | |
32 | * @param mixed[] $rawFileData | |
33 | */ | |
34 | protected function __construct(array $rawFileData) | |
35 | { | |
36 | if (\is_array($rawFileData['name'])) { | |
37 | // iOS work-around | |
38 | $newRawFileData = [ | |
39 | 'name' => [], | |
40 | 'type' => [], | |
41 | 'tmp_name' => [], | |
42 | 'error' => [], | |
43 | 'size' => [], | |
44 | ]; | |
45 | $i = 0; | |
46 | foreach (\array_keys($rawFileData['name']) as $internalFileID) { | |
47 | // __wcf_X_filename.ext | |
48 | $newRawFileData['name'][$i] = '__wcf_' . $internalFileID . '_' . $rawFileData['name'][$internalFileID]; | |
49 | $newRawFileData['type'][$i] = $rawFileData['type'][$internalFileID]; | |
50 | $newRawFileData['tmp_name'][$i] = $rawFileData['tmp_name'][$internalFileID]; | |
51 | $newRawFileData['error'][$i] = $rawFileData['error'][$internalFileID]; | |
52 | $newRawFileData['size'][$i] = $rawFileData['size'][$internalFileID]; | |
53 | ||
54 | $i++; | |
55 | } | |
56 | $rawFileData = $newRawFileData; | |
57 | ||
58 | // multiple uploads | |
59 | for ($i = 0, $l = \count($rawFileData['name']); $i < $l; $i++) { | |
60 | $mimeType = ''; | |
61 | if ($rawFileData['tmp_name'][$i]) { | |
62 | $mimeType = self::getMimeType($rawFileData['tmp_name'][$i], $rawFileData['type'][$i]); | |
63 | } | |
64 | ||
65 | $this->files[] = new UploadFile( | |
66 | $rawFileData['name'][$i], | |
67 | $rawFileData['tmp_name'][$i], | |
68 | $rawFileData['size'][$i], | |
69 | $rawFileData['error'][$i], | |
70 | $mimeType | |
71 | ); | |
72 | } | |
73 | } else { | |
74 | $this->files[] = new UploadFile( | |
75 | $rawFileData['name'], | |
76 | $rawFileData['tmp_name'], | |
77 | $rawFileData['size'], | |
78 | $rawFileData['error'], | |
79 | ($rawFileData['tmp_name'] ? self::getMimeType($rawFileData['tmp_name'], $rawFileData['type']) : '') | |
80 | ); | |
81 | } | |
82 | } | |
83 | ||
84 | /** | |
85 | * Returns the list of uploaded files. | |
86 | * | |
87 | * @return UploadFile[] | |
88 | */ | |
89 | public function getFiles() | |
90 | { | |
91 | return $this->files; | |
92 | } | |
93 | ||
94 | /** | |
95 | * Validates the uploaded files. Returns true on success, otherwise false. | |
96 | * | |
97 | * @param IUploadFileValidationStrategy $validationStrategy | |
98 | * @return bool | |
99 | */ | |
100 | public function validateFiles(IUploadFileValidationStrategy $validationStrategy) | |
101 | { | |
102 | $result = true; | |
103 | foreach ($this->files as $file) { | |
104 | if (!$validationStrategy->validate($file)) { | |
105 | $this->erroneousFiles[] = $file; | |
106 | $result = false; | |
107 | } | |
108 | } | |
109 | ||
110 | return $result; | |
111 | } | |
112 | ||
113 | /** | |
114 | * Returns a list of erroneous files. | |
115 | * | |
116 | * @return UploadFile[] | |
117 | */ | |
118 | public function getErroneousFiles() | |
119 | { | |
120 | return $this->erroneousFiles; | |
121 | } | |
122 | ||
123 | /** | |
124 | * Saves the uploaded files. | |
125 | * | |
126 | * @param IUploadFileSaveStrategy $saveStrategy | |
127 | */ | |
128 | public function saveFiles(IUploadFileSaveStrategy $saveStrategy) | |
129 | { | |
130 | foreach ($this->files as $file) { | |
131 | if (!$file->getValidationErrorType()) { | |
132 | $saveStrategy->save($file); | |
133 | } | |
134 | } | |
135 | } | |
136 | ||
137 | /** | |
138 | * Returns an upload handler instance for the given identifier or `null` if no data exists in `$_FILES` | |
139 | * for the identifier. | |
140 | * | |
141 | * @param string $identifier | |
142 | * @return UploadHandler | |
143 | */ | |
144 | public static function getUploadHandler($identifier) | |
145 | { | |
146 | if (isset($_FILES[$identifier]) && \is_array($_FILES[$identifier])) { | |
147 | return new self($_FILES[$identifier]); | |
148 | } | |
149 | } | |
150 | ||
151 | /** | |
152 | * Returns the mime type of a file. | |
153 | * | |
154 | * @param string $file | |
155 | * @param string $mimeType mime type transferred by client | |
156 | * @return string | |
157 | */ | |
158 | protected static function getMimeType($file, $mimeType) | |
159 | { | |
160 | if ( | |
161 | $mimeType == 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' | |
162 | || $mimeType == 'application/vnd.openxmlformats-officedocument.presentationml.presentation' | |
163 | || $mimeType == 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' | |
164 | ) { | |
165 | // libmagic can not detect mime type of docx, xlsx and pttx files | |
166 | return $mimeType; | |
167 | } | |
168 | ||
169 | $finfoMimeType = FileUtil::getMimeType($file); | |
170 | if ($finfoMimeType) { | |
171 | return $finfoMimeType; | |
172 | } | |
173 | ||
174 | return $mimeType; | |
175 | } | |
02b12b91 | 176 | } |