Merge "Revert "Adding sanity check to Title::isRedirect().""
[lhc/web/wiklou.git] / includes / upload / UploadFromChunks.php
index 3a5f809..e50c6da 100644 (file)
@@ -1,12 +1,32 @@
 <?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;
        
@@ -74,7 +94,7 @@ class UploadFromChunks extends UploadFromFile {
                
                $metadata = $this->stash->getMetadata( $key );
                $this->initializePathInfo( $name,
-                       $this->getRealPath ( $metadata['us_path'] ),
+                       $this->getRealPath( $metadata['us_path'] ),
                        $metadata['us_size'],
                        false
                );
@@ -82,12 +102,12 @@ class UploadFromChunks extends UploadFromFile {
        
        /**
         * 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"
@@ -95,13 +115,23 @@ class UploadFromChunks extends UploadFromFile {
                        $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;
        }
 
@@ -115,13 +145,13 @@ class UploadFromChunks extends UploadFromFile {
         */
        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' ) . 
@@ -131,12 +161,13 @@ class UploadFromChunks extends UploadFromFile {
                                ) . 
                                $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 ) {
@@ -232,15 +263,15 @@ class UploadFromChunks extends UploadFromFile {
        /**
         * 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:
@@ -254,7 +285,7 @@ class UploadFromChunks extends UploadFromFile {
                                        $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;
        }