(bug 27018) Added action=filerevert to revert files to an old version. Copied procedu...
authorBryan Tong Minh <btongminh@users.mediawiki.org>
Sat, 5 Mar 2011 17:23:35 +0000 (17:23 +0000)
committerBryan Tong Minh <btongminh@users.mediawiki.org>
Sat, 5 Mar 2011 17:23:35 +0000 (17:23 +0000)
Further changes:
* Added Status::getErrorsByType() which returns the internal error array untouched
* Added ApiResult::convertStatusToArray() which converts a Status object to something useful for the Api

RELEASE-NOTES
includes/AutoLoader.php
includes/Status.php
includes/api/ApiFileRevert.php [new file with mode: 0644]
includes/api/ApiMain.php
includes/api/ApiResult.php

index d1ba8b5..c1abcde 100644 (file)
@@ -208,6 +208,7 @@ PHP if you have not done so prior to upgrading MediaWiki.
 * (bug 27862) Useremail module didn't properly return success on success.
 * (bug 27590) prop=imageinfo now allows querying the media type
 * (bug 27587) list=filearchive now outputs full title info
+(bug 27018) Added action=filerevert to revert files to an old version
 
 === Languages updated in 1.18 ===
 
index e1820b1..e813f20 100644 (file)
@@ -275,6 +275,7 @@ $wgAutoloadLocalClasses = array(
        'ApiEmailUser' => 'includes/api/ApiEmailUser.php',
        'ApiExpandTemplates' => 'includes/api/ApiExpandTemplates.php',
        'ApiFeedWatchlist' => 'includes/api/ApiFeedWatchlist.php',
+       'ApiFileRevert' => 'includes/api/ApiFileRevert.php',
        'ApiFormatBase' => 'includes/api/ApiFormatBase.php',
        'ApiFormatDbg' => 'includes/api/ApiFormatDbg.php',
        'ApiFormatDump' => 'includes/api/ApiFormatDump.php',
index 30cbb85..6e44d0b 100644 (file)
@@ -287,6 +287,24 @@ class Status {
                }
                return $result;
        }
+       
+       /**
+        * Returns a list of status messages of the given type, with message and
+        * params left untouched, like a sane version of getStatusArray
+        * 
+        * @param $type String
+        *
+        * @return Array
+        */
+       public function getErrorsByType( $type ) {
+               $result = array();
+               foreach ( $this->errors as $error ) {
+                       if ( $error['type'] === $type ) {
+                               $result[] = $error;
+                       }               
+               }
+               return $result;
+       }
        /**
         * Returns true if the specified message is present as a warning or error
         *
diff --git a/includes/api/ApiFileRevert.php b/includes/api/ApiFileRevert.php
new file mode 100644 (file)
index 0000000..9ae309a
--- /dev/null
@@ -0,0 +1,192 @@
+<?php
+/**
+ *
+ *
+ * Created on March 5, 2011
+ *
+ * Copyright © 2011 Bryan Tong Minh <Bryan.TongMinh@Gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+       // Eclipse helper - will be ignored in production
+       require_once( "ApiBase.php" );
+}
+
+/**
+ * @ingroup API
+ */
+class ApiFileRevert extends ApiBase {
+
+       /**
+        * @var File
+        */
+       protected $file;
+       protected $archiveName;
+       
+       protected $params;
+
+       public function __construct( $main, $action ) {
+               parent::__construct( $main, $action );
+       }
+
+       public function execute() {
+               global $wgUser;
+
+               // First check permission to upload/revert
+               $this->checkPermissions( $wgUser );
+
+               $this->params = $this->extractRequestParams();
+               $this->validateParameters();
+               
+
+               $sourceUrl = $this->file->getArchiveVirtualUrl( $this->archiveName );
+               $status = $this->file->upload( $sourceUrl, $this->params['comment'], $this->params['comment'] );
+               
+               if ( $status->isGood() ) {
+                       $result = array( 'result' => 'Success' );
+               } else {
+                       $result = array( 
+                               'result' => 'Failure', 
+                               'errors' => $this->getResult()->convertStatusToArray( $status ),
+                       );
+               }
+                       
+               $this->getResult()->addValue( null, $this->getModuleName(), $result );  
+
+       }
+
+       /**
+        * Checks that the user has permissions to perform this revert.
+        * Dies with usage message on inadequate permissions.
+        * @param $user User The user to check.
+        */
+       protected function checkPermissions( $user ) {
+               $permission = $user->isAllowed( 'edit' ) && $user->isAllowed( 'upload' );
+
+               if ( $permission !== true ) {
+                       if ( !$user->isLoggedIn() ) {
+                               $this->dieUsageMsg( array( 'mustbeloggedin', 'upload' ) );
+                       } else {
+                               $this->dieUsageMsg( array( 'badaccess-groups' ) );
+                       }
+               }
+       }
+       
+       /**
+        * Validate the user parameters and set $this->archiveName and $this->file.
+        * Throws an error if validation fails
+        */
+       protected function validateParameters() {
+               // Validate the input title
+               $title = Title::makeTitleSafe( NS_FILE, $this->params['filename'] );
+               if ( is_null( $title ) ) {
+                       $this->dieUsageMsg( array( 'invalidtitle', $this->params['filename'] ) );
+               }
+               // Check if the file really exists
+               $this->file = wfLocalFile( $title );
+               if ( !$this->file->exists() ) {
+                       $this->dieUsageMsg( array( 'notanarticle' ) );
+               }
+               
+               // Check if the archivename is valid for this file
+               $this->archiveName = $this->params['archivename'];
+               $oldFile = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $title, $this->archiveName );
+               if ( !$oldFile->exists() ) {
+                       $this->dieUsageMsg( array( 'filerevert-badversion' ) );
+               }
+       }
+       
+       
+
+       public function mustBePosted() {
+               return true;
+       }
+
+       public function isWriteMode() {
+               return true;
+       }
+
+       public function getAllowedParams() {
+               return array(
+                       'filename' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => true,
+                       ),
+                       'comment' => array(
+                               ApiBase::PARAM_DFLT => '',
+                       ),
+                       'archivename' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => true,                        
+                       ),
+                       'token' => null,
+               );
+
+       }
+
+       public function getParamDescription() {
+               $params = array(
+                       'filename' => 'Target filename',
+                       'token' => 'Edit token. You can get one of these through prop=info',
+                       'comment' => 'Upload comment',
+                       'archivename' => 'Archive name of the revision to revert to',
+               );
+
+               return $params;
+
+       }
+
+       public function getDescription() {
+               return array(
+                       'Revert a file to an old version'
+               );
+       }
+
+       public function getPossibleErrors() {
+               return array_merge( parent::getPossibleErrors(),
+                       array(
+                               array( 'mustbeloggedin', 'upload' ),
+                               array( 'badaccess-groups' ),
+                               array( 'invalidtitle', 'title' ),
+                               array( 'notanarticle' ),
+                               array( 'filerevert-badversion' ),
+                       )
+               );
+       }
+
+       public function needsToken() {
+               return true;
+       }
+
+       public function getTokenSalt() {
+               return '';
+       }
+
+       protected function getExamples() {
+               return array(
+                       'Revert Wiki.png to the version of 20110305152740:',
+                       '    api.php?action=filerevert&filename=Wiki.png&comment=Revert&archivename=20110305152740!Wiki.png&token=+\\',
+               );
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id$';
+       }
+}
index 7cf5386..60820a7 100644 (file)
@@ -76,6 +76,7 @@ class ApiMain extends ApiBase {
                'move' => 'ApiMove',
                'edit' => 'ApiEditPage',
                'upload' => 'ApiUpload',
+               'filerevert' => 'ApiFileRevert',
                'emailuser' => 'ApiEmailUser',
                'watch' => 'ApiWatch',
                'patrol' => 'ApiPatrol',
index 90c29af..48cd5b1 100644 (file)
@@ -338,6 +338,27 @@ class ApiResult extends ApiBase {
                global $wgContLang;
                $s = $wgContLang->normalize( $s );
        }
+       
+
+       /**
+        * Converts a Status object to an array suitable for addValue
+        * @param Status $status
+        * @param string $errorType
+        * @return array
+        */
+       public function convertStatusToArray( $status, $errorType = 'error' ) {
+               if ( $status->isGood() ) {
+                       return array();
+               }
+               
+               $result = array();
+               foreach ( $status->getErrorsByType( $errorType ) as $error ) {
+                       $this->setIndexedTagName( $error['params'], 'param' );
+                       $result[] = $error;
+               }
+               $this->setIndexedTagName( $result, $errorType );
+               return $result;
+       }
 
        public function execute() {
                ApiBase::dieDebug( __METHOD__, 'execute() is not supported on Result object' );