comparison vendor/zendframework/zend-diactoros/src/UploadedFile.php @ 0:c75dbcec494b

Initial commit from drush-created site
author Chris Cannam
date Thu, 05 Jul 2018 14:24:15 +0000
parents
children 5311817fb629
comparison
equal deleted inserted replaced
-1:000000000000 0:c75dbcec494b
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
4 *
5 * @see http://github.com/zendframework/zend-diactoros for the canonical source repository
6 * @copyright Copyright (c) 2015-2016 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
8 */
9
10 namespace Zend\Diactoros;
11
12 use InvalidArgumentException;
13 use Psr\Http\Message\StreamInterface;
14 use Psr\Http\Message\UploadedFileInterface;
15 use RuntimeException;
16
17 class UploadedFile implements UploadedFileInterface
18 {
19 /**
20 * @var string
21 */
22 private $clientFilename;
23
24 /**
25 * @var string
26 */
27 private $clientMediaType;
28
29 /**
30 * @var int
31 */
32 private $error;
33
34 /**
35 * @var null|string
36 */
37 private $file;
38
39 /**
40 * @var bool
41 */
42 private $moved = false;
43
44 /**
45 * @var int
46 */
47 private $size;
48
49 /**
50 * @var null|StreamInterface
51 */
52 private $stream;
53
54 /**
55 * @param string|resource $streamOrFile
56 * @param int $size
57 * @param int $errorStatus
58 * @param string|null $clientFilename
59 * @param string|null $clientMediaType
60 * @throws InvalidArgumentException
61 */
62 public function __construct($streamOrFile, $size, $errorStatus, $clientFilename = null, $clientMediaType = null)
63 {
64 if ($errorStatus === UPLOAD_ERR_OK) {
65 if (is_string($streamOrFile)) {
66 $this->file = $streamOrFile;
67 }
68 if (is_resource($streamOrFile)) {
69 $this->stream = new Stream($streamOrFile);
70 }
71
72 if (! $this->file && ! $this->stream) {
73 if (! $streamOrFile instanceof StreamInterface) {
74 throw new InvalidArgumentException('Invalid stream or file provided for UploadedFile');
75 }
76 $this->stream = $streamOrFile;
77 }
78 }
79
80 if (! is_int($size)) {
81 throw new InvalidArgumentException('Invalid size provided for UploadedFile; must be an int');
82 }
83 $this->size = $size;
84
85 if (! is_int($errorStatus)
86 || 0 > $errorStatus
87 || 8 < $errorStatus
88 ) {
89 throw new InvalidArgumentException(
90 'Invalid error status for UploadedFile; must be an UPLOAD_ERR_* constant'
91 );
92 }
93 $this->error = $errorStatus;
94
95 if (null !== $clientFilename && ! is_string($clientFilename)) {
96 throw new InvalidArgumentException(
97 'Invalid client filename provided for UploadedFile; must be null or a string'
98 );
99 }
100 $this->clientFilename = $clientFilename;
101
102 if (null !== $clientMediaType && ! is_string($clientMediaType)) {
103 throw new InvalidArgumentException(
104 'Invalid client media type provided for UploadedFile; must be null or a string'
105 );
106 }
107 $this->clientMediaType = $clientMediaType;
108 }
109
110 /**
111 * {@inheritdoc}
112 * @throws \RuntimeException if the upload was not successful.
113 */
114 public function getStream()
115 {
116 if ($this->error !== UPLOAD_ERR_OK) {
117 throw new RuntimeException('Cannot retrieve stream due to upload error');
118 }
119
120 if ($this->moved) {
121 throw new RuntimeException('Cannot retrieve stream after it has already been moved');
122 }
123
124 if ($this->stream instanceof StreamInterface) {
125 return $this->stream;
126 }
127
128 $this->stream = new Stream($this->file);
129 return $this->stream;
130 }
131
132 /**
133 * {@inheritdoc}
134 *
135 * @see http://php.net/is_uploaded_file
136 * @see http://php.net/move_uploaded_file
137 * @param string $targetPath Path to which to move the uploaded file.
138 * @throws \RuntimeException if the upload was not successful.
139 * @throws \InvalidArgumentException if the $path specified is invalid.
140 * @throws \RuntimeException on any error during the move operation, or on
141 * the second or subsequent call to the method.
142 */
143 public function moveTo($targetPath)
144 {
145 if ($this->moved) {
146 throw new RuntimeException('Cannot move file; already moved!');
147 }
148
149 if ($this->error !== UPLOAD_ERR_OK) {
150 throw new RuntimeException('Cannot retrieve stream due to upload error');
151 }
152
153 if (! is_string($targetPath) || empty($targetPath)) {
154 throw new InvalidArgumentException(
155 'Invalid path provided for move operation; must be a non-empty string'
156 );
157 }
158
159 $targetDirectory = dirname($targetPath);
160 if (! is_dir($targetDirectory) || ! is_writable($targetDirectory)) {
161 throw new RuntimeException(sprintf(
162 'The target directory `%s` does not exists or is not writable',
163 $targetDirectory
164 ));
165 }
166
167 $sapi = PHP_SAPI;
168 switch (true) {
169 case (empty($sapi) || 0 === strpos($sapi, 'cli') || ! $this->file):
170 // Non-SAPI environment, or no filename present
171 $this->writeFile($targetPath);
172 break;
173 default:
174 // SAPI environment, with file present
175 if (false === move_uploaded_file($this->file, $targetPath)) {
176 throw new RuntimeException('Error occurred while moving uploaded file');
177 }
178 break;
179 }
180
181 $this->moved = true;
182 }
183
184 /**
185 * {@inheritdoc}
186 *
187 * @return int|null The file size in bytes or null if unknown.
188 */
189 public function getSize()
190 {
191 return $this->size;
192 }
193
194 /**
195 * {@inheritdoc}
196 *
197 * @see http://php.net/manual/en/features.file-upload.errors.php
198 * @return int One of PHP's UPLOAD_ERR_XXX constants.
199 */
200 public function getError()
201 {
202 return $this->error;
203 }
204
205 /**
206 * {@inheritdoc}
207 *
208 * @return string|null The filename sent by the client or null if none
209 * was provided.
210 */
211 public function getClientFilename()
212 {
213 return $this->clientFilename;
214 }
215
216 /**
217 * {@inheritdoc}
218 */
219 public function getClientMediaType()
220 {
221 return $this->clientMediaType;
222 }
223
224 /**
225 * Write internal stream to given path
226 *
227 * @param string $path
228 */
229 private function writeFile($path)
230 {
231 $handle = fopen($path, 'wb+');
232 if (false === $handle) {
233 throw new RuntimeException('Unable to write to designated path');
234 }
235
236 $stream = $this->getStream();
237 $stream->rewind();
238 while (! $stream->eof()) {
239 fwrite($handle, $stream->read(4096));
240 }
241
242 fclose($handle);
243 }
244 }