<?php
/**
- * Implements uploading from chunks
+ * Backend for uploading files from chunks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
- * @ingroup upload
- * @author Michael Dale
+ * @ingroup Upload
*/
+/**
+ * Implements uploading from chunks
+ *
+ * @ingroup Upload
+ * @author Michael Dale
+ */
class UploadFromChunks extends UploadFromFile {
protected $mOffset, $mChunkIndex, $mFileKey, $mVirtualTempPath;
$metadata = $this->stash->getMetadata( $key );
$this->initializePathInfo( $name,
- $this->getRealPath ( $metadata['us_path'] ),
+ $this->getRealPath( $metadata['us_path'] ),
$metadata['us_size'],
false
);
/**
* Append the final chunk and ready file for parent::performUpload()
- * @return void
+ * @return FileRepoStatus
*/
public function concatenateChunks() {
wfDebug( __METHOD__ . " concatenate {$this->mChunkIndex} chunks:" .
- $this->getOffset() . ' inx:' . $this->getChunkIndex() . "\n" );
-
+ $this->getOffset() . ' inx:' . $this->getChunkIndex() . "\n" );
+
// Concatenate all the chunks to mVirtualTempPath
$fileList = Array();
// The first chunk is stored at the mVirtualTempPath path so we start on "chunk 1"
$fileList[] = $this->getVirtualChunkLocation( $i );
}
- // Concatenate into the mVirtualTempPath location;
- $status = $this->repo->concatenate( $fileList, $this->mVirtualTempPath, FileRepo::DELETE_SOURCE );
+ // Get the file extension from the last chunk
+ $ext = FileBackend::extensionFromPath( $this->mVirtualTempPath );
+ // Get a 0-byte temp file to perform the concatenation at
+ $tmpFile = TempFSFile::factory( 'chunkedupload_', $ext );
+ $tmpPath = $tmpFile
+ ? $tmpFile->getPath()
+ : false; // fail in concatenate()
+ // Concatenate the chunks at the temp file
+ $status = $this->repo->concatenate( $fileList, $tmpPath, FileRepo::DELETE_SOURCE );
if( !$status->isOk() ){
return $status;
}
- // Update the mTempPath variable ( for FileUpload or normal Stash to take over )
- $this->mTempPath = $this->getRealPath( $this->mVirtualTempPath );
+ // Update the mTempPath and mLocalFile
+ // ( for FileUpload or normal Stash to take over )
+ $this->mTempPath = $tmpPath; // file system path
+ $this->mLocalFile = parent::stashFile();
+
return $status;
}
*/
public function performUpload( $comment, $pageText, $watch, $user ) {
$rv = parent::performUpload( $comment, $pageText, $watch, $user );
- $this->repo->freeTemp( $this->mVirtualTempPath );
return $rv;
}
/**
* Returns the virtual chunk location:
- * @param unknown_type $index
+ * @param $index
+ * @return string
*/
function getVirtualChunkLocation( $index ){
return $this->repo->getVirtualUrl( 'temp' ) .
) .
$this->getChunkFileKey( $index );
}
+
/**
* Add a chunk to the temporary directory
*
- * @param $chunkPath path to temporary chunk file
- * @param $chunkSize size of the current chunk
- * @param $offset offset of current chunk ( mutch match database chunk offset )
+ * @param $chunkPath string path to temporary chunk file
+ * @param $chunkSize int size of the current chunk
+ * @param $offset int offset of current chunk ( mutch match database chunk offset )
* @return Status
*/
public function addChunk( $chunkPath, $chunkSize, $offset ) {
/**
* Output the chunk to disk
*
- * @param $chunk
- * @param unknown_type $path
+ * @param $chunkPath string
+ * @return FileRepoStatus
*/
private function outputChunk( $chunkPath ){
// Key is fileKey + chunk index
$fileKey = $this->getChunkFileKey();
// Store the chunk per its indexed fileKey:
- $hashPath = $this->repo->getHashPath( $fileKey );
+ $hashPath = $this->repo->getHashPath( $fileKey );
$storeStatus = $this->repo->store( $chunkPath, 'temp', "$hashPath$fileKey" );
// Check for error in stashing the chunk:
$error = array( 'unknown', 'no error recorded' );
}
}
- throw new UploadChunkFileException( "error storing file in '$path': " . implode( '; ', $error ) );
+ throw new UploadChunkFileException( "error storing file in '$chunkPath': " . implode( '; ', $error ) );
}
return $storeStatus;
}