MediaWiki  REL1_19
UploadFromUrl.php
Go to the documentation of this file.
00001 <?php
00009 class UploadFromUrl extends UploadBase {
00010         protected $mAsync, $mUrl;
00011         protected $mIgnoreWarnings = true;
00012 
00013         protected $mTempPath, $mTmpHandle;
00014 
00023         public static function isAllowed( $user ) {
00024                 if ( !$user->isAllowed( 'upload_by_url' ) ) {
00025                         return 'upload_by_url';
00026                 }
00027                 return parent::isAllowed( $user );
00028         }
00029 
00034         public static function isEnabled() {
00035                 global $wgAllowCopyUploads;
00036                 return $wgAllowCopyUploads && parent::isEnabled();
00037         }
00038 
00048         public function initialize( $name, $url, $async = false ) {
00049                 global $wgAllowAsyncCopyUploads;
00050 
00051                 $this->mUrl = $url;
00052                 $this->mAsync = $wgAllowAsyncCopyUploads ? $async : false;
00053                 if ( $async ) {
00054                         throw new MWException( 'Asynchronous copy uploads are no longer possible as of r81612.' );
00055                 }
00056 
00057                 $tempPath = $this->mAsync ? null : $this->makeTemporaryFile();
00058                 # File size and removeTempFile will be filled in later
00059                 $this->initializePathInfo( $name, $tempPath, 0, false );
00060         }
00061 
00066         public function initializeFromRequest( &$request ) {
00067                 $desiredDestName = $request->getText( 'wpDestFile' );
00068                 if ( !$desiredDestName ) {
00069                         $desiredDestName = $request->getText( 'wpUploadFileURL' );
00070                 }
00071                 return $this->initialize(
00072                         $desiredDestName,
00073                         trim( $request->getVal( 'wpUploadFileURL' ) ),
00074                         false
00075                 );
00076         }
00077 
00082         public static function isValidRequest( $request ) {
00083                 global $wgUser;
00084 
00085                 $url = $request->getVal( 'wpUploadFileURL' );
00086                 return !empty( $url )
00087                         && Http::isValidURI( $url )
00088                         && $wgUser->isAllowed( 'upload_by_url' );
00089         }
00090 
00094         public function getSourceType() { return 'url'; }
00095 
00099         public function fetchFile() {
00100                 if ( !Http::isValidURI( $this->mUrl ) ) {
00101                         return Status::newFatal( 'http-invalid-url' );
00102                 }
00103 
00104                 if ( !$this->mAsync ) {
00105                         return $this->reallyFetchFile();
00106                 }
00107                 return Status::newGood();
00108         }
00114         protected function makeTemporaryFile() {
00115                 return tempnam( wfTempDir(), 'URL' );
00116         }
00117 
00125         public function saveTempFileChunk( $req, $buffer ) {
00126                 $nbytes = fwrite( $this->mTmpHandle, $buffer );
00127 
00128                 if ( $nbytes == strlen( $buffer ) ) {
00129                         $this->mFileSize += $nbytes;
00130                 } else {
00131                         // Well... that's not good!
00132                         fclose( $this->mTmpHandle );
00133                         $this->mTmpHandle = false;
00134                 }
00135 
00136                 return $nbytes;
00137         }
00138 
00144         protected function reallyFetchFile() {
00145                 if ( $this->mTempPath === false ) {
00146                         return Status::newFatal( 'tmp-create-error' );
00147                 }
00148 
00149                 // Note the temporary file should already be created by makeTemporaryFile()
00150                 $this->mTmpHandle = fopen( $this->mTempPath, 'wb' );
00151                 if ( !$this->mTmpHandle ) {
00152                         return Status::newFatal( 'tmp-create-error' );
00153                 }
00154 
00155                 $this->mRemoveTempFile = true;
00156                 $this->mFileSize = 0;
00157 
00158                 $req = MWHttpRequest::factory( $this->mUrl, array(
00159                         'followRedirects' => true
00160                 ) );
00161                 $req->setCallback( array( $this, 'saveTempFileChunk' ) );
00162                 $status = $req->execute();
00163 
00164                 if ( $this->mTmpHandle ) {
00165                         // File got written ok...
00166                         fclose( $this->mTmpHandle );
00167                         $this->mTmpHandle = null;
00168                 } else {
00169                         // We encountered a write error during the download...
00170                         return Status::newFatal( 'tmp-write-error' );
00171                 }
00172 
00173                 if ( !$status->isOk() ) {
00174                         return $status;
00175                 }
00176 
00177                 return $status;
00178         }
00179 
00184         public function verifyUpload() {
00185                 if ( $this->mAsync ) {
00186                         return array( 'status' => UploadBase::OK );
00187                 }
00188                 return parent::verifyUpload();
00189         }
00190 
00195         public function checkWarnings() {
00196                 if ( $this->mAsync ) {
00197                         $this->mIgnoreWarnings = false;
00198                         return array();
00199                 }
00200                 return parent::checkWarnings();
00201         }
00202 
00207         public function verifyTitlePermissions( $user ) {
00208                 if ( $this->mAsync ) {
00209                         return true;
00210                 }
00211                 return parent::verifyTitlePermissions( $user );
00212         }
00213 
00218         public function performUpload( $comment, $pageText, $watch, $user ) {
00219                 if ( $this->mAsync ) {
00220                         $sessionKey = $this->insertJob( $comment, $pageText, $watch, $user );
00221 
00222                         return Status::newFatal( 'async', $sessionKey );
00223                 }
00224 
00225                 return parent::performUpload( $comment, $pageText, $watch, $user );
00226         }
00227 
00235         protected function insertJob( $comment, $pageText, $watch, $user ) {
00236                 $sessionKey = $this->stashSession();
00237                 $job = new UploadFromUrlJob( $this->getTitle(), array(
00238                         'url' => $this->mUrl,
00239                         'comment' => $comment,
00240                         'pageText' => $pageText,
00241                         'watch' => $watch,
00242                         'userName' => $user->getName(),
00243                         'leaveMessage' => $this->mAsync == 'async-leavemessage',
00244                         'ignoreWarnings' => $this->mIgnoreWarnings,
00245                         'sessionId' => session_id(),
00246                         'sessionKey' => $sessionKey,
00247                 ) );
00248                 $job->initializeSessionData();
00249                 $job->insert();
00250                 return $sessionKey;
00251         }
00252 
00253 }