public function run()
 {
     $scope = RequestContext::importScopedSession($this->params['session']);
     $context = RequestContext::getMain();
     try {
         $user = $context->getUser();
         if (!$user->isLoggedIn()) {
             $this->setLastError("Could not load the author user from session.");
             return false;
         }
         if (count($_SESSION) === 0) {
             // Empty session probably indicates that we didn't associate
             // with the session correctly. Note that being able to load
             // the user does not necessarily mean the session was loaded.
             // Most likely cause by suhosin.session.encrypt = On.
             $this->setLastError("Error associating with user session. " . "Try setting suhosin.session.encrypt = Off");
             return false;
         }
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood()));
         $upload = new UploadFromChunks($user);
         $upload->continueChunks($this->params['filename'], $this->params['filekey'], $context->getRequest());
         // Combine all of the chunks into a local file and upload that to a new stash file
         $status = $upload->concatenateChunks();
         if (!$status->isGood()) {
             UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => $status));
             $this->setLastError($status->getWikiText());
             return false;
         }
         // We have a new filekey for the fully concatenated file
         $newFileKey = $upload->getLocalFile()->getFileKey();
         // Remove the old stash file row and first chunk file
         $upload->stash->removeFileNoAuth($this->params['filekey']);
         // Build the image info array while we have the local reference handy
         $apiMain = new ApiMain();
         // dummy object (XXX)
         $imageInfo = $upload->getImageInfo($apiMain->getResult());
         // Cleanup any temporary local file
         $upload->cleanupTempFile();
         // Cache the info so the user doesn't have to wait forever to get the final info
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => Status::newGood()));
     } catch (MWException $e) {
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed')));
         $this->setLastError(get_class($e) . ": " . $e->getText());
         // To be extra robust.
         MWExceptionHandler::rollbackMasterChangesAndLog($e);
         return false;
     }
     return true;
 }
 public function run()
 {
     $scope = RequestContext::importScopedSession($this->params['session']);
     $this->addTeardownCallback(function () use(&$scope) {
         ScopedCallback::consume($scope);
         // T126450
     });
     $context = RequestContext::getMain();
     $user = $context->getUser();
     try {
         if (!$user->isLoggedIn()) {
             $this->setLastError("Could not load the author user from session.");
             return false;
         }
         UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood()]);
         $upload = new UploadFromChunks($user);
         $upload->continueChunks($this->params['filename'], $this->params['filekey'], new WebRequestUpload($context->getRequest(), 'null'));
         // Combine all of the chunks into a local file and upload that to a new stash file
         $status = $upload->concatenateChunks();
         if (!$status->isGood()) {
             UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'assembling', 'status' => $status]);
             $this->setLastError($status->getWikiText(false, false, 'en'));
             return false;
         }
         // We can only get warnings like 'duplicate' after concatenating the chunks
         $status = Status::newGood();
         $status->value = ['warnings' => $upload->checkWarnings()];
         // We have a new filekey for the fully concatenated file
         $newFileKey = $upload->getStashFile()->getFileKey();
         // Remove the old stash file row and first chunk file
         $upload->stash->removeFileNoAuth($this->params['filekey']);
         // Build the image info array while we have the local reference handy
         $apiMain = new ApiMain();
         // dummy object (XXX)
         $imageInfo = $upload->getImageInfo($apiMain->getResult());
         // Cleanup any temporary local file
         $upload->cleanupTempFile();
         // Cache the info so the user doesn't have to wait forever to get the final info
         UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => $status]);
     } catch (Exception $e) {
         UploadBase::setSessionStatus($user, $this->params['filekey'], ['result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed')]);
         $this->setLastError(get_class($e) . ": " . $e->getMessage());
         // To be extra robust.
         MWExceptionHandler::rollbackMasterChangesAndLog($e);
         return false;
     }
     return true;
 }
 public function run()
 {
     $scope = RequestContext::importScopedSession($this->params['session']);
     $context = RequestContext::getMain();
     try {
         $user = $context->getUser();
         if (!$user->isLoggedIn()) {
             $this->setLastError("Could not load the author user from session.");
             return false;
         }
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Poll', 'stage' => 'assembling', 'status' => Status::newGood()));
         $upload = new UploadFromChunks($user);
         $upload->continueChunks($this->params['filename'], $this->params['filekey'], $context->getRequest());
         // Combine all of the chunks into a local file and upload that to a new stash file
         $status = $upload->concatenateChunks();
         if (!$status->isGood()) {
             UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => $status));
             $this->setLastError($status->getWikiText());
             return false;
         }
         // We have a new filekey for the fully concatenated file
         $newFileKey = $upload->getLocalFile()->getFileKey();
         // Remove the old stash file row and first chunk file
         $upload->stash->removeFileNoAuth($this->params['filekey']);
         // Build the image info array while we have the local reference handy
         $apiMain = new ApiMain();
         // dummy object (XXX)
         $imageInfo = $upload->getImageInfo($apiMain->getResult());
         // Cleanup any temporary local file
         $upload->cleanupTempFile();
         // Cache the info so the user doesn't have to wait forever to get the final info
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Success', 'stage' => 'assembling', 'filekey' => $newFileKey, 'imageinfo' => $imageInfo, 'status' => Status::newGood()));
     } catch (MWException $e) {
         UploadBase::setSessionStatus($this->params['filekey'], array('result' => 'Failure', 'stage' => 'assembling', 'status' => Status::newFatal('api-error-stashfailed')));
         $this->setLastError(get_class($e) . ": " . $e->getText());
         return false;
     }
     return true;
 }
Esempio n. 4
0
 /**
  * Select an upload module and set it to mUpload. Dies on failure. If the
  * request was a status request and not a true upload, returns false;
  * otherwise true
  *
  * @return bool
  */
 protected function selectUploadModule()
 {
     $request = $this->getMain()->getRequest();
     // chunk or one and only one of the following parameters is needed
     if (!$this->mParams['chunk']) {
         $this->requireOnlyOneParameter($this->mParams, 'filekey', 'file', 'url');
     }
     // Status report for "upload to stash"/"upload from stash"
     if ($this->mParams['filekey'] && $this->mParams['checkstatus']) {
         $progress = UploadBase::getSessionStatus($this->getUser(), $this->mParams['filekey']);
         if (!$progress) {
             $this->dieUsage('No result in status data', 'missingresult');
         } elseif (!$progress['status']->isGood()) {
             $this->dieUsage($progress['status']->getWikiText(false, false, 'en'), 'stashfailed');
         }
         if (isset($progress['status']->value['verification'])) {
             $this->checkVerification($progress['status']->value['verification']);
         }
         unset($progress['status']);
         // remove Status object
         $this->getResult()->addValue(null, $this->getModuleName(), $progress);
         return false;
     }
     // The following modules all require the filename parameter to be set
     if (is_null($this->mParams['filename'])) {
         $this->dieUsageMsg(['missingparam', 'filename']);
     }
     if ($this->mParams['chunk']) {
         // Chunk upload
         $this->mUpload = new UploadFromChunks();
         if (isset($this->mParams['filekey'])) {
             if ($this->mParams['offset'] === 0) {
                 $this->dieUsage('Cannot supply a filekey when offset is 0', 'badparams');
             }
             // handle new chunk
             $this->mUpload->continueChunks($this->mParams['filename'], $this->mParams['filekey'], $request->getUpload('chunk'));
         } else {
             if ($this->mParams['offset'] !== 0) {
                 $this->dieUsage('Must supply a filekey when offset is non-zero', 'badparams');
             }
             // handle first chunk
             $this->mUpload->initialize($this->mParams['filename'], $request->getUpload('chunk'));
         }
     } elseif (isset($this->mParams['filekey'])) {
         // Upload stashed in a previous request
         if (!UploadFromStash::isValidKey($this->mParams['filekey'])) {
             $this->dieUsageMsg('invalid-file-key');
         }
         $this->mUpload = new UploadFromStash($this->getUser());
         // This will not download the temp file in initialize() in async mode.
         // We still have enough information to call checkWarnings() and such.
         $this->mUpload->initialize($this->mParams['filekey'], $this->mParams['filename'], !$this->mParams['async']);
     } elseif (isset($this->mParams['file'])) {
         $this->mUpload = new UploadFromFile();
         $this->mUpload->initialize($this->mParams['filename'], $request->getUpload('file'));
     } elseif (isset($this->mParams['url'])) {
         // Make sure upload by URL is enabled:
         if (!UploadFromUrl::isEnabled()) {
             $this->dieUsageMsg('copyuploaddisabled');
         }
         if (!UploadFromUrl::isAllowedHost($this->mParams['url'])) {
             $this->dieUsageMsg('copyuploadbaddomain');
         }
         if (!UploadFromUrl::isAllowedUrl($this->mParams['url'])) {
             $this->dieUsageMsg('copyuploadbadurl');
         }
         $this->mUpload = new UploadFromUrl();
         $this->mUpload->initialize($this->mParams['filename'], $this->mParams['url']);
     }
     return true;
 }
Esempio n. 5
0
 /**
  * Select an upload module and set it to mUpload. Dies on failure. If the
  * request was a status request and not a true upload, returns false;
  * otherwise true
  *
  * @return bool
  */
 protected function selectUploadModule()
 {
     $request = $this->getMain()->getRequest();
     // chunk or one and only one of the following parameters is needed
     if (!$this->mParams['chunk']) {
         $this->requireOnlyOneParameter($this->mParams, 'filekey', 'file', 'url', 'statuskey');
     }
     // Status report for "upload to stash"/"upload from stash"
     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');
         }
         if (isset($progress['status']->value['verification'])) {
             $this->checkVerification($progress['status']->value['verification']);
         }
         unset($progress['status']);
         // remove Status object
         $this->getResult()->addValue(null, $this->getModuleName(), $progress);
         return false;
     }
     if ($this->mParams['statuskey']) {
         $this->checkAsyncDownloadEnabled();
         // Status request for an async upload
         $sessionData = UploadFromUrlJob::getSessionData($this->mParams['statuskey']);
         if (!isset($sessionData['result'])) {
             $this->dieUsage('No result in session data', 'missingresult');
         }
         if ($sessionData['result'] == 'Warning') {
             $sessionData['warnings'] = $this->transformWarnings($sessionData['warnings']);
             $sessionData['sessionkey'] = $this->mParams['statuskey'];
         }
         $this->getResult()->addValue(null, $this->getModuleName(), $sessionData);
         return false;
     }
     // The following modules all require the filename parameter to be set
     if (is_null($this->mParams['filename'])) {
         $this->dieUsageMsg(array('missingparam', 'filename'));
     }
     if ($this->mParams['chunk']) {
         // Chunk upload
         $this->mUpload = new UploadFromChunks();
         if (isset($this->mParams['filekey'])) {
             // handle new chunk
             $this->mUpload->continueChunks($this->mParams['filename'], $this->mParams['filekey'], $request->getUpload('chunk'));
         } else {
             // handle first chunk
             $this->mUpload->initialize($this->mParams['filename'], $request->getUpload('chunk'));
         }
     } elseif (isset($this->mParams['filekey'])) {
         // Upload stashed in a previous request
         if (!UploadFromStash::isValidKey($this->mParams['filekey'])) {
             $this->dieUsageMsg('invalid-file-key');
         }
         $this->mUpload = new UploadFromStash($this->getUser());
         // This will not download the temp file in initialize() in async mode.
         // We still have enough information to call checkWarnings() and such.
         $this->mUpload->initialize($this->mParams['filekey'], $this->mParams['filename'], !$this->mParams['async']);
     } elseif (isset($this->mParams['file'])) {
         $this->mUpload = new UploadFromFile();
         $this->mUpload->initialize($this->mParams['filename'], $request->getUpload('file'));
     } elseif (isset($this->mParams['url'])) {
         // Make sure upload by URL is enabled:
         if (!UploadFromUrl::isEnabled()) {
             $this->dieUsageMsg('copyuploaddisabled');
         }
         if (!UploadFromUrl::isAllowedHost($this->mParams['url'])) {
             $this->dieUsageMsg('copyuploadbaddomain');
         }
         if (!UploadFromUrl::isAllowedUrl($this->mParams['url'])) {
             $this->dieUsageMsg('copyuploadbadurl');
         }
         $async = false;
         if ($this->mParams['asyncdownload']) {
             $this->checkAsyncDownloadEnabled();
             if ($this->mParams['leavemessage'] && !$this->mParams['ignorewarnings']) {
                 $this->dieUsage('Using leavemessage without ignorewarnings is not supported', 'missing-ignorewarnings');
             }
             if ($this->mParams['leavemessage']) {
                 $async = 'async-leavemessage';
             } else {
                 $async = 'async';
             }
         }
         $this->mUpload = new UploadFromUrl();
         $this->mUpload->initialize($this->mParams['filename'], $this->mParams['url'], $async);
     }
     return true;
 }