comparison vendor/guzzlehttp/psr7/src/UploadedFile.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2 namespace GuzzleHttp\Psr7;
3
4 use InvalidArgumentException;
5 use Psr\Http\Message\StreamInterface;
6 use Psr\Http\Message\UploadedFileInterface;
7 use RuntimeException;
8
9 class UploadedFile implements UploadedFileInterface
10 {
11 /**
12 * @var int[]
13 */
14 private static $errors = [
15 UPLOAD_ERR_OK,
16 UPLOAD_ERR_INI_SIZE,
17 UPLOAD_ERR_FORM_SIZE,
18 UPLOAD_ERR_PARTIAL,
19 UPLOAD_ERR_NO_FILE,
20 UPLOAD_ERR_NO_TMP_DIR,
21 UPLOAD_ERR_CANT_WRITE,
22 UPLOAD_ERR_EXTENSION,
23 ];
24
25 /**
26 * @var string
27 */
28 private $clientFilename;
29
30 /**
31 * @var string
32 */
33 private $clientMediaType;
34
35 /**
36 * @var int
37 */
38 private $error;
39
40 /**
41 * @var null|string
42 */
43 private $file;
44
45 /**
46 * @var bool
47 */
48 private $moved = false;
49
50 /**
51 * @var int
52 */
53 private $size;
54
55 /**
56 * @var StreamInterface|null
57 */
58 private $stream;
59
60 /**
61 * @param StreamInterface|string|resource $streamOrFile
62 * @param int $size
63 * @param int $errorStatus
64 * @param string|null $clientFilename
65 * @param string|null $clientMediaType
66 */
67 public function __construct(
68 $streamOrFile,
69 $size,
70 $errorStatus,
71 $clientFilename = null,
72 $clientMediaType = null
73 ) {
74 $this->setError($errorStatus);
75 $this->setSize($size);
76 $this->setClientFilename($clientFilename);
77 $this->setClientMediaType($clientMediaType);
78
79 if ($this->isOk()) {
80 $this->setStreamOrFile($streamOrFile);
81 }
82 }
83
84 /**
85 * Depending on the value set file or stream variable
86 *
87 * @param mixed $streamOrFile
88 * @throws InvalidArgumentException
89 */
90 private function setStreamOrFile($streamOrFile)
91 {
92 if (is_string($streamOrFile)) {
93 $this->file = $streamOrFile;
94 } elseif (is_resource($streamOrFile)) {
95 $this->stream = new Stream($streamOrFile);
96 } elseif ($streamOrFile instanceof StreamInterface) {
97 $this->stream = $streamOrFile;
98 } else {
99 throw new InvalidArgumentException(
100 'Invalid stream or file provided for UploadedFile'
101 );
102 }
103 }
104
105 /**
106 * @param int $error
107 * @throws InvalidArgumentException
108 */
109 private function setError($error)
110 {
111 if (false === is_int($error)) {
112 throw new InvalidArgumentException(
113 'Upload file error status must be an integer'
114 );
115 }
116
117 if (false === in_array($error, UploadedFile::$errors)) {
118 throw new InvalidArgumentException(
119 'Invalid error status for UploadedFile'
120 );
121 }
122
123 $this->error = $error;
124 }
125
126 /**
127 * @param int $size
128 * @throws InvalidArgumentException
129 */
130 private function setSize($size)
131 {
132 if (false === is_int($size)) {
133 throw new InvalidArgumentException(
134 'Upload file size must be an integer'
135 );
136 }
137
138 $this->size = $size;
139 }
140
141 /**
142 * @param mixed $param
143 * @return boolean
144 */
145 private function isStringOrNull($param)
146 {
147 return in_array(gettype($param), ['string', 'NULL']);
148 }
149
150 /**
151 * @param mixed $param
152 * @return boolean
153 */
154 private function isStringNotEmpty($param)
155 {
156 return is_string($param) && false === empty($param);
157 }
158
159 /**
160 * @param string|null $clientFilename
161 * @throws InvalidArgumentException
162 */
163 private function setClientFilename($clientFilename)
164 {
165 if (false === $this->isStringOrNull($clientFilename)) {
166 throw new InvalidArgumentException(
167 'Upload file client filename must be a string or null'
168 );
169 }
170
171 $this->clientFilename = $clientFilename;
172 }
173
174 /**
175 * @param string|null $clientMediaType
176 * @throws InvalidArgumentException
177 */
178 private function setClientMediaType($clientMediaType)
179 {
180 if (false === $this->isStringOrNull($clientMediaType)) {
181 throw new InvalidArgumentException(
182 'Upload file client media type must be a string or null'
183 );
184 }
185
186 $this->clientMediaType = $clientMediaType;
187 }
188
189 /**
190 * Return true if there is no upload error
191 *
192 * @return boolean
193 */
194 private function isOk()
195 {
196 return $this->error === UPLOAD_ERR_OK;
197 }
198
199 /**
200 * @return boolean
201 */
202 public function isMoved()
203 {
204 return $this->moved;
205 }
206
207 /**
208 * @throws RuntimeException if is moved or not ok
209 */
210 private function validateActive()
211 {
212 if (false === $this->isOk()) {
213 throw new RuntimeException('Cannot retrieve stream due to upload error');
214 }
215
216 if ($this->isMoved()) {
217 throw new RuntimeException('Cannot retrieve stream after it has already been moved');
218 }
219 }
220
221 /**
222 * {@inheritdoc}
223 * @throws RuntimeException if the upload was not successful.
224 */
225 public function getStream()
226 {
227 $this->validateActive();
228
229 if ($this->stream instanceof StreamInterface) {
230 return $this->stream;
231 }
232
233 return new LazyOpenStream($this->file, 'r+');
234 }
235
236 /**
237 * {@inheritdoc}
238 *
239 * @see http://php.net/is_uploaded_file
240 * @see http://php.net/move_uploaded_file
241 * @param string $targetPath Path to which to move the uploaded file.
242 * @throws RuntimeException if the upload was not successful.
243 * @throws InvalidArgumentException if the $path specified is invalid.
244 * @throws RuntimeException on any error during the move operation, or on
245 * the second or subsequent call to the method.
246 */
247 public function moveTo($targetPath)
248 {
249 $this->validateActive();
250
251 if (false === $this->isStringNotEmpty($targetPath)) {
252 throw new InvalidArgumentException(
253 'Invalid path provided for move operation; must be a non-empty string'
254 );
255 }
256
257 if ($this->file) {
258 $this->moved = php_sapi_name() == 'cli'
259 ? rename($this->file, $targetPath)
260 : move_uploaded_file($this->file, $targetPath);
261 } else {
262 copy_to_stream(
263 $this->getStream(),
264 new LazyOpenStream($targetPath, 'w')
265 );
266
267 $this->moved = true;
268 }
269
270 if (false === $this->moved) {
271 throw new RuntimeException(
272 sprintf('Uploaded file could not be moved to %s', $targetPath)
273 );
274 }
275 }
276
277 /**
278 * {@inheritdoc}
279 *
280 * @return int|null The file size in bytes or null if unknown.
281 */
282 public function getSize()
283 {
284 return $this->size;
285 }
286
287 /**
288 * {@inheritdoc}
289 *
290 * @see http://php.net/manual/en/features.file-upload.errors.php
291 * @return int One of PHP's UPLOAD_ERR_XXX constants.
292 */
293 public function getError()
294 {
295 return $this->error;
296 }
297
298 /**
299 * {@inheritdoc}
300 *
301 * @return string|null The filename sent by the client or null if none
302 * was provided.
303 */
304 public function getClientFilename()
305 {
306 return $this->clientFilename;
307 }
308
309 /**
310 * {@inheritdoc}
311 */
312 public function getClientMediaType()
313 {
314 return $this->clientMediaType;
315 }
316 }