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