r23562 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r23561‎ | r23562 | r23563 >
Date:19:55, 29 June 2007
Author:catrope
Status:old
Tags:
Comment:
* Separating UI code and DB code in Article::rollback()
* Adding API rollback functionality
Modified paths:
  • /trunk/phase3/includes/Article.php (modified) (history)
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/Defines.php (modified) (history)
  • /trunk/phase3/includes/api/ApiMain.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryInfo.php (modified) (history)
  • /trunk/phase3/includes/api/ApiRollback.php (added) (history)

Diff [purge]

Index: trunk/phase3/includes/Defines.php
@@ -195,6 +195,19 @@
196196 define( 'EDIT_AUTOSUMMARY', 64 );
197197 /**#@-*/
198198
 199+/**#@+
 200+ * Article::doRollback() return values
 201+ */
 202+define('ROLLBACK_SUCCES', 0);
 203+define('ROLLBACK_PERM', 1); // Permission denied
 204+define('ROLLBACK_BLOCKED', 2); // User has been blocked
 205+define('ROLLBACK_READONLY', 3); // Wiki is in read-only mode
 206+define('ROLLBACK_BADTOKEN', 4); // Invalid token specified
 207+define('ROLLBACK_BADARTICLE', 5); // $article is not a valid Article
 208+define('ROLLBACK_ALREADYROLLED', 6); // Someone else already rolled this back. $info['usertext'] and $info['comment'] will be set
 209+define('ROLLBACK_ONLYAUTHOR', 7); // User is the only author of the page
 210+define('ROLLBACK_EDITFAILED', 8); // Article::doEdit() failed. This is a very weird error
 211+
199212 /**
200213 * Flags for Database::makeList()
201214 * These are also available as Database class constants
Index: trunk/phase3/includes/Article.php
@@ -2155,119 +2155,152 @@
21562156 return true;
21572157 }
21582158
2159 - /**
2160 - * Revert a modification
 2159+ /** Backend rollback implementation. UI logic is in rollback()
 2160+ * @param string $user - Name of the user whose edits to rollback.
 2161+ * @param string $token - Rollback token.
 2162+ * @param bool $bot - If true, mark all reverted edits as bot.
 2163+ * @param string $summary - Custom summary. Set to default summary if empty.
 2164+ * @param array $info - Reference to associative array that will be set to contain the revision ID, edit summary, etc.
 2165+ * @return ROLLBACK_SUCCES on succes, ROLLBACK_* on failure
21612166 */
2162 - function rollback() {
2163 - global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol;
 2167+ public function doRollback($user, $token, $bot = false, $summary = "", &$info = NULL)
 2168+ {
 2169+ global $wgUser, $wgUseRCPatrol;
 2170+ if(!$wgUser->isAllowed('rollback'))
 2171+ return ROLLBACK_PERM;
 2172+ if($wgUser->isBlocked())
 2173+ return ROLLBACK_BLOCKED;
 2174+ if(wfReadOnly())
 2175+ return ROLLBACK_READONLY;
21642176
2165 - if( $wgUser->isAllowed( 'rollback' ) ) {
2166 - if( $wgUser->isBlocked() ) {
2167 - $wgOut->blockedPage();
2168 - return;
2169 - }
2170 - } else {
2171 - $wgOut->permissionRequired( 'rollback' );
2172 - return;
2173 - }
 2177+ // Check token first
 2178+ if(!$wgUser->matchEditToken($token, array($this->mTitle->getPrefixedText(), $user)))
 2179+ return ROLLBACK_BADTOKEN;
21742180
2175 - if ( wfReadOnly() ) {
2176 - $wgOut->readOnlyPage( $this->getContent() );
2177 - return;
2178 - }
2179 - if( !$wgUser->matchEditToken( $wgRequest->getVal( 'token' ),
2180 - array( $this->mTitle->getPrefixedText(),
2181 - $wgRequest->getVal( 'from' ) ) ) ) {
2182 - $wgOut->setPageTitle( wfMsg( 'rollbackfailed' ) );
2183 - $wgOut->addWikiText( wfMsg( 'sessionfailure' ) );
2184 - return;
2185 - }
2186 - $dbw = wfGetDB( DB_MASTER );
 2181+ $dbw = wfGetDB(DB_MASTER);
 2182+ $current = Revision::newFromTitle($this->mTitle);
 2183+ if(is_null($current))
 2184+ return ROLLBACK_BADARTICLE;
21872185
2188 - # Enhanced rollback, marks edits rc_bot=1
2189 - $bot = $wgRequest->getBool( 'bot' );
2190 -
2191 - # Replace all this user's current edits with the next one down
2192 -
2193 - # Get the last editor
2194 - $current = Revision::newFromTitle( $this->mTitle );
2195 - if( is_null( $current ) ) {
2196 - # Something wrong... no page?
2197 - $wgOut->addHTML( wfMsg( 'notanarticle' ) );
2198 - return;
 2186+ // Check if someone else was there first
 2187+ if($user != $current->getUserText())
 2188+ {
 2189+ $info['usertext'] = $current->getUserText();
 2190+ $info['comment'] = $current->getComment();
 2191+ return ROLLBACK_ALREADYROLLED;
21992192 }
2200 -
2201 - $from = str_replace( '_', ' ', $wgRequest->getVal( 'from' ) );
2202 - if( $from != $current->getUserText() ) {
2203 - $wgOut->setPageTitle( wfMsg('rollbackfailed') );
2204 - $wgOut->addWikiText( wfMsg( 'alreadyrolled',
2205 - htmlspecialchars( $this->mTitle->getPrefixedText()),
2206 - htmlspecialchars( $from ),
2207 - htmlspecialchars( $current->getUserText() ) ) );
2208 - if( $current->getComment() != '') {
2209 - $wgOut->addHTML(
2210 - wfMsg( 'editcomment',
2211 - $wgUser->getSkin()->formatComment( $current->getComment() ) ) );
2212 - }
2213 - return;
2214 - }
2215 -
2216 - # Get the last edit not by this guy
2217 - $user = intval( $current->getUser() );
2218 - $user_text = $dbw->addQuotes( $current->getUserText() );
2219 - $s = $dbw->selectRow( 'revision',
2220 - array( 'rev_id', 'rev_timestamp' ),
 2193+ // Get the last edit not by $user
 2194+ $userid = intval($current->getUser());
 2195+ $s = $dbw->selectRow('revision',
 2196+ array('rev_id', 'rev_timestamp'),
22212197 array(
22222198 'rev_page' => $current->getPage(),
2223 - "rev_user <> {$user} OR rev_user_text <> {$user_text}"
 2199+ "rev_user <> $userid OR rev_user_text <> {$dbw->addQuotes($user)}"
22242200 ), __METHOD__,
22252201 array(
22262202 'USE INDEX' => 'page_timestamp',
2227 - 'ORDER BY' => 'rev_timestamp DESC' )
2228 - );
2229 - if( $s === false ) {
2230 - # Something wrong
2231 - $wgOut->setPageTitle(wfMsg('rollbackfailed'));
2232 - $wgOut->addHTML( wfMsg( 'cantrollback' ) );
2233 - return;
2234 - }
 2203+ 'ORDER BY' => 'rev_timestamp DESC'
 2204+ ));
 2205+ if($s === false)
 2206+ return ROLLBACK_ONLYAUTHOR;
 2207+ $target = Revision::newFromID($s->rev_id);
22352208
 2209+ // If the reverted edits should be marked bot or patrolled, do so
22362210 $set = array();
2237 - if ( $bot ) {
2238 - # Mark all reverted edits as bot
 2211+ if($bot)
22392212 $set['rc_bot'] = 1;
2240 - }
2241 - if ( $wgUseRCPatrol ) {
2242 - # Mark all reverted edits as patrolled
 2213+ if($wgUseRCPatrol)
22432214 $set['rc_patrolled'] = 1;
2244 - }
 2215+ if($set)
 2216+ $dbw->update('recentchanges', $set,
 2217+ array(
 2218+ 'rc_cur_id' => $current->getPage(),
 2219+ 'rc_user_text' => $user,
 2220+ "rc_timestamp > '{$s->rev_timestamp}'"
 2221+ ), __METHOD__
 2222+ );
22452223
2246 - if ( $set ) {
2247 - $dbw->update( 'recentchanges', $set,
2248 - array( /* WHERE */
2249 - 'rc_cur_id' => $current->getPage(),
2250 - 'rc_user_text' => $current->getUserText(),
2251 - "rc_timestamp > '{$s->rev_timestamp}'",
2252 - ), __METHOD__
2253 - );
2254 - }
 2224+ // Generate an edit summary
 2225+ if(empty($summary))
 2226+ $summary = wfMsgForContent('revertpage', $target->getUserText(), $user);
22552227
2256 - # Get the edit summary
2257 - $target = Revision::newFromId( $s->rev_id );
2258 - $newComment = wfMsgForContent( 'revertpage', $target->getUserText(), $from );
2259 - $newComment = $wgRequest->getText( 'summary', $newComment );
 2228+ // Now we *finally* get to commit the edit
 2229+ $flags = EDIT_UPDATE | EDIT_MINOR;
 2230+ if($bot)
 2231+ $flags |= EDIT_FORCE_BOT;
 2232+ if(!$this->doEdit($target->getText(), $summary, $flags))
 2233+ return ROLLBACK_EDITFAILED;
22602234
2261 - # Save it!
2262 - $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
2263 - $wgOut->setRobotpolicy( 'noindex,nofollow' );
2264 - $wgOut->addHTML( '<h2>' . htmlspecialchars( $newComment ) . "</h2>\n<hr />\n" );
 2235+ if(is_null($info))
 2236+ // Save time
 2237+ return ROLLBACK_SUCCESS;
22652238
2266 - $this->updateArticle( $target->getText(), $newComment, 1, $this->mTitle->userIsWatching(), $bot );
 2239+ $info['title'] = $this->mTitle->getPrefixedText();
 2240+ $info['pageid'] = $current->getPage();
 2241+ $info['summary'] = $summary;
 2242+ // NOTE: If the rollback turned out to be a null edit, revid and old_revid will be equal
 2243+ $info['revid'] = $this->mTitle->getLatestRevID(); // The revid of your rollback
 2244+ $info['old_revid'] = $current->getId(); // The revid of the last edit before your rollback
 2245+ $info['last_revid'] = $s->rev_id; // The revid of the last edit that was not rolled back
 2246+ $info['user'] = $user; // The name of the victim
 2247+ $info['userid'] = $userid; // And their userid
 2248+ $info['to'] = $target->getUserText(); // The user whose last version was reverted to
 2249+ if($bot)
 2250+ $info['bot'] = "";
 2251+ return ROLLBACK_SUCCESS;
 2252+ }
22672253
2268 - $wgOut->returnToMain( false );
 2254+ /** UI entry point for rollbacks. Relies on doRollback() to do the hard work */
 2255+ function rollback() {
 2256+ global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol;
 2257+
 2258+ // Basically, we just call doRollback() and interpret its return value
 2259+ $info = array();
 2260+ $retval = $this->doRollback($wgRequest->getVal('from'), $wgRequest->getVal('token'), $wgRequest->getBool('bot'),
 2261+ $wgRequest->getText('summary'), &$info);
 2262+ switch($retval)
 2263+ {
 2264+ case ROLLBACK_SUCCESS:
 2265+ case ROLLBACK_EDITFAILED: // Is ignored
 2266+ $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
 2267+ $wgOut->setRobotpolicy( 'noindex,nofollow' );
 2268+ $wgOut->addHTML( '<h2>' . htmlspecialchars( $info['summary'] ) . "</h2>\n<hr />\n" );
 2269+ $this->doRedirect(true);
 2270+ $wgOut->returnToMain(false);
 2271+ return;
 2272+ case ROLLBACK_PERM:
 2273+ $wgOut->permissionRequired('rollback');
 2274+ return;
 2275+ case ROLLBACK_BLOCKED:
 2276+ $wgOut->blockedPage();
 2277+ return;
 2278+ case ROLLBACK_READONLY:
 2279+ $wgOut->readOnlyPage($this->getContent());
 2280+ return;
 2281+ case ROLLBACK_BADTOKEN:
 2282+ $wgOut->setPageTitle(wfMsg('rollbackfailed'));
 2283+ $wgOut->addWikiText(wfMsg('sessionfailure'));
 2284+ return;
 2285+ case ROLLBACK_BADARTICLE:
 2286+ $wgOut->addHTML(wfMsg('notanarticle'));
 2287+ return;
 2288+ case ROLLBACK_ALREADYROLLED:
 2289+ $wgOut->setPageTitle(wfMsg('rollbackfailed'));
 2290+ $wgOut->addWikiText(wfMsg('alreadyrolled',
 2291+ htmlspecialchars($this->mTitle->getPrefixedText()),
 2292+ htmlspecialchars($wgRequest->getVal('from')),
 2293+ htmlspecialchars($info['usertext'])));
 2294+ if($info['comment'] != '')
 2295+ $wgOut->addHTML(wfMsg('editcomment',
 2296+ $wgUser->getSkin()->formatComment($info['comment'])));
 2297+ return;
 2298+ case ROLLBACK_ONLYAUTHOR:
 2299+ $wgOut->setPageTitle(wfMsg('rollbackfailed'));
 2300+ $wgOut->addHTML(wfMsg('cantrollback'));
 2301+ return;
 2302+ }
22692303 }
22702304
2271 -
22722305 /**
22732306 * Do standard deferred updates after page view
22742307 * @private
Index: trunk/phase3/includes/AutoLoader.php
@@ -322,6 +322,7 @@
323323 'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php',
324324 'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php',
325325 'ApiResult' => 'includes/api/ApiResult.php',
 326+ 'ApiRollback' => 'includes/api/ApiRollback.php'
326327 );
327328
328329 wfProfileIn( __METHOD__ );
Index: trunk/phase3/includes/api/ApiQueryInfo.php
@@ -49,13 +49,17 @@
5050 }
5151
5252 public function execute() {
 53+ global $wgUser;
5354
5455 $params = $this->extractRequestParams();
5556 $fld_protection = false;
5657 if(!is_null($params['prop'])) {
5758 $prop = array_flip($params['prop']);
5859 $fld_protection = isset($prop['protection']);
 60+ $fld_lastrevby = isset($prop['lastrevby']);
5961 }
 62+ if(!is_null($params['tokens']))
 63+ $params['tokens'] = array_flip($params['tokens']);
6064
6165 $pageSet = $this->getPageSet();
6266 $titles = $pageSet->getGoodTitles();
@@ -85,13 +89,18 @@
8690 $db->freeResult($res);
8791 }
8892
89 - foreach ( $titles as $pageid => $unused ) {
 93+ foreach ( $titles as $pageid => $title ) {
9094 $pageInfo = array (
9195 'touched' => wfTimestamp(TS_ISO_8601, $pageTouched[$pageid]),
9296 'lastrevid' => intval($pageLatest[$pageid]),
9397 'counter' => intval($pageCounter[$pageid]),
94 - 'length' => intval($pageLength[$pageid]),
 98+ 'length' => intval($pageLength[$pageid])
9599 );
 100+ if(isset($params['tokens']) || $fld_lastrevby)
 101+ {
 102+ $lastrev = Revision::newFromId($pageInfo['lastrevid']);
 103+ $pageInfo['lastrevby'] = $lastrev->getUserText();
 104+ }
96105
97106 if ($pageIsRedir[$pageid])
98107 $pageInfo['redirect'] = '';
@@ -108,6 +117,31 @@
109118 }
110119 }
111120
 121+ $tokenArr = array();
 122+ foreach($params['tokens'] as $token => $unused)
 123+ switch($token)
 124+ {
 125+ case 'rollback':
 126+ $tokenArr[$token] = $wgUser->editToken(array($title->getPrefixedText(), $pageInfo['lastrevby']));
 127+ break;
 128+ case 'edit':
 129+ case 'move':
 130+ case 'delete':
 131+ case 'undelete':
 132+ case 'protect':
 133+ case 'unprotect':
 134+ if($wgUser->isAnon())
 135+ $tokenArr[$token] = EDIT_TOKEN_SUFFIX;
 136+ else
 137+ $tokenArr[$token] = $wgUser->editToken();
 138+ // default: can't happen, ignore it if it does happen in some weird way
 139+ }
 140+ if(count($tokenArr) > 0)
 141+ {
 142+ $pageInfo['tokens'] = $tokenArr;
 143+ $result->setIndexedTagName($pageInfo['tokens'], 't');
 144+ }
 145+
112146 $result->addValue(array (
113147 'query',
114148 'pages'
@@ -121,7 +155,20 @@
122156 ApiBase :: PARAM_DFLT => NULL,
123157 ApiBase :: PARAM_ISMULTI => true,
124158 ApiBase :: PARAM_TYPE => array (
125 - 'protection'
 159+ 'protection',
 160+ 'lastrevby'
 161+ )),
 162+ 'tokens' => array(
 163+ ApiBase :: PARAM_DFLT => NULL,
 164+ ApiBase :: PARAM_ISMULTI => true,
 165+ ApiBase :: PARAM_TYPE => array(
 166+ 'edit',
 167+ 'move',
 168+ 'delete',
 169+ 'undelete',
 170+ 'rollback',
 171+ 'protect',
 172+ 'unprotect'
126173 ))
127174 );
128175 }
@@ -130,8 +177,10 @@
131178 return array (
132179 'prop' => array (
133180 'Which additional properties to get:',
134 - ' "protection" - List the protection level of each page'
135 - )
 181+ ' "protection" - List the protection level of each page',
 182+ ' "lastrevby" - The name of the user who made the last edit. You may need this for action=rollback.'
 183+ ),
 184+ 'tokens' => 'Which tokens to get.'
136185 );
137186 }
138187
@@ -143,7 +192,8 @@
144193 protected function getExamples() {
145194 return array (
146195 'api.php?action=query&prop=info&titles=Main%20Page',
147 - 'api.php?action=query&prop=info&inprop=protection&titles=Main%20Page'
 196+ 'api.php?action=query&prop=info&inprop=protection&titles=Main%20Page',
 197+ 'api.php?action=query&prop=info&intokens=edit|rollback&titles=Main%20Page'
148198 );
149199 }
150200
Index: trunk/phase3/includes/api/ApiMain.php
@@ -54,6 +54,7 @@
5555 private static $Modules = array (
5656 'login' => 'ApiLogin',
5757 'query' => 'ApiQuery',
 58+ 'rollback' => 'ApiRollback',
5859 'opensearch' => 'ApiOpenSearch',
5960 'feedwatchlist' => 'ApiFeedWatchlist',
6061 'help' => 'ApiHelp',
@@ -104,6 +105,18 @@
105106 $this->mRequest = & $request;
106107
107108 $this->mSquidMaxage = 0;
 109+
 110+ global $wgUser, $wgCookiePrefix;
 111+ if(session_id() == '')
 112+ wfSetupSession();
 113+ // Reinit $wgUser with info from lg* or the session data. The former overrides the latter
 114+ if(isset($_REQUEST['lguserid']) && isset($_REQUEST['lgusername']) && isset($_REQUEST['lgtoken']))
 115+ {
 116+ $_SESSION['wsUserID'] = $_REQUEST['lguserid'];
 117+ $_SESSION['wsUserName'] = $_REQUEST['lgusername'];
 118+ $_SESSION['wsToken'] = $_REQUEST['lgtoken'];
 119+ }
 120+ $wgUser = User::newFromSession();
108121 }
109122
110123 /**
Index: trunk/phase3/includes/api/ApiRollback.php
@@ -0,0 +1,134 @@
 2+<?php
 3+
 4+/*
 5+ * Created on Jun 20, 2007
 6+ * API for MediaWiki 1.8+
 7+ *
 8+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
 9+ *
 10+ * This program is free software; you can redistribute it and/or modify
 11+ * it under the terms of the GNU General Public License as published by
 12+ * the Free Software Foundation; either version 2 of the License, or
 13+ * (at your option) any later version.
 14+ *
 15+ * This program is distributed in the hope that it will be useful,
 16+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 18+ * GNU General Public License for more details.
 19+ *
 20+ * You should have received a copy of the GNU General Public License along
 21+ * with this program; if not, write to the Free Software Foundation, Inc.,
 22+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 23+ * http://www.gnu.org/copyleft/gpl.html
 24+ */
 25+
 26+if (!defined('MEDIAWIKI')) {
 27+ // Eclipse helper - will be ignored in production
 28+ require_once ("ApiBase.php");
 29+}
 30+
 31+/**
 32+ * @addtogroup API
 33+ */
 34+class ApiRollback extends ApiBase {
 35+
 36+ public function __construct($main, $action) {
 37+ parent :: __construct($main, $action);
 38+ }
 39+
 40+ public function execute() {
 41+ global $wgUser;
 42+ $params = $this->extractRequestParams();
 43+
 44+ $titleObj = NULL;
 45+ if(!isset($params['title']))
 46+ $this->dieUsage('The title parameter must be set', 'notarget');
 47+ if(!isset($params['user']))
 48+ $this->dieUsage('The user parameter must be set', 'nouser');
 49+ if(!isset($params['token']))
 50+ $this->dieUsage('The token parameter must be set', 'notoken');
 51+
 52+ // doRollback() also checks for these, but we wanna save some work
 53+ if(!$wgUser->isAllowed('rollback'))
 54+ $this->dieUsage('You don\'t have permission to rollback', 'permissiondenied');
 55+ if($wgUser->isBlocked())
 56+ $this->dieUsage('You have been blocked from editing', 'blocked');
 57+ if(wfReadOnly())
 58+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
 59+
 60+ $titleObj = Title::newFromText($params['title']);
 61+ if(!$titleObj)
 62+ $this->dieUsage("bad title {$params['title']}", 'invalidtitle');
 63+
 64+ $articleObj = new Article($titleObj);
 65+ $summary = (isset($params['summary']) ? $params['summary'] : "");
 66+ $info = array();
 67+ $retval = $articleObj->doRollback($params['user'], $params['token'], isset($params['markbot']), $summary, &$info);
 68+
 69+ switch($retval)
 70+ {
 71+ case ROLLBACK_SUCCESS:
 72+ break; // We'll deal with that later
 73+ case ROLLBACK_PERM:
 74+ $this->dieUsage('You don\'t have permission to rollback', 'permissiondenied');
 75+ case ROLLBACK_BLOCKED: // If we get BLOCKED or PERM that's very weird, but it's possible
 76+ $this->dieUsage('You have been blocked from editing', 'blocked');
 77+ case ROLLBACK_READONLY:
 78+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
 79+ case ROLLBACK_BADTOKEN:
 80+ $this->dieUsage('Invalid token', 'badtoken');
 81+ case ROLLBACK_BADARTICLE:
 82+ $this->dieUsage("The article ``{$params['title']}'' doesn't exist", 'missingtitle');
 83+ case ROLLBACK_ALREADYROLLED:
 84+ $this->dieUsage('The edit(s) you tried to rollback is/are already rolled back', 'alreadyrolled');
 85+ case ROLLBACK_ONLYAUTHOR:
 86+ $this->dieUsage("{$params['user']} is the only author of the page", 'onlyauthor');
 87+ case ROLLBACK_EDITFAILED:
 88+ $this->dieDebug(__METHOD__, 'Article::doEdit() failed');
 89+ default:
 90+ // rollback() has apparently invented a new error, which is extremely weird
 91+ $this->dieDebug(__METHOD__, "rollback() returned an unknown error ($retval)");
 92+ }
 93+ // $retval has to be ROLLBACK_SUCCESS if we get here
 94+ $this->getResult()->addValue(null, 'rollback', $info);
 95+ }
 96+
 97+ protected function getAllowedParams() {
 98+ return array (
 99+ 'title' => null,
 100+ 'user' => null,
 101+ 'token' => null,
 102+ 'summary' => null,
 103+ 'markbot' => null
 104+ );
 105+ }
 106+
 107+ protected function getParamDescription() {
 108+ return array (
 109+ 'title' => 'Title of the page you want to rollback.',
 110+ 'user' => 'Name of the user whose edits are to be rolled back. If set incorrectly, you\'ll get a badtoken error.',
 111+ 'token' => 'A rollback token previously retrieved through prop=info',
 112+ 'summary' => 'Custom edit summary. If not set, default summary will be used.',
 113+ 'markbot' => 'Mark the reverted edits and the revert as bot edits'
 114+ );
 115+ }
 116+
 117+ protected function getDescription() {
 118+ return array(
 119+ 'Undoes the last edit to the page. If the last user who edited the page made multiple edits in a row,',
 120+ 'they will all be rolled back. You need to be logged in as a sysop to use this function, see also action=login.'
 121+ );
 122+ }
 123+
 124+ protected function getExamples() {
 125+ return array (
 126+ 'api.php?action=rollback&title=Main%20Page&user=Catrope&token=123ABC',
 127+ 'api.php?action=rollback&title=Main%20Page&user=217.121.114.116&token=123ABC&summary=Reverting%20vandalism&markbot=1'
 128+ );
 129+ }
 130+
 131+ public function getVersion() {
 132+ return __CLASS__ . ': $Id: ApiRollback.php 22289 2007-05-20 23:31:44Z yurik $';
 133+ }
 134+}
 135+?>

Follow-up revisions

RevisionCommit summaryAuthorDate
r23564Reverting r23562: accidentally modified phase3 rather than...catrope20:02, 29 June 2007
r23565Adding to the right branch. See r23562 for details.catrope20:04, 29 June 2007
r23581Merged revisions 23406-23580 via svnmerge from...david04:50, 30 June 2007

Status & tagging log