Apply PSR-12 code style (#3886)
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / upload / UploadHandler.class.php
CommitLineData
02b12b91 1<?php
a9229942 2
02b12b91 3namespace wcf\system\upload;
a9229942 4
35e07ccc 5use 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
15class 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}