data = $data; $this->fromUpload = $fromUpload; } /** * Throw if there was an error * @throws RuntimeException */ private function checkError() { switch ( $this->data['error'] ) { case UPLOAD_ERR_OK: break; case UPLOAD_ERR_INI_SIZE: throw new RuntimeException( 'Upload exceeded maximum size' ); case UPLOAD_ERR_FORM_SIZE: throw new RuntimeException( 'Upload exceeded form-specified maximum size' ); case UPLOAD_ERR_PARTIAL: throw new RuntimeException( 'File was only partially uploaded' ); case UPLOAD_ERR_NO_FILE: throw new RuntimeException( 'No file was uploaded' ); case UPLOAD_ERR_NO_TMP_DIR: throw new RuntimeException( 'PHP has no temporary folder for storing uploaded files' ); case UPLOAD_ERR_CANT_WRITE: throw new RuntimeException( 'PHP was unable to save the uploaded file' ); case UPLOAD_ERR_EXTENSION: throw new RuntimeException( 'A PHP extension stopped the file upload' ); default: throw new RuntimeException( 'Unknown upload error code ' . $this->data['error'] ); } if ( $this->moved ) { throw new RuntimeException( 'File has already been moved' ); } if ( !isset( $this->data['tmp_name'] ) || !file_exists( $this->data['tmp_name'] ) ) { throw new RuntimeException( 'Uploaded file is missing' ); } } public function getStream() { if ( $this->stream ) { return $this->stream; } $this->checkError(); $this->stream = new UploadedFileStream( $this->data['tmp_name'] ); return $this->stream; } public function moveTo( $targetPath ) { $this->checkError(); if ( $this->fromUpload && !is_uploaded_file( $this->data['tmp_name'] ) ) { throw new RuntimeException( 'Specified file is not an uploaded file' ); } // TODO remove the function_exists check once we drop HHVM support if ( function_exists( 'error_clear_last' ) ) { error_clear_last(); } $ret = AtEase::quietCall( $this->fromUpload ? 'move_uploaded_file' : 'rename', $this->data['tmp_name'], $targetPath ); if ( $ret === false ) { $err = error_get_last(); throw new RuntimeException( "Move failed: " . ( $err['message'] ?? 'Unknown error' ) ); } $this->moved = true; if ( $this->stream ) { $this->stream->close(); $this->stream = null; } } public function getSize() { return $this->data['size'] ?? null; } public function getError() { return $this->data['error'] ?? UPLOAD_ERR_NO_FILE; } public function getClientFilename() { $ret = $this->data['name'] ?? null; return $ret === '' ? null : $ret; } public function getClientMediaType() { $ret = $this->data['type'] ?? null; return $ret === '' ? null : $ret; } }