MediaWiki  REL1_24
PublishStashedFileJob.php
Go to the documentation of this file.
00001 <?php
00029 class PublishStashedFileJob extends Job {
00030     public function __construct( $title, $params ) {
00031         parent::__construct( 'PublishStashedFile', $title, $params );
00032         $this->removeDuplicates = true;
00033     }
00034 
00035     public function run() {
00036         $scope = RequestContext::importScopedSession( $this->params['session'] );
00037         $context = RequestContext::getMain();
00038         try {
00039             $user = $context->getUser();
00040             if ( !$user->isLoggedIn() ) {
00041                 $this->setLastError( "Could not load the author user from session." );
00042 
00043                 return false;
00044             }
00045 
00046             if ( count( $_SESSION ) === 0 ) {
00047                 // Empty session probably indicates that we didn't associate
00048                 // with the session correctly. Note that being able to load
00049                 // the user does not necessarily mean the session was loaded.
00050                 // Most likely cause by suhosin.session.encrypt = On.
00051                 $this->setLastError( "Error associating with user session. " .
00052                     "Try setting suhosin.session.encrypt = Off" );
00053 
00054                 return false;
00055             }
00056 
00057             UploadBase::setSessionStatus(
00058                 $this->params['filekey'],
00059                 array( 'result' => 'Poll', 'stage' => 'publish', 'status' => Status::newGood() )
00060             );
00061 
00062             $upload = new UploadFromStash( $user );
00063             // @todo initialize() causes a GET, ideally we could frontload the antivirus
00064             // checks and anything else to the stash stage (which includes concatenation and
00065             // the local file is thus already there). That way, instead of GET+PUT, there could
00066             // just be a COPY operation from the stash to the public zone.
00067             $upload->initialize( $this->params['filekey'], $this->params['filename'] );
00068 
00069             // Check if the local file checks out (this is generally a no-op)
00070             $verification = $upload->verifyUpload();
00071             if ( $verification['status'] !== UploadBase::OK ) {
00072                 $status = Status::newFatal( 'verification-error' );
00073                 $status->value = array( 'verification' => $verification );
00074                 UploadBase::setSessionStatus(
00075                     $this->params['filekey'],
00076                     array( 'result' => 'Failure', 'stage' => 'publish', 'status' => $status )
00077                 );
00078                 $this->setLastError( "Could not verify upload." );
00079 
00080                 return false;
00081             }
00082 
00083             // Upload the stashed file to a permanent location
00084             $status = $upload->performUpload(
00085                 $this->params['comment'],
00086                 $this->params['text'],
00087                 $this->params['watch'],
00088                 $user
00089             );
00090             if ( !$status->isGood() ) {
00091                 UploadBase::setSessionStatus(
00092                     $this->params['filekey'],
00093                     array( 'result' => 'Failure', 'stage' => 'publish', 'status' => $status )
00094                 );
00095                 $this->setLastError( $status->getWikiText() );
00096 
00097                 return false;
00098             }
00099 
00100             // Build the image info array while we have the local reference handy
00101             $apiMain = new ApiMain(); // dummy object (XXX)
00102             $imageInfo = $upload->getImageInfo( $apiMain->getResult() );
00103 
00104             // Cleanup any temporary local file
00105             $upload->cleanupTempFile();
00106 
00107             // Cache the info so the user doesn't have to wait forever to get the final info
00108             UploadBase::setSessionStatus(
00109                 $this->params['filekey'],
00110                 array(
00111                     'result' => 'Success',
00112                     'stage' => 'publish',
00113                     'filename' => $upload->getLocalFile()->getName(),
00114                     'imageinfo' => $imageInfo,
00115                     'status' => Status::newGood()
00116                 )
00117             );
00118         } catch ( MWException $e ) {
00119             UploadBase::setSessionStatus(
00120                 $this->params['filekey'],
00121                 array(
00122                     'result' => 'Failure',
00123                     'stage' => 'publish',
00124                     'status' => Status::newFatal( 'api-error-publishfailed' )
00125                 )
00126             );
00127             $this->setLastError( get_class( $e ) . ": " . $e->getText() );
00128             // To prevent potential database referential integrity issues.
00129             // See bug 32551.
00130             MWExceptionHandler::rollbackMasterChangesAndLog( $e );
00131 
00132             return false;
00133         }
00134 
00135         return true;
00136     }
00137 
00138     public function getDeduplicationInfo() {
00139         $info = parent::getDeduplicationInfo();
00140         if ( is_array( $info['params'] ) ) {
00141             $info['params'] = array( 'filekey' => $info['params']['filekey'] );
00142         }
00143 
00144         return $info;
00145     }
00146 
00147     public function allowRetries() {
00148         return false;
00149     }
00150 }