Cleaned up and optimized wfBaseConvert();
[lhc/web/wiklou.git] / includes / api / ApiUpload.php
index 6b8639c..d68c515 100644 (file)
@@ -114,6 +114,7 @@ class ApiUpload extends ApiBase {
                // Cleanup any temporary mess
                $this->mUpload->cleanupTempFile();
        }
+
        /**
         * Get an uplaod result based on upload context
         * @return array
@@ -179,7 +180,9 @@ class ApiUpload extends ApiBase {
         * @param $warnings array Array of Api upload warnings
         * @return array
         */
-       private function getChunkResult( $warnings ){
+       private function getChunkResult( $warnings ) {
+               global $IP;
+
                $result = array();
 
                $result['result'] = 'Continue';
@@ -192,8 +195,8 @@ class ApiUpload extends ApiBase {
                if ($this->mParams['offset'] == 0) {
                        $result['filekey'] = $this->performStash();
                } else {
-                       $status = $this->mUpload->addChunk($chunkPath, $chunkSize,
-                                                                               $this->mParams['offset']);
+                       $status = $this->mUpload->addChunk(
+                               $chunkPath, $chunkSize, $this->mParams['offset'] );
                        if ( !$status->isGood() ) {
                                $this->dieUsage( $status->getWikiText(), 'stashfailed' );
                                return array();
@@ -201,23 +204,51 @@ class ApiUpload extends ApiBase {
 
                        // Check we added the last chunk:
                        if( $this->mParams['offset'] + $chunkSize == $this->mParams['filesize'] ) {
-                               $status = $this->mUpload->concatenateChunks();
-
-                               if ( !$status->isGood() ) {
-                                       $this->dieUsage( $status->getWikiText(), 'stashfailed' );
-                                       return array();
-                               }
-
-                               // We have a new filekey for the fully concatenated file.
-                               $result['filekey'] =  $this->mUpload->getLocalFile()->getFileKey();
+                               if ( $this->mParams['async'] && !wfIsWindows() ) {
+                                       $progress = UploadBase::getSessionStatus( $this->mParams['filekey'] );
+                                       if ( $progress && $progress['result'] !== 'Failed' ) {
+                                               $this->dieUsage( "Chunk assembly already in progress.", 'stashfailed' );
+                                       }
+                                       UploadBase::setSessionStatus(
+                                               $this->mParams['filekey'],
+                                               array( 'result' => 'Poll',
+                                                       'stage' => 'queued', 'status' => Status::newGood() )
+                                       );
+                                       $retVal = 1;
+                                       $cmd = wfShellWikiCmd(
+                                               "$IP/includes/upload/AssembleUploadChunks.php",
+                                               array(
+                                                       '--filename', $this->mParams['filename'],
+                                                       '--filekey', $this->mParams['filekey'],
+                                                       '--userid', $this->getUser()->getId(),
+                                                       '--sessionid', session_id(),
+                                                       '--quiet'
+                                               )
+                                       ) . " < " . wfGetNull() . " > " . wfGetNull() . " 2>&1 &";
+                                       wfShellExec( $cmd, $retVal ); // start a process in the background
+                                       if ( $retVal == 0 ) {
+                                               $result['result'] = 'Poll';
+                                       } else {
+                                               UploadBase::setSessionStatus( $this->mParams['filekey'], false );
+                                               $this->dieUsage(
+                                                       "Failed to start AssembleUploadChunks.php", 'stashfailed' );
+                                       }
+                               } else {
+                                       $status = $this->mUpload->concatenateChunks();
+                                       if ( !$status->isGood() ) {
+                                               $this->dieUsage( $status->getWikiText(), 'stashfailed' );
+                                               return array();
+                                       }
 
-                               // Remove chunk from stash. (Checks against user ownership of chunks.)
-                               $this->mUpload->stash->removeFile( $this->mParams['filekey'] );
+                                       // We have a new filekey for the fully concatenated file.
+                                       $result['filekey'] =  $this->mUpload->getLocalFile()->getFileKey();
 
-                               $result['result'] = 'Success';
+                                       // Remove chunk from stash. (Checks against user ownership of chunks.)
+                                       $this->mUpload->stash->removeFile( $this->mParams['filekey'] );
 
+                                       $result['result'] = 'Success';
+                               }
                        } else {
-
                                // Continue passing through the filekey for adding further chunks.
                                $result['filekey'] = $this->mParams['filekey'];
                        }
@@ -281,11 +312,23 @@ class ApiUpload extends ApiBase {
                $request = $this->getMain()->getRequest();
 
                // chunk or one and only one of the following parameters is needed
-               if( !$this->mParams['chunk'] ) {
+               if ( !$this->mParams['chunk'] ) {
                        $this->requireOnlyOneParameter( $this->mParams,
                                'filekey', 'file', 'url', 'statuskey' );
                }
 
+               if ( $this->mParams['filekey'] && $this->mParams['checkstatus'] ) {
+                       $progress = UploadBase::getSessionStatus( $this->mParams['filekey'] );
+                       if ( !$progress ) {
+                               $this->dieUsage( 'No result in status data', 'missingresult' );
+                       } elseif ( !$progress['status']->isGood() ) {
+                               $this->dieUsage( $progress['status']->getWikiText(), 'stashfailed' );
+                       }
+                       unset( $progress['status'] ); // remove Status object
+                       $this->getResult()->addValue( null, $this->getModuleName(), $progress );
+                       return false;
+               }
+
                if ( $this->mParams['statuskey'] ) {
                        $this->checkAsyncDownloadEnabled();
 
@@ -300,7 +343,6 @@ class ApiUpload extends ApiBase {
                        }
                        $this->getResult()->addValue( null, $this->getModuleName(), $sessionData );
                        return false;
-
                }
 
                // The following modules all require the filename parameter to be set
@@ -612,9 +654,11 @@ class ApiUpload extends ApiBase {
                        'offset' => null,
                        'chunk' => null,
 
+                       'async' => false,
                        'asyncdownload' => false,
                        'leavemessage' => false,
                        'statuskey' => null,
+                       'checkstatus' => false,
                );
 
                return $params;
@@ -639,9 +683,11 @@ class ApiUpload extends ApiBase {
                        'offset' => 'Offset of chunk in bytes',
                        'filesize' => 'Filesize of entire upload',
 
+                       'async' => 'Make potentially large file operations asynchronous when possible',
                        'asyncdownload' => 'Make fetching a URL asynchronous',
                        'leavemessage' => 'If asyncdownload is used, leave a message on the user talk page if finished',
-                       'statuskey' => 'Fetch the upload status for this file key',
+                       'statuskey' => 'Fetch the upload status for this file key (upload by URL)',
+                       'checkstatus' => 'Only fetch the upload status for the given file key',
                );
 
                return $params;