From 8bd336981cd7c138f141a45dd5806fd233907694 Mon Sep 17 00:00:00 2001 From: Bryan Tong Minh Date: Fri, 25 Mar 2011 21:22:02 +0000 Subject: [PATCH] API upload errors may now return the parameter that needs to be changed and a sessionkey to fix the error. This is for now only done for uploads that can be fixed by changing the filename, but may be extended later to comment and pagetext. --- RELEASE-NOTES | 2 ++ includes/api/ApiBase.php | 4 ++++ includes/api/ApiUpload.php | 49 ++++++++++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 64dffcb9e8..d41e9ae4c5 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -285,6 +285,8 @@ PHP if you have not done so prior to upgrading MediaWiki. * (bug 28226) prop=extlinks&eloffset should be an integer * (bug 28070) Fix watchlist RSS for databases that store timestamps in a real timestamp field. +* API upload errors may now return the parameter that needs to be changed and + a sessionkey to fix the error. === Languages updated in 1.18 === diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php index 26bb18c835..336bc79e03 100644 --- a/includes/api/ApiBase.php +++ b/includes/api/ApiBase.php @@ -1087,6 +1087,10 @@ abstract class ApiBase { 'nouploadmodule' => array( 'code' => 'nouploadmodule', 'info' => 'No upload module set' ), 'uploaddisabled' => array( 'code' => 'uploaddisabled', 'info' => 'Uploads are not enabled. Make sure $wgEnableUploads is set to true in LocalSettings.php and the PHP ini setting file_uploads is true' ), 'copyuploaddisabled' => array( 'code' => 'copyuploaddisabled', 'info' => 'Uploads by URL is not enabled. Make sure $wgAllowCopyUploads is set to true in LocalSettings.php.' ), + + 'filename-tooshort' => array( 'code' => 'filename-tooshort', 'info' => 'The filename is too short' ), + 'illegal-filename' => array( 'code' => 'illegal-filename', 'info' => 'The filename is not allowed' ), + 'filetype-missing' => array( 'code' => 'filetype-missing', 'info' => 'The file is missing an extension' ), ); /** diff --git a/includes/api/ApiUpload.php b/includes/api/ApiUpload.php index c9ad2838cb..f21408c078 100644 --- a/includes/api/ApiUpload.php +++ b/includes/api/ApiUpload.php @@ -82,14 +82,14 @@ class ApiUpload extends ApiBase { // Check if the uploaded file is sane $this->verifyUpload(); + // Check if the user has the rights to modify or overwrite the requested title // (This check is irrelevant if stashing is already requested, since the errors // can always be fixed by changing the title) if ( ! $this->mParams['stash'] ) { $permErrors = $this->mUpload->verifyTitlePermissions( $wgUser ); if ( $permErrors !== true ) { - // TODO: stash the upload and allow choosing a new name - $this->dieUsageMsg( array( 'badaccess-groups' ) ); + $this->dieRecoverableError( $permErrors[0], 'filename' ); } } @@ -146,6 +146,27 @@ class ApiUpload extends ApiBase { } return $sessionKey; } + + /** + * Throw an error that the user can recover from by providing a better + * value for $parameter + * + * @param $error array Error array suitable for passing to dieUsageMsg() + * @param $parameter string Parameter that needs revising + * @param $data array Optional extra data to pass to the user + * @throws UsageException + */ + function dieRecoverableError( $error, $parameter, $data = array() ) { + try { + $data['sessionkey'] = $this->performStash(); + } catch ( MWException $e ) { + $data['stashfailed'] = $e->getMessage(); + } + $data['invalidparameter'] = $parameter; + + $parsed = $this->parseMsg( $error ); + $this->dieUsage( $parsed['info'], $parsed['code'], 0, $data ); + } /** * Select an upload module and set it to mUpload. Dies on failure. If the @@ -262,15 +283,26 @@ class ApiUpload extends ApiBase { // TODO: Move them to ApiBase's message map switch( $verification['status'] ) { + // Recoverable errors + case UploadBase::MIN_LENGTH_PARTNAME: + $this->dieRecoverableError( 'filename-tooshort', 'filename' ); + break; + case UploadBase::ILLEGAL_FILENAME: + $this->dieRecoverableError( 'illegal-filename', 'filename', + array( 'filename' => $verification['filtered'] ) ); + break; + case UploadBase::FILETYPE_MISSING: + $this->dieRecoverableError( 'filetype-missing', 'filename' ); + break; + + // Unrecoverable errors case UploadBase::EMPTY_FILE: $this->dieUsage( 'The file you submitted was empty', 'empty-file' ); break; case UploadBase::FILE_TOO_LARGE: $this->dieUsage( 'The file you submitted was too large', 'file-too-large' ); break; - case UploadBase::FILETYPE_MISSING: - $this->dieUsage( 'The file is missing an extension', 'filetype-missing' ); - break; + case UploadBase::FILETYPE_BADTYPE: $this->dieUsage( 'This type of file is banned', 'filetype-banned', 0, array( @@ -278,13 +310,6 @@ class ApiUpload extends ApiBase { 'allowed' => $wgFileExtensions ) ); break; - case UploadBase::MIN_LENGTH_PARTNAME: - $this->dieUsage( 'The filename is too short', 'filename-tooshort' ); - break; - case UploadBase::ILLEGAL_FILENAME: - $this->dieUsage( 'The filename is not allowed', 'illegal-filename', - 0, array( 'filename' => $verification['filtered'] ) ); - break; case UploadBase::VERIFICATION_ERROR: $this->getResult()->setIndexedTagName( $verification['details'], 'detail' ); $this->dieUsage( 'This file did not pass file verification', 'verification-error', -- 2.20.1