Ugly temporary fix for bug 21279:
authorAndrew Garrett <werdna@users.mediawiki.org>
Sun, 23 May 2010 14:19:20 +0000 (14:19 +0000)
committerAndrew Garrett <werdna@users.mediawiki.org>
Sun, 23 May 2010 14:19:20 +0000 (14:19 +0000)
* When a revision cannot be found in the revision table, look for it in the archive table.
* If both deleted and undeleted revisions are covered by the same log entry, show two links (see bug 23663)

includes/LogEventsList.php
includes/specials/SpecialRevisiondelete.php
maintenance/tables.sql

index 045644d..2c7939f 100644 (file)
@@ -41,7 +41,7 @@ class LogEventsList {
                if( !isset( $this->message ) ) {
                        $messages = array( 'revertmerge', 'protect_change', 'unblocklink', 'change-blocklink',
                                'revertmove', 'undeletelink', 'undeleteviewlink', 'revdel-restore', 'hist', 'diff',
-                               'pipe-separator' );
+                               'pipe-separator', 'revdel-restore-deleted', 'revdel-restore-visible' );
                        foreach( $messages as $msg ) {
                                $this->message[$msg] = wfMsgExt( $msg, array( 'escapenoentities' ) );
                        }
@@ -450,57 +450,8 @@ class LogEventsList {
                        ) . ')';
                // If an edit was hidden from a page give a review link to the history
                } else if( self::typeAction( $row, array( 'delete', 'suppress' ), 'revision', 'deletedhistory' ) ) {
-                       if( count($paramArray) >= 2 ) {
-                               // Different revision types use different URL params...
-                               $key = $paramArray[0];
-                               // $paramArray[1] is a CSV of the IDs
-                               $Ids = explode( ',', $paramArray[1] );
-                               $query = $paramArray[1];
-                               $revert = array();
-                               // Diff link for single rev deletions
-                               if( count($Ids) == 1 ) {
-                                       // Live revision diffs...
-                                       if( in_array( $key, array( 'oldid', 'revision' ) ) ) {
-                                               $revert[] = $this->skin->link(
-                                                       $title,
-                                                       $this->message['diff'],
-                                                       array(),
-                                                       array(
-                                                               'diff' => intval( $Ids[0] ),
-                                                               'unhide' => 1
-                                                       ),
-                                                       array( 'known', 'noclasses' )
-                                               );
-                                       // Deleted revision diffs...
-                                       } else if( in_array( $key, array( 'artimestamp','archive' ) ) ) {
-                                               $revert[] = $this->skin->link(
-                                                       SpecialPage::getTitleFor( 'Undelete' ),
-                                                       $this->message['diff'], 
-                                                       array(),
-                                                       array(
-                                                               'target'    => $title->getPrefixedDBKey(),
-                                                               'diff'      => 'prev',
-                                                               'timestamp' => $Ids[0]
-                                                       ),
-                                                       array( 'known', 'noclasses' )
-                                               );
-                                       }
-                               }
-                               // View/modify link...
-                               $revert[] = $this->skin->link(
-                                       SpecialPage::getTitleFor( 'Revisiondelete' ),
-                                       $this->message['revdel-restore'],
-                                       array(),
-                                       array(
-                                               'target' => $title->getPrefixedText(),
-                                               'type' => $key,
-                                               'ids' => $query
-                                       ),
-                                       array( 'known', 'noclasses' )
-                               );
-                               // Pipe links
-                               $revert = wfMsg( 'parentheses', $wgLang->pipeList( $revert ) );
-                       }
+                       $revert = RevisionDeleter::getLogLinks( $title, $paramArray,
+                                                               $this->skin, $this->message );
                // Hidden log items, give review link
                } else if( self::typeAction( $row, array( 'delete', 'suppress' ), 'event', 'deletedhistory' ) ) {
                        if( count($paramArray) >= 1 ) {
index 4e1edcd..43178bc 100644 (file)
@@ -719,6 +719,143 @@ class RevisionDeleter {
                        return null;
                }
        }
+       
+       // Checks if a revision still exists in the revision table.
+       //  If it doesn't, returns the corresponding ar_timestamp field
+       //  so that this key can be used instead.
+       public static function checkRevisionExistence( $title, $revid ) {
+               $dbr = wfGetDB( DB_SLAVE );
+               $exists = $dbr->selectField( 'revision', '1',
+                               array( 'rev_id' => $revid ), __METHOD__ );
+                               
+               if ( $exists ) {
+                       return true;
+               }
+               
+               $timestamp = $dbr->selectField( 'archive', 'ar_timestamp',
+                               array( 'ar_namespace' => $title->getNamespace(),
+                                       'ar_title' => $title->getDBkey(),
+                                       'ar_rev_id' => $revid ), __METHOD__ );
+               
+               return $timestamp;
+       }
+       
+       // Creates utility links for log entries.
+       public static function getLogLinks( $title, $paramArray, $skin, $messages ) {
+               global $wgLang;
+               
+               if( count($paramArray) >= 2 ) {
+                       // Different revision types use different URL params...
+                       $originalKey = $key = $paramArray[0];
+                       // $paramArray[1] is a CSV of the IDs
+                       $Ids = explode( ',', $paramArray[1] );
+                       $query = $paramArray[1];
+                       $revert = array();
+                       
+                       // For if undeleted revisions are found amidst deleted ones.
+                       $undeletedRevisions = array();
+                       
+                       // This is not going to work if some revs are deleted and some
+                       //  aren't.
+                       if ($key == 'revision') {
+                               foreach( $Ids as $k => $id ) {
+                                       $existResult =
+                                               self::checkRevisionExistence( $title, $id );
+                                       
+                                       if ($existResult !== true) {
+                                               $key = 'archive';
+                                               $Ids[$k] = $existResult;
+                                       } elseif ($key != $originalKey) {
+                                               // Undeleted revision amidst deleted ones
+                                               unset($Ids[$k]);
+                                               $undeletedRevisions[] = $id;
+                                       }
+                               }
+                       }
+                       
+                       // Diff link for single rev deletions
+                       if( count($Ids) == 1 && !count($undeletedRevisions) ) {
+                               // Live revision diffs...
+                               if( in_array( $key, array( 'oldid', 'revision' ) ) ) {
+                                       $revert[] = $skin->link(
+                                               $title,
+                                               $messages['diff'],
+                                               array(),
+                                               array(
+                                                       'diff' => intval( $Ids[0] ),
+                                                       'unhide' => 1
+                                               ),
+                                               array( 'known', 'noclasses' )
+                                       );
+                               // Deleted revision diffs...
+                               } else if( in_array( $key, array( 'artimestamp','archive' ) ) ) {
+                                       $revert[] = $skin->link(
+                                               SpecialPage::getTitleFor( 'Undelete' ),
+                                               $messages['diff'], 
+                                               array(),
+                                               array(
+                                                       'target'    => $title->getPrefixedDBKey(),
+                                                       'diff'      => 'prev',
+                                                       'timestamp' => $Ids[0]
+                                               ),
+                                               array( 'known', 'noclasses' )
+                                       );
+                               }
+                       }
+                       
+                       // View/modify link...
+                       if ( count($undeletedRevisions) ) {
+                               // FIXME THIS IS A HORRIBLE HORRIBLE HACK AND SHOULD DIE
+                               // It's not possible to pass a list of both deleted and
+                               // undeleted revisions to SpecialRevisionDelete, so we're
+                               // stuck with two links. See bug 
+                               $restoreLinks = array();
+                               
+                               $restoreLinks[] = $skin->link(
+                                       SpecialPage::getTitleFor( 'Revisiondelete' ),
+                                       $messages['revdel-restore-visible'],
+                                       array(),
+                                       array(
+                                               'target' => $title->getPrefixedText(),
+                                               'type' => $originalKey,
+                                               'ids' => implode(',', $undeletedRevisions),
+                                       ),
+                                       array( 'known', 'noclasses' )
+                               );
+                               
+                               $restoreLinks[] = $skin->link(
+                                       SpecialPage::getTitleFor( 'Revisiondelete' ),
+                                       $messages['revdel-restore-deleted'],
+                                       array(),
+                                       array(
+                                               'target' => $title->getPrefixedText(),
+                                               'type' => $key,
+                                               'ids' => implode(',', $Ids),
+                                       ),
+                                       array( 'known', 'noclasses' )
+                               );
+                               
+                               $revert[] = $messages['revdel-restore'] . ' [' .
+                                               $wgLang->pipeList( $restoreLinks ) . ']';
+                       } else {
+                               $revert[] = $skin->link(
+                                       SpecialPage::getTitleFor( 'Revisiondelete' ),
+                                       $messages['revdel-restore'],
+                                       array(),
+                                       array(
+                                               'target' => $title->getPrefixedText(),
+                                               'type' => $key,
+                                               'ids' => implode(',', $Ids),
+                                       ),
+                                       array( 'known', 'noclasses' )
+                               );
+                       }
+                       
+                       // Pipe links
+                       $revert = wfMsg( 'parentheses', $wgLang->pipeList( $revert ) );
+               }
+               return $revert;
+       }       
 }
 
 /**
index 661955b..db1b09d 100644 (file)
@@ -412,11 +412,12 @@ CREATE TABLE /*_*/archive (
   ar_page_id int unsigned,
   
   -- Original previous revision
-  ar_parent_id int unsigned default NULL
+  ar_parent_id int unsigned default NULL,
 ) /*$wgDBTableOptions*/;
 
 CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
 CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp);
+CREATE INDEX /*i*/ar_page_revid ON /*_*/archive (ar_namespace, ar_title, ar_id);
 
 
 --