Chris@0: setError($errorStatus); Chris@0: $this->setSize($size); Chris@0: $this->setClientFilename($clientFilename); Chris@0: $this->setClientMediaType($clientMediaType); Chris@0: Chris@0: if ($this->isOk()) { Chris@0: $this->setStreamOrFile($streamOrFile); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Depending on the value set file or stream variable Chris@0: * Chris@0: * @param mixed $streamOrFile Chris@0: * @throws InvalidArgumentException Chris@0: */ Chris@0: private function setStreamOrFile($streamOrFile) Chris@0: { Chris@0: if (is_string($streamOrFile)) { Chris@0: $this->file = $streamOrFile; Chris@0: } elseif (is_resource($streamOrFile)) { Chris@0: $this->stream = new Stream($streamOrFile); Chris@0: } elseif ($streamOrFile instanceof StreamInterface) { Chris@0: $this->stream = $streamOrFile; Chris@0: } else { Chris@0: throw new InvalidArgumentException( Chris@0: 'Invalid stream or file provided for UploadedFile' Chris@0: ); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * @param int $error Chris@0: * @throws InvalidArgumentException Chris@0: */ Chris@0: private function setError($error) Chris@0: { Chris@0: if (false === is_int($error)) { Chris@0: throw new InvalidArgumentException( Chris@0: 'Upload file error status must be an integer' Chris@0: ); Chris@0: } Chris@0: Chris@0: if (false === in_array($error, UploadedFile::$errors)) { Chris@0: throw new InvalidArgumentException( Chris@0: 'Invalid error status for UploadedFile' Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->error = $error; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @param int $size Chris@0: * @throws InvalidArgumentException Chris@0: */ Chris@0: private function setSize($size) Chris@0: { Chris@0: if (false === is_int($size)) { Chris@0: throw new InvalidArgumentException( Chris@0: 'Upload file size must be an integer' Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->size = $size; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @param mixed $param Chris@0: * @return boolean Chris@0: */ Chris@0: private function isStringOrNull($param) Chris@0: { Chris@0: return in_array(gettype($param), ['string', 'NULL']); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @param mixed $param Chris@0: * @return boolean Chris@0: */ Chris@0: private function isStringNotEmpty($param) Chris@0: { Chris@0: return is_string($param) && false === empty($param); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @param string|null $clientFilename Chris@0: * @throws InvalidArgumentException Chris@0: */ Chris@0: private function setClientFilename($clientFilename) Chris@0: { Chris@0: if (false === $this->isStringOrNull($clientFilename)) { Chris@0: throw new InvalidArgumentException( Chris@0: 'Upload file client filename must be a string or null' Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->clientFilename = $clientFilename; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @param string|null $clientMediaType Chris@0: * @throws InvalidArgumentException Chris@0: */ Chris@0: private function setClientMediaType($clientMediaType) Chris@0: { Chris@0: if (false === $this->isStringOrNull($clientMediaType)) { Chris@0: throw new InvalidArgumentException( Chris@0: 'Upload file client media type must be a string or null' Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->clientMediaType = $clientMediaType; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Return true if there is no upload error Chris@0: * Chris@0: * @return boolean Chris@0: */ Chris@0: private function isOk() Chris@0: { Chris@0: return $this->error === UPLOAD_ERR_OK; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @return boolean Chris@0: */ Chris@0: public function isMoved() Chris@0: { Chris@0: return $this->moved; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @throws RuntimeException if is moved or not ok Chris@0: */ Chris@0: private function validateActive() Chris@0: { Chris@0: if (false === $this->isOk()) { Chris@0: throw new RuntimeException('Cannot retrieve stream due to upload error'); Chris@0: } Chris@0: Chris@0: if ($this->isMoved()) { Chris@0: throw new RuntimeException('Cannot retrieve stream after it has already been moved'); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: * @throws RuntimeException if the upload was not successful. Chris@0: */ Chris@0: public function getStream() Chris@0: { Chris@0: $this->validateActive(); Chris@0: Chris@0: if ($this->stream instanceof StreamInterface) { Chris@0: return $this->stream; Chris@0: } Chris@0: Chris@0: return new LazyOpenStream($this->file, 'r+'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: * Chris@0: * @see http://php.net/is_uploaded_file Chris@0: * @see http://php.net/move_uploaded_file Chris@0: * @param string $targetPath Path to which to move the uploaded file. Chris@0: * @throws RuntimeException if the upload was not successful. Chris@0: * @throws InvalidArgumentException if the $path specified is invalid. Chris@0: * @throws RuntimeException on any error during the move operation, or on Chris@0: * the second or subsequent call to the method. Chris@0: */ Chris@0: public function moveTo($targetPath) Chris@0: { Chris@0: $this->validateActive(); Chris@0: Chris@0: if (false === $this->isStringNotEmpty($targetPath)) { Chris@0: throw new InvalidArgumentException( Chris@0: 'Invalid path provided for move operation; must be a non-empty string' Chris@0: ); Chris@0: } Chris@0: Chris@0: if ($this->file) { Chris@0: $this->moved = php_sapi_name() == 'cli' Chris@0: ? rename($this->file, $targetPath) Chris@0: : move_uploaded_file($this->file, $targetPath); Chris@0: } else { Chris@0: copy_to_stream( Chris@0: $this->getStream(), Chris@0: new LazyOpenStream($targetPath, 'w') Chris@0: ); Chris@0: Chris@0: $this->moved = true; Chris@0: } Chris@0: Chris@0: if (false === $this->moved) { Chris@0: throw new RuntimeException( Chris@0: sprintf('Uploaded file could not be moved to %s', $targetPath) Chris@0: ); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: * Chris@0: * @return int|null The file size in bytes or null if unknown. Chris@0: */ Chris@0: public function getSize() Chris@0: { Chris@0: return $this->size; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: * Chris@0: * @see http://php.net/manual/en/features.file-upload.errors.php Chris@0: * @return int One of PHP's UPLOAD_ERR_XXX constants. Chris@0: */ Chris@0: public function getError() Chris@0: { Chris@0: return $this->error; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: * Chris@0: * @return string|null The filename sent by the client or null if none Chris@0: * was provided. Chris@0: */ Chris@0: public function getClientFilename() Chris@0: { Chris@0: return $this->clientFilename; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getClientMediaType() Chris@0: { Chris@0: return $this->clientMediaType; Chris@0: } Chris@0: }