| Code Coverage | ||||||||||
| Classes and Traits | Functions and Methods | Lines | ||||||||
| Total |  | 0.00% | 0 / 1 |  | 80.00% | 8 / 10 | CRAP |  | 94.55% | 52 / 55 | 
| UploadedFile |  | 0.00% | 0 / 1 |  | 80.00% | 8 / 10 | 33.18 |  | 94.55% | 52 / 55 | 
| __construct |  | 100.00% | 1 / 1 | 13 |  | 100.00% | 21 / 21 | |||
| createBy_FILE |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 1 / 1 | |||
| getStream |  | 100.00% | 1 / 1 | 4 |  | 100.00% | 8 / 8 | |||
| moveTo |  | 0.00% | 0 / 1 | 6.29 |  | 80.00% | 8 / 10 | |||
| getSize |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 1 / 1 | |||
| getError |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 1 / 1 | |||
| getClientFilename |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 1 / 1 | |||
| getClientMediaType |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 1 / 1 | |||
| writeFile |  | 0.00% | 0 / 1 | 3.02 |  | 87.50% | 7 / 8 | |||
| isUploadOk |  | 100.00% | 1 / 1 | 2 |  | 100.00% | 3 / 3 | |||
| <?php | |
| namespace Puyo\Psr7; | |
| /** | |
| * PSR-7 の UploadedFileInterface の実装 | |
| * | |
| * アップロードされたファイル1件の抽象化。 | |
| */ | |
| class UploadedFile implements \Psr\Http\Message\UploadedFileInterface | |
| { | |
| /** @var string */ | |
| private $clientFilename; | |
| /** @var string */ | |
| private $clientMediaType; | |
| /** @var int */ | |
| private $errorCode; | |
| /** @var string|null */ | |
| private $file; | |
| /** @var bool */ | |
| private $moved = false; | |
| /** @var int */ | |
| private $size; | |
| /** @var \Psr\Http\Message\StreamInterface */ | |
| private $stream; | |
| /** | |
| * @param string|resource|\Psr\Http\Message\StreamInterface $streamOrFile | |
| * @param int $size UPLOAD_ERR_* constant | |
| * @param int $errorCode | |
| * @param string $clientFilename | |
| * @param string $clientMediaType | |
| */ | |
| public function __construct($streamOrFile, $size, $errorCode, $clientFilename=null, $clientMediaType=null) { | |
| if($errorCode === UPLOAD_ERR_OK) { | |
| if(is_string($streamOrFile)) { | |
| $this->file = $streamOrFile; | |
| } elseif(is_resource($streamOrFile)) { | |
| $this->stream = new Stream($streamOrFile); | |
| } elseif($streamOrFile instanceof \Psr\Http\Message\StreamInterface) { | |
| $this->stream = $streamOrFile; | |
| } else { | |
| throw new \InvalidArgumentException('Invalid stream or file provided for UploadedFile'); | |
| } | |
| } | |
| if(!is_int($size)) { | |
| throw new \InvalidArgumentException('size must be an int'); | |
| } | |
| $this->size = $size; | |
| if(!is_int($errorCode) || $errorCode < UPLOAD_ERR_OK || $errorCode > UPLOAD_ERR_EXTENSION) { | |
| throw new \InvalidArgumentException('error must be an UPLOAD_ERR_* constant'); | |
| } | |
| $this->errorCode = $errorCode; | |
| if($clientFilename !== null && !is_string($clientFilename)) { | |
| throw new \InvalidArgumentException('name must be a string'); | |
| } | |
| $this->clientFilename = $clientFilename; | |
| if($clientMediaType !== null && !is_string($clientMediaType)) { | |
| throw new \InvalidArgumentException('type must be a string'); | |
| } | |
| $this->clientMediaType = $clientMediaType; | |
| } | |
| /** | |
| * $_FILES の1件分から作成する | |
| * @param array $file | |
| * @return \Puyo\Psr7\UploadedFile | |
| */ | |
| public static function createBy_FILE(array $file) { | |
| return new UploadedFile($file['tmp_name'], $file['size'], $file['error'], $file['name'], $file['type']); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| * @return \Psr\Http\Message\StreamInterface | |
| * @throws \RuntimeException if the upload was not successful. | |
| */ | |
| public function getStream() { | |
| if(!$this->isUploadOk()) { | |
| throw new \RuntimeException('Cannot retrieve stream due to upload error'); | |
| } | |
| if($this->moved) { | |
| throw new \RuntimeException('Cannot retrieve stream after it has already been moved'); | |
| } | |
| if($this->stream instanceof \Psr\Http\Message\StreamInterface) { | |
| return $this->stream; | |
| } | |
| $this->stream = new Stream($this->file); | |
| return $this->stream; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| * @param string $targetPath | |
| */ | |
| public function moveTo($targetPath) { | |
| if(!$this->isUploadOk()) { | |
| throw new \RuntimeException('Cannot retrieve stream due to upload error'); | |
| } | |
| if($this->moved) { | |
| throw new \RuntimeException('Cannot move file. already moved.'); | |
| } | |
| if(PHP_SAPI === 'cli' || empty(PHP_SAPI)) { | |
| $this->writeFile($targetPath); | |
| } else { | |
| if(!move_uploaded_file($this->file, $targetPath)) { | |
| throw new \RuntimeException('Cannot moving uploaded file'); | |
| } | |
| } | |
| $this->moved = true; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| * @return int | |
| */ | |
| public function getSize() { | |
| return $this->size; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| * @return int | |
| */ | |
| public function getError() { | |
| return $this->errorCode; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| * @return string | |
| */ | |
| public function getClientFilename() { | |
| return $this->clientFilename; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| * @return string | |
| */ | |
| public function getClientMediaType() { | |
| return $this->clientMediaType; | |
| } | |
| private function writeFile($path) { | |
| $fp = fopen($path, 'wb+'); | |
| if(!is_resource($fp)) { | |
| throw new \RuntimeException('Unable to write to designated path'); | |
| } | |
| $stream = $this->getStream(); | |
| while(!$stream->eof()) { | |
| fwrite($fp, $stream->read(4096)); | |
| } | |
| fclose($fp); | |
| } | |
| /** | |
| * アップロードが正常に完了したかどうかを返す | |
| * @return bool | |
| */ | |
| public function isUploadOk() { | |
| if($this->errorCode === UPLOAD_ERR_OK) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| } |