r29803 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r29802‎ | r29803 | r29804 >
Date:17:31, 15 January 2008
Author:catrope
Status:old
Tags:
Comment:
Large refactoring of rollback code:
* DB code is now in Article::commitRollback(), permissions checks in Article::doRollback()
* doRollback() no longer returns named constants but an OutputPage::showPermissionsErrorPage() compatible array
Modified paths:
  • /trunk/phase3/includes/Article.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Article.php
@@ -37,19 +37,6 @@
3838 /**@}}*/
3939
4040 /**
41 - * Constants used by internal components to get rollback results
42 - */
43 - const SUCCESS = 0; // Operation successful
44 - const PERM_DENIED = 1; // Permission denied
45 - const BLOCKED = 2; // User has been blocked
46 - const READONLY = 3; // Wiki is in read-only mode
47 - const BAD_TOKEN = 4; // Invalid token specified
48 - const BAD_TITLE = 5; // $this is not a valid Article
49 - const ALREADY_ROLLED = 6; // Someone else already rolled this back. $from and $summary will be set
50 - const ONLY_AUTHOR = 7; // User is the only author of the page
51 - const RATE_LIMITED = 8;
52 -
53 - /**
5441 * Constructor and clear the article
5542 * @param $title Reference to a Title object.
5643 * @param $oldId Integer revision ID, null to fetch from request, zero for current
@@ -2273,57 +2260,73 @@
22742261 /**
22752262 * Roll back the most recent consecutive set of edits to a page
22762263 * from the same user; fails if there are no eligible edits to
2277 - * roll back to, e.g. user is the sole contributor
 2264+ * roll back to, e.g. user is the sole contributor. This function
 2265+ * performs permissions checks on $wgUser, then calls commitRollback()
 2266+ * to do the dirty work
22782267 *
22792268 * @param string $fromP - Name of the user whose edits to rollback.
22802269 * @param string $summary - Custom summary. Set to default summary if empty.
22812270 * @param string $token - Rollback token.
22822271 * @param bool $bot - If true, mark all reverted edits as bot.
22832272 *
2284 - * @param array $resultDetails contains result-specific dict of additional values
2285 - * ALREADY_ROLLED : 'current' (rev)
2286 - * SUCCESS : 'summary' (str), 'current' (rev), 'target' (rev)
 2273+ * @param array $resultDetails contains result-specific array of additional values
 2274+ * 'alreadyrolled' : 'current' (rev)
 2275+ * success : 'summary' (str), 'current' (rev), 'target' (rev)
22872276 *
2288 - * @return self::SUCCESS on succes, self::* on failure
 2277+ * @return array of errors, each error formatted as array(messagekey, param1, param2, ...).
 2278+ * On success, the array is empty. This array can also be passed to OutputPage::showPermissionsErrorPage().
 2279+ * NOTE: If the user is blocked, 'blocked' is passed as a message, but it doesn't exist. Be sure to check
 2280+ * it before calling showPermissionsErrorPage(). The same is true for 'actionthrottledtext', which
 2281+ * is passed if the rate limit is passed.
22892282 */
22902283 public function doRollback( $fromP, $summary, $token, $bot, &$resultDetails ) {
2291 - global $wgUser, $wgUseRCPatrol;
 2284+ global $wgUser;
22922285 $resultDetails = null;
22932286
2294 - # Just in case it's being called from elsewhere
2295 -
2296 - if( $wgUser->isAllowed( 'rollback' ) && $this->mTitle->userCan( 'edit' ) ) {
2297 - if( $wgUser->isBlocked() ) {
2298 - return self::BLOCKED;
2299 - }
2300 - } else {
2301 - return self::PERM_DENIED;
2302 - }
2303 -
2304 - if ( wfReadOnly() ) {
2305 - return self::READONLY;
2306 - }
2307 -
 2287+ # Check permissions
 2288+ $errors = array_merge( $this->mTitle->getUserPermissionsErrors( 'edit', $wgUser ),
 2289+ $this->mTitle->getUserPermissionsErrors( 'rollback', $wgUser ) );
23082290 if( !$wgUser->matchEditToken( $token, array( $this->mTitle->getPrefixedText(), $fromP ) ) )
2309 - return self::BAD_TOKEN;
 2291+ $errors[] = array( 'sessionfailure' );
23102292
23112293 if ( $wgUser->pingLimiter('rollback') || $wgUser->pingLimiter() ) {
2312 - return self::RATE_LIMITED;
 2294+ $errors[] = array( 'actionthrottledtext' );
23132295 }
 2296+ if ( $wgUser->isBlocked() )
 2297+ $errors[] = array( 'blocked' );
23142298
 2299+ # If there were errors, bail out now
 2300+ if(!empty($errors))
 2301+ return $errors;
 2302+
 2303+ return $this->commitRollback($fromP, $summary, $bot, $resultDetails);
 2304+ }
 2305+
 2306+ /**
 2307+ * Backend implementation of doRollback(), please refer there for parameter and return value documentation
 2308+ *
 2309+ * NOTE: This function does NOT check ANY permissions, it just commits the rollback to the DB.
 2310+ * Therefore, you should only call this function directly if you really know what you're doing. If you don't, use doRollback() instead
 2311+ */
 2312+ public function commitRollback($fromP, $summary, $bot, &$resultDetails) {
 2313+ global $wgUseRCPatrol;
23152314 $dbw = wfGetDB( DB_MASTER );
23162315
23172316 # Get the last editor
23182317 $current = Revision::newFromTitle( $this->mTitle );
23192318 if( is_null( $current ) ) {
23202319 # Something wrong... no page?
2321 - return self::BAD_TITLE;
 2320+ return array(array('notanarticle'));
23222321 }
23232322
23242323 $from = str_replace( '_', ' ', $fromP );
23252324 if( $from != $current->getUserText() ) {
23262325 $resultDetails = array( 'current' => $current );
2327 - return self::ALREADY_ROLLED;
 2326+ return array(array('alreadyrolled',
 2327+ htmlspecialchars($this->mTitle->getPrefixedText()),
 2328+ htmlspecialchars($fromP),
 2329+ htmlspecialchars($current->getUserText())
 2330+ ));
23282331 }
23292332
23302333 # Get the last edit not by this guy
@@ -2331,17 +2334,15 @@
23322335 $user_text = $dbw->addQuotes( $current->getUserText() );
23332336 $s = $dbw->selectRow( 'revision',
23342337 array( 'rev_id', 'rev_timestamp' ),
2335 - array(
2336 - 'rev_page' => $current->getPage(),
 2338+ array( 'rev_page' => $current->getPage(),
23372339 "rev_user <> {$user} OR rev_user_text <> {$user_text}"
23382340 ), __METHOD__,
2339 - array(
2340 - 'USE INDEX' => 'page_timestamp',
 2341+ array( 'USE INDEX' => 'page_timestamp',
23412342 'ORDER BY' => 'rev_timestamp DESC' )
23422343 );
23432344 if( $s === false ) {
2344 - # Something wrong
2345 - return self::ONLY_AUTHOR;
 2345+ # No one else ever edited this page
 2346+ return array(array('cantrollback'));
23462347 }
23472348
23482349 $set = array();
@@ -2364,7 +2365,7 @@
23652366 );
23662367 }
23672368
2368 - # Get the edit summary
 2369+ # Generate the edit summary if necessary
23692370 $target = Revision::newFromId( $s->rev_id );
23702371 if( empty( $summary ) )
23712372 {
@@ -2393,7 +2394,7 @@
23942395 'current' => $current,
23952396 'target' => $target,
23962397 );
2397 - return self::SUCCESS;
 2398+ return array();
23982399 }
23992400
24002401 /**
@@ -2401,19 +2402,8 @@
24022403 */
24032404 function rollback() {
24042405 global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol;
2405 -
24062406 $details = null;
24072407
2408 - # Skip the permissions-checking in doRollback() itself, by checking permissions here.
2409 -
2410 - $perm_errors = array_merge( $this->mTitle->getUserPermissionsErrors( 'edit', $wgUser ),
2411 - $this->mTitle->getUserPermissionsErrors( 'rollback', $wgUser ) );
2412 -
2413 - if (count($perm_errors)) {
2414 - $wgOut->showPermissionsErrorPage( $perm_errors );
2415 - return;
2416 - }
2417 -
24182408 $result = $this->doRollback(
24192409 $wgRequest->getVal( 'from' ),
24202410 $wgRequest->getText( 'summary' ),
@@ -2421,62 +2411,30 @@
24222412 $wgRequest->getBool( 'bot' ),
24232413 $details
24242414 );
2425 -
2426 - switch( $result ) {
2427 - case self::BLOCKED:
2428 - $wgOut->blockedPage();
2429 - break;
2430 - case self::PERM_DENIED:
2431 - $wgOut->permissionRequired( 'rollback' );
2432 - break;
2433 - case self::READONLY:
2434 - $wgOut->readOnlyPage( $this->getContent() );
2435 - break;
2436 - case self::BAD_TOKEN:
2437 - $wgOut->setPageTitle( wfMsg( 'rollbackfailed' ) );
2438 - $wgOut->addWikiText( wfMsg( 'sessionfailure' ) );
2439 - break;
2440 - case self::BAD_TITLE:
2441 - $wgOut->addHtml( wfMsg( 'notanarticle' ) );
2442 - break;
2443 - case self::ALREADY_ROLLED:
2444 - $current = $details['current'];
2445 - $wgOut->setPageTitle( wfMsg( 'rollbackfailed' ) );
2446 - $wgOut->addWikiText(
2447 - wfMsg( 'alreadyrolled',
2448 - htmlspecialchars( $this->mTitle->getPrefixedText() ),
2449 - htmlspecialchars( $wgRequest->getVal( 'from' ) ),
2450 - htmlspecialchars( $current->getUserText() )
2451 - )
2452 - );
2453 - if( $current->getComment() != '' ) {
2454 - $wgOut->addHtml( wfMsg( 'editcomment',
2455 - $wgUser->getSkin()->formatComment( $current->getComment() ) ) );
2456 - }
2457 - break;
2458 - case self::ONLY_AUTHOR:
2459 - $wgOut->setPageTitle( wfMsg( 'rollbackfailed' ) );
2460 - $wgOut->addHtml( wfMsg( 'cantrollback' ) );
2461 - break;
2462 - case self::RATE_LIMITED:
2463 - $wgOut->rateLimited();
2464 - break;
2465 - case self::SUCCESS:
2466 - $current = $details['current'];
2467 - $target = $details['target'];
2468 - $wgOut->setPageTitle( wfMsg( 'actioncomplete' ) );
2469 - $wgOut->setRobotPolicy( 'noindex,nofollow' );
2470 - $old = $wgUser->getSkin()->userLink( $current->getUser(), $current->getUserText() )
2471 - . $wgUser->getSkin()->userToolLinks( $current->getUser(), $current->getUserText() );
2472 - $new = $wgUser->getSkin()->userLink( $target->getUser(), $target->getUserText() )
2473 - . $wgUser->getSkin()->userToolLinks( $target->getUser(), $target->getUserText() );
2474 - $wgOut->addHtml( wfMsgExt( 'rollback-success', array( 'parse', 'replaceafter' ), $old, $new ) );
2475 - $wgOut->returnToMain( false, $this->mTitle );
2476 - break;
2477 - default:
2478 - throw new MWException( __METHOD__ . ": Unknown return value `{$result}`" );
 2415+
 2416+ if(in_array(array('blocked'), $result)) {
 2417+ $wgOut->blockedPage();
 2418+ return;
24792419 }
 2420+ if(in_array(array('actionthrottledtext'), $result)) {
 2421+ $wgOut->rateLimited();
 2422+ return;
 2423+ }
 2424+ if(!empty($result)) {
 2425+ $wgOut->showPermissionsErrorPage( $result );
 2426+ return;
 2427+ }
24802428
 2429+ $current = $details['current'];
 2430+ $target = $details['target'];
 2431+ $wgOut->setPageTitle( wfMsg( 'actioncomplete' ) );
 2432+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
 2433+ $old = $wgUser->getSkin()->userLink( $current->getUser(), $current->getUserText() )
 2434+ . $wgUser->getSkin()->userToolLinks( $current->getUser(), $current->getUserText() );
 2435+ $new = $wgUser->getSkin()->userLink( $target->getUser(), $target->getUserText() )
 2436+ . $wgUser->getSkin()->userToolLinks( $target->getUser(), $target->getUserText() );
 2437+ $wgOut->addHtml( wfMsgExt( 'rollback-success', array( 'parse', 'replaceafter' ), $old, $new ) );
 2438+ $wgOut->returnToMain( false, $this->mTitle );
24812439 }
24822440
24832441

Status & tagging log