MediaWiki
REL1_19
|
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 }