00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 if ( !defined( 'MEDIAWIKI' ) ) {
00025
00026 require_once( "ApiBase.php" );
00027 }
00028
00032 class ApiUpload extends ApiBase {
00033 protected $mUpload = null;
00034 protected $mParams;
00035
00036 public function __construct( $main, $action ) {
00037 parent::__construct( $main, $action );
00038 }
00039
00040 public function execute() {
00041 global $wgUser, $wgAllowCopyUploads;
00042
00043
00044 if ( !UploadBase::isEnabled() )
00045 $this->dieUsageMsg( array( 'uploaddisabled' ) );
00046
00047 $this->mParams = $this->extractRequestParams();
00048 $request = $this->getMain()->getRequest();
00049
00050
00051 $this->mParams['file'] = $request->getFileName( 'file' );
00052
00053
00054 $this->requireOnlyOneParameter( $this->mParams,
00055 'sessionkey', 'file', 'url' );
00056
00057 if ( $this->mParams['sessionkey'] ) {
00061
00062 if ( !isset( $_SESSION['wsUploadData'][$this->mParams['sessionkey']] ) )
00063 $this->dieUsageMsg( array( 'invalid-session-key' ) );
00064
00065 $this->mUpload = new UploadFromStash();
00066 $this->mUpload->initialize( $this->mParams['filename'],
00067 $this->mParams['sessionkey'],
00068 $_SESSION['wsUploadData'][$this->mParams['sessionkey']] );
00069 } elseif ( isset( $this->mParams['filename'] ) ) {
00075 if ( isset( $this->mParams['file'] ) ) {
00076 $this->mUpload = new UploadFromFile();
00077 $this->mUpload->initialize(
00078 $this->mParams['filename'],
00079 $request->getFileTempName( 'file' ),
00080 $request->getFileSize( 'file' )
00081 );
00082 } elseif ( isset( $this->mParams['url'] ) ) {
00083
00084 if ( !$wgAllowCopyUploads )
00085 $this->dieUsageMsg( array( 'uploaddisabled' ) );
00086
00087
00088 if ( ! $wgUser->isAllowed( 'upload_by_url' ) )
00089 $this->dieUsageMsg( array( 'badaccess-groups' ) );
00090
00091 $this->mUpload = new UploadFromUrl();
00092 $this->mUpload->initialize( $this->mParams['filename'],
00093 $this->mParams['url'] );
00094
00095 $status = $this->mUpload->fetchFile();
00096 if ( !$status->isOK() ) {
00097 $this->dieUsage( $status->getWikiText(), 'fetchfileerror' );
00098 }
00099 }
00100 } else $this->dieUsageMsg( array( 'missingparam', 'filename' ) );
00101
00102 if ( !isset( $this->mUpload ) )
00103 $this->dieUsage( 'No upload module set', 'nomodule' );
00104
00105
00106 $permission = $this->mUpload->isAllowed( $wgUser );
00107
00108 if ( $permission !== true ) {
00109 if ( !$wgUser->isLoggedIn() )
00110 $this->dieUsageMsg( array( 'mustbeloggedin', 'upload' ) );
00111 else
00112 $this->dieUsageMsg( array( 'badaccess-groups' ) );
00113 }
00114
00115 $result = $this->performUpload();
00116
00117
00118 $this->mUpload->cleanupTempFile();
00119
00120 $this->getResult()->addValue( null, $this->getModuleName(), $result );
00121 }
00122
00123 protected function performUpload() {
00124 global $wgUser;
00125 $result = array();
00126 $permErrors = $this->mUpload->verifyPermissions( $wgUser );
00127 if ( $permErrors !== true ) {
00128 $this->dieUsageMsg( array( 'badaccess-groups' ) );
00129 }
00130
00131
00132 $verification = $this->mUpload->verifyUpload();
00133 if ( $verification['status'] !== UploadBase::OK ) {
00134 $result['result'] = 'Failure';
00135 switch( $verification['status'] ) {
00136 case UploadBase::EMPTY_FILE:
00137 $this->dieUsage( 'The file you submitted was empty', 'empty-file' );
00138 break;
00139 case UploadBase::FILETYPE_MISSING:
00140 $this->dieUsage( 'The file is missing an extension', 'filetype-missing' );
00141 break;
00142 case UploadBase::FILETYPE_BADTYPE:
00143 global $wgFileExtensions;
00144 $this->dieUsage( 'This type of file is banned', 'filetype-banned',
00145 0, array(
00146 'filetype' => $verification['finalExt'],
00147 'allowed' => $wgFileExtensions
00148 ) );
00149 break;
00150 case UploadBase::MIN_LENGTH_PARTNAME:
00151 $this->dieUsage( 'The filename is too short', 'filename-tooshort' );
00152 break;
00153 case UploadBase::ILLEGAL_FILENAME:
00154 $this->dieUsage( 'The filename is not allowed', 'illegal-filename',
00155 0, array( 'filename' => $verification['filtered'] ) );
00156 break;
00157 case UploadBase::OVERWRITE_EXISTING_FILE:
00158 $this->dieUsage( 'Overwriting an existing file is not allowed', 'overwrite' );
00159 break;
00160 case UploadBase::VERIFICATION_ERROR:
00161 $this->getResult()->setIndexedTagName( $verification['details'], 'detail' );
00162 $this->dieUsage( 'This file did not pass file verification', 'verification-error',
00163 0, array( 'details' => $verification['details'] ) );
00164 break;
00165 case UploadBase::HOOK_ABORTED:
00166 $this->dieUsage( "The modification you tried to make was aborted by an extension hook",
00167 'hookaborted', 0, array( 'error' => $verification['error'] ) );
00168 break;
00169 default:
00170 $this->dieUsage( 'An unknown error occurred', 'unknown-error',
00171 0, array( 'code' => $verification['status'] ) );
00172 break;
00173 }
00174 return $result;
00175 }
00176 if ( !$this->mParams['ignorewarnings'] ) {
00177 $warnings = $this->mUpload->checkWarnings();
00178 if ( $warnings ) {
00179
00180 $this->getResult()->setIndexedTagName( $warnings, 'warning' );
00181
00182 if ( isset( $warnings['duplicate'] ) ) {
00183 $dupes = array();
00184 foreach ( $warnings['duplicate'] as $key => $dupe )
00185 $dupes[] = $dupe->getName();
00186 $this->getResult()->setIndexedTagName( $dupes, 'duplicate' );
00187 $warnings['duplicate'] = $dupes;
00188 }
00189
00190
00191 if ( isset( $warnings['exists'] ) ) {
00192 $warning = $warnings['exists'];
00193 unset( $warnings['exists'] );
00194 $warnings[$warning['warning']] = $warning['file']->getName();
00195 }
00196
00197 $result['result'] = 'Warning';
00198 $result['warnings'] = $warnings;
00199
00200 $sessionKey = $this->mUpload->stashSession();
00201 if ( !$sessionKey )
00202 $this->dieUsage( 'Stashing temporary file failed', 'stashfailed' );
00203
00204 $result['sessionkey'] = $sessionKey;
00205
00206 return $result;
00207 }
00208 }
00209
00210
00211 if ( is_null( $this->mParams['text'] ) )
00212 $this->mParams['text'] = $this->mParams['comment'];
00213
00214
00215 $status = $this->mUpload->performUpload( $this->mParams['comment'],
00216 $this->mParams['text'], $this->mParams['watch'], $wgUser );
00217
00218 if ( !$status->isGood() ) {
00219 $error = $status->getErrorsArray();
00220 $this->getResult()->setIndexedTagName( $result['details'], 'error' );
00221
00222 $this->dieUsage( 'An internal error occurred', 'internal-error', 0, $error );
00223 }
00224
00225 $file = $this->mUpload->getLocalFile();
00226 $result['result'] = 'Success';
00227 $result['filename'] = $file->getName();
00228 $result['imageinfo'] = $this->mUpload->getImageInfo( $this->getResult() );
00229
00230 return $result;
00231 }
00232
00233 public function mustBePosted() {
00234 return true;
00235 }
00236
00237 public function isWriteMode() {
00238 return true;
00239 }
00240
00241 public function getAllowedParams() {
00242 $params = array(
00243 'filename' => null,
00244 'comment' => array(
00245 ApiBase::PARAM_DFLT => ''
00246 ),
00247 'text' => null,
00248 'token' => null,
00249 'watch' => false,
00250 'ignorewarnings' => false,
00251 'file' => null,
00252 'url' => null,
00253 'sessionkey' => null,
00254 );
00255 return $params;
00256
00257 }
00258
00259 public function getParamDescription() {
00260 return array(
00261 'filename' => 'Target filename',
00262 'token' => 'Edit token. You can get one of these through prop=info',
00263 'comment' => 'Upload comment. Also used as the initial page text for new files if "text" is not specified',
00264 'text' => 'Initial page text for new files',
00265 'watch' => 'Watch the page',
00266 'ignorewarnings' => 'Ignore any warnings',
00267 'file' => 'File contents',
00268 'url' => 'Url to fetch the file from',
00269 'sessionkey' => array(
00270 'Session key returned by a previous upload that failed due to warnings',
00271 ),
00272 );
00273 }
00274
00275 public function getDescription() {
00276 return array(
00277 'Upload a file, or get the status of pending uploads. Several methods are available:',
00278 ' * Upload file contents directly, using the "file" parameter',
00279 ' * Have the MediaWiki server fetch a file from a URL, using the "url" parameter',
00280 ' * Complete an earlier upload that failed due to warnings, using the "sessionkey" parameter',
00281 'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
00282 'sending the "file". Note also that queries using session keys must be',
00283 'done in the same login session as the query that originally returned the key (i.e. do not',
00284 'log out and then log back in). Also you must get and send an edit token before doing any upload stuff.'
00285 );
00286 }
00287
00288 public function getPossibleErrors() {
00289 return array_merge( parent::getPossibleErrors(), array(
00290 array( 'uploaddisabled' ),
00291 array( 'invalid-session-key' ),
00292 array( 'uploaddisabled' ),
00293 array( 'badaccess-groups' ),
00294 array( 'missingparam', 'filename' ),
00295 array( 'mustbeloggedin', 'upload' ),
00296 array( 'badaccess-groups' ),
00297 array( 'badaccess-groups' ),
00298 array( 'code' => 'fetchfileerror', 'info' => '' ),
00299 array( 'code' => 'nomodule', 'info' => 'No upload module set' ),
00300 array( 'code' => 'empty-file', 'info' => 'The file you submitted was empty' ),
00301 array( 'code' => 'filetype-missing', 'info' => 'The file is missing an extension' ),
00302 array( 'code' => 'filename-tooshort', 'info' => 'The filename is too short' ),
00303 array( 'code' => 'overwrite', 'info' => 'Overwriting an existing file is not allowed' ),
00304 array( 'code' => 'stashfailed', 'info' => 'Stashing temporary file failed' ),
00305 array( 'code' => 'internal-error', 'info' => 'An internal error occurred' ),
00306 ) );
00307 }
00308
00309 public function needsToken() {
00310 return true;
00311 }
00312
00313 public function getTokenSalt() {
00314 return '';
00315 }
00316
00317 protected function getExamples() {
00318 return array(
00319 'Upload from a URL:',
00320 ' api.php?action=upload&filename=Wiki.png&url=http%3A//upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png',
00321 'Complete an upload that failed due to warnings:',
00322 ' api.php?action=upload&filename=Wiki.png&sessionkey=sessionkey&ignorewarnings=1',
00323 );
00324 }
00325
00326 public function getVersion() {
00327 return __CLASS__ . ': $Id: ApiUpload.php 51812 2009-06-12 23:45:20Z dale $';
00328 }
00329 }