summaryrefslogtreecommitdiff
path: root/includes/specials/SpecialUndelete.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/specials/SpecialUndelete.php')
-rw-r--r--includes/specials/SpecialUndelete.php197
1 files changed, 99 insertions, 98 deletions
diff --git a/includes/specials/SpecialUndelete.php b/includes/specials/SpecialUndelete.php
index d862ebb3..a9fb4ef1 100644
--- a/includes/specials/SpecialUndelete.php
+++ b/includes/specials/SpecialUndelete.php
@@ -119,7 +119,7 @@ class PageArchive {
* @todo Does this belong in Image for fuller encapsulation?
*/
function listFiles() {
- if( $this->title->getNamespace() == NS_IMAGE ) {
+ if( $this->title->getNamespace() == NS_FILE ) {
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( 'filearchive',
array(
@@ -336,7 +336,7 @@ class PageArchive {
$restoreText = $restoreAll || !empty( $timestamps );
$restoreFiles = $restoreAll || !empty( $fileVersions );
- if( $restoreFiles && $this->title->getNamespace() == NS_IMAGE ) {
+ if( $restoreFiles && $this->title->getNamespace() == NS_FILE ) {
$img = wfLocalFile( $this->title );
$this->fileStatus = $img->restore( $fileVersions, $unsuppress );
$filesRestored = $this->fileStatus->successCount;
@@ -412,7 +412,7 @@ class PageArchive {
# we'll update the latest revision field in the record.
$newid = 0;
$pageId = $page->page_id;
- $previousRevId = $page->page_latest;
+ $previousRevId = $page->page_latest;
# Get the time span of this page
$previousTimestamp = $dbw->selectField( 'revision', 'rev_timestamp',
array( 'rev_id' => $previousRevId ),
@@ -461,25 +461,10 @@ class PageArchive {
'ar_title' => $this->title->getDBkey(),
$oldones ),
__METHOD__,
- /* options */ array(
- 'ORDER BY' => 'ar_timestamp' )
+ /* options */ array( 'ORDER BY' => 'ar_timestamp' )
);
$ret = $dbw->resultObject( $result );
-
$rev_count = $dbw->numRows( $result );
- if( $rev_count ) {
- # We need to seek around as just using DESC in the ORDER BY
- # would leave the revisions inserted in the wrong order
- $first = $ret->fetchObject();
- $ret->seek( $rev_count - 1 );
- $last = $ret->fetchObject();
- // We don't handle well changing the top revision's settings
- if( !$unsuppress && $last->ar_deleted && $last->ar_timestamp > $previousTimestamp ) {
- wfDebug( __METHOD__.": restoration would result in a deleted top revision\n" );
- return false;
- }
- $ret->seek( 0 );
- }
if( $makepage ) {
$newid = $article->insertOn( $dbw );
@@ -502,6 +487,12 @@ class PageArchive {
// a new text table entry will be created for it.
$revText = Revision::getRevisionText( $row, 'ar_' );
}
+ // Check for key dupes due to shitty archive integrity.
+ if( $row->ar_rev_id ) {
+ $exists = $dbw->selectField( 'revision', '1', array('rev_id' => $row->ar_rev_id), __METHOD__ );
+ if( $exists ) continue; // don't throw DB errors
+ }
+
$revision = new Revision( array(
'page' => $pageId,
'id' => $row->ar_rev_id,
@@ -520,17 +511,32 @@ class PageArchive {
wfRunHooks( 'ArticleRevisionUndeleted', array( &$this->title, $revision, $row->ar_page_id ) );
}
+ # Now that it's safely stored, take it out of the archive
+ $dbw->delete( 'archive',
+ /* WHERE */ array(
+ 'ar_namespace' => $this->title->getNamespace(),
+ 'ar_title' => $this->title->getDBkey(),
+ $oldones ),
+ __METHOD__ );
+
// Was anything restored at all?
- if($restored == 0)
+ if( $restored == 0 )
return 0;
if( $revision ) {
// Attach the latest revision to the page...
$wasnew = $article->updateIfNewerOn( $dbw, $revision, $previousRevId );
-
if( $newid || $wasnew ) {
// Update site stats, link tables, etc
$article->createUpdates( $revision );
+ // We don't handle well with top revision deleted
+ if( $revision->getVisibility() ) {
+ $dbw->update( 'revision',
+ array( 'rev_deleted' => 0 ),
+ array( 'rev_id' => $revision->getId() ),
+ __METHOD__
+ );
+ }
}
if( $newid ) {
@@ -541,7 +547,7 @@ class PageArchive {
Article::onArticleEdit( $this->title );
}
- if( $this->title->getNamespace() == NS_IMAGE ) {
+ if( $this->title->getNamespace() == NS_FILE ) {
$update = new HTMLCacheUpdate( $this->title, 'imagelinks' );
$update->doUpdate();
}
@@ -550,14 +556,6 @@ class PageArchive {
return self::UNDELETE_UNKNOWNERR;
}
- # Now that it's safely stored, take it out of the archive
- $dbw->delete( 'archive',
- /* WHERE */ array(
- 'ar_namespace' => $this->title->getNamespace(),
- 'ar_title' => $this->title->getDBkey(),
- $oldones ),
- __METHOD__ );
-
return $restored;
}
@@ -570,7 +568,7 @@ class PageArchive {
* @ingroup SpecialPage
*/
class UndeleteForm {
- var $mAction, $mTarget, $mTimestamp, $mRestore, $mTargetObj;
+ var $mAction, $mTarget, $mTimestamp, $mRestore, $mInvert, $mTargetObj;
var $mTargetTimestamp, $mAllowed, $mComment, $mToken;
function UndeleteForm( $request, $par = "" ) {
@@ -585,6 +583,7 @@ class UndeleteForm {
$posted = $request->wasPosted() &&
$wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
$this->mRestore = $request->getCheck( 'restore' ) && $posted;
+ $this->mInvert = $request->getCheck( 'invert' ) && $posted;
$this->mPreview = $request->getCheck( 'preview' ) && $posted;
$this->mDiff = $request->getCheck( 'diff' );
$this->mComment = $request->getText( 'wpComment' );
@@ -606,7 +605,7 @@ class UndeleteForm {
} else {
$this->mTargetObj = NULL;
}
- if( $this->mRestore ) {
+ if( $this->mRestore || $this->mInvert ) {
$timestamps = array();
$this->mFileVersions = array();
foreach( $_REQUEST as $key => $val ) {
@@ -666,6 +665,9 @@ class UndeleteForm {
if( $this->mRestore && $this->mAction == "submit" ) {
return $this->undelete();
}
+ if( $this->mInvert && $this->mAction == "submit" ) {
+ return $this->showHistory( );
+ }
return $this->showHistory();
}
@@ -673,21 +675,20 @@ class UndeleteForm {
global $wgOut, $wgScript;
$wgOut->addWikiMsg( 'undelete-header' );
- $wgOut->addHtml(
+ $wgOut->addHTML(
Xml::openElement( 'form', array(
'method' => 'get',
'action' => $wgScript ) ) .
- '<fieldset>' .
- Xml::element( 'legend', array(),
- wfMsg( 'undelete-search-box' ) ) .
+ Xml::fieldset( wfMsg( 'undelete-search-box' ) ) .
Xml::hidden( 'title',
SpecialPage::getTitleFor( 'Undelete' )->getPrefixedDbKey() ) .
Xml::inputLabel( wfMsg( 'undelete-search-prefix' ),
'prefix', 'prefix', 20,
- $this->mSearchPrefix ) .
+ $this->mSearchPrefix ) . ' ' .
Xml::submitButton( wfMsg( 'undelete-search-submit' ) ) .
- '</fieldset>' .
- '</form>' );
+ Xml::closeElement( 'fieldset' ) .
+ Xml::closeElement( 'form' )
+ );
}
// Generic list of deleted pages
@@ -699,7 +700,7 @@ class UndeleteForm {
return;
}
- $wgOut->addWikiMsg( "undeletepagetext" );
+ $wgOut->addWikiMsg( 'undeletepagetext', $wgLang->formatNum( $result->numRows() ) );
$sk = $wgUser->getSkin();
$undelete = SpecialPage::getTitleFor( 'Undelete' );
@@ -708,11 +709,10 @@ class UndeleteForm {
$title = Title::makeTitleSafe( $row->ar_namespace, $row->ar_title );
$link = $sk->makeKnownLinkObj( $undelete, htmlspecialchars( $title->getPrefixedText() ),
'target=' . $title->getPrefixedUrl() );
- #$revs = wfMsgHtml( 'undeleterevisions', $wgLang->formatNum( $row->count ) );
$revs = wfMsgExt( 'undeleterevisions',
array( 'parseinline' ),
$wgLang->formatNum( $row->count ) );
- $wgOut->addHtml( "<li>{$link} ({$revs})</li>\n" );
+ $wgOut->addHTML( "<li>{$link} ({$revs})</li>\n" );
}
$result->free();
$wgOut->addHTML( "</ul>\n" );
@@ -752,8 +752,6 @@ class UndeleteForm {
SpecialPage::getTitleFor( 'Undelete', $this->mTargetObj->getPrefixedDBkey() ),
htmlspecialchars( $this->mTargetObj->getPrefixedText() )
);
- $time = htmlspecialchars( $wgLang->timeAndDate( $timestamp, true ) );
- $user = $skin->revUserTools( $rev );
if( $this->mDiff ) {
$previousRev = $archive->getPreviousRevision( $timestamp );
@@ -762,59 +760,66 @@ class UndeleteForm {
if( $wgUser->getOption( 'diffonly' ) ) {
return;
} else {
- $wgOut->addHtml( '<hr />' );
+ $wgOut->addHTML( '<hr />' );
}
} else {
- $wgOut->addHtml( wfMsgHtml( 'undelete-nodiff' ) );
+ $wgOut->addHTML( wfMsgHtml( 'undelete-nodiff' ) );
}
}
- $wgOut->addHtml( '<p>' . wfMsgHtml( 'undelete-revision', $link, $time, $user ) . '</p>' );
+ // date and time are separate parameters to facilitate localisation.
+ // $time is kept for backward compat reasons.
+ $time = htmlspecialchars( $wgLang->timeAndDate( $timestamp, true ) );
+ $d = htmlspecialchars( $wgLang->date( $timestamp, true ) );
+ $t = htmlspecialchars( $wgLang->time( $timestamp, true ) );
+ $user = $skin->revUserTools( $rev );
+
+ $wgOut->addHTML( '<p>' . wfMsgHtml( 'undelete-revision', $link, $time, $user, $d, $t ) . '</p>' );
wfRunHooks( 'UndeleteShowRevision', array( $this->mTargetObj, $rev ) );
if( $this->mPreview ) {
- $wgOut->addHtml( "<hr />\n" );
+ $wgOut->addHTML( "<hr />\n" );
//Hide [edit]s
$popts = $wgOut->parserOptions();
$popts->setEditSection( false );
$wgOut->parserOptions( $popts );
- $wgOut->addWikiTextTitleTidy( $rev->revText(), $this->mTargetObj, true );
+ $wgOut->addWikiTextTitleTidy( $rev->getText( Revision::FOR_THIS_USER ), $this->mTargetObj, true );
}
- $wgOut->addHtml(
- wfElement( 'textarea', array(
+ $wgOut->addHTML(
+ Xml::element( 'textarea', array(
'readonly' => 'readonly',
'cols' => intval( $wgUser->getOption( 'cols' ) ),
'rows' => intval( $wgUser->getOption( 'rows' ) ) ),
- $rev->revText() . "\n" ) .
- wfOpenElement( 'div' ) .
- wfOpenElement( 'form', array(
+ $rev->getText( Revision::FOR_THIS_USER ) . "\n" ) .
+ Xml::openElement( 'div' ) .
+ Xml::openElement( 'form', array(
'method' => 'post',
'action' => $self->getLocalURL( "action=submit" ) ) ) .
- wfElement( 'input', array(
+ Xml::element( 'input', array(
'type' => 'hidden',
'name' => 'target',
'value' => $this->mTargetObj->getPrefixedDbKey() ) ) .
- wfElement( 'input', array(
+ Xml::element( 'input', array(
'type' => 'hidden',
'name' => 'timestamp',
'value' => $timestamp ) ) .
- wfElement( 'input', array(
+ Xml::element( 'input', array(
'type' => 'hidden',
'name' => 'wpEditToken',
'value' => $wgUser->editToken() ) ) .
- wfElement( 'input', array(
+ Xml::element( 'input', array(
'type' => 'submit',
'name' => 'preview',
'value' => wfMsg( 'showpreview' ) ) ) .
- wfElement( 'input', array(
+ Xml::element( 'input', array(
'name' => 'diff',
'type' => 'submit',
'value' => wfMsg( 'showdiff' ) ) ) .
- wfCloseElement( 'form' ) .
- wfCloseElement( 'div' ) );
+ Xml::closeElement( 'form' ) .
+ Xml::closeElement( 'div' ) );
}
/**
@@ -829,7 +834,7 @@ class UndeleteForm {
$diffEngine = new DifferenceEngine();
$diffEngine->showDiffStyle();
- $wgOut->addHtml(
+ $wgOut->addHTML(
"<div>" .
"<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>" .
"<col class='diff-marker' />" .
@@ -838,11 +843,11 @@ class UndeleteForm {
"<col class='diff-content' />" .
"<tr>" .
"<td colspan='2' width='50%' align='center' class='diff-otitle'>" .
- $this->diffHeader( $previousRev ) .
- "</td>" .
+ $this->diffHeader( $previousRev, 'o' ) .
+ "</td>\n" .
"<td colspan='2' width='50%' align='center' class='diff-ntitle'>" .
- $this->diffHeader( $currentRev ) .
- "</td>" .
+ $this->diffHeader( $currentRev, 'n' ) .
+ "</td>\n" .
"</tr>" .
$diffEngine->generateDiffBody(
$previousRev->getText(), $currentRev->getText() ) .
@@ -851,7 +856,7 @@ class UndeleteForm {
}
- private function diffHeader( $rev ) {
+ private function diffHeader( $rev, $prefix ) {
global $wgUser, $wgLang, $wgLang;
$sk = $wgUser->getSkin();
$isDeleted = !( $rev->getId() && $rev->getTitle() );
@@ -868,17 +873,17 @@ class UndeleteForm {
$targetQuery = 'oldid=' . $rev->getId();
}
return
- '<div id="mw-diff-otitle1"><strong>' .
+ '<div id="mw-diff-'.$prefix.'title1"><strong>' .
$sk->makeLinkObj( $targetPage,
wfMsgHtml( 'revisionasof',
$wgLang->timeanddate( $rev->getTimestamp(), true ) ),
$targetQuery ) .
( $isDeleted ? ' ' . wfMsgHtml( 'deletedrev' ) : '' ) .
'</strong></div>' .
- '<div id="mw-diff-otitle2">' .
+ '<div id="mw-diff-'.$prefix.'title2">' .
$sk->revUserTools( $rev ) . '<br/>' .
'</div>' .
- '<div id="mw-diff-otitle3">' .
+ '<div id="mw-diff-'.$prefix.'title3">' .
$sk->revComment( $rev ) . '<br/>' .
'</div>';
}
@@ -891,7 +896,8 @@ class UndeleteForm {
$file = new ArchivedFile( $this->mTargetObj, '', $this->mFile );
$wgOut->addWikiMsg( 'undelete-show-file-confirm',
$this->mTargetObj->getText(),
- $wgLang->timeanddate( $file->getTimestamp() ) );
+ $wgLang->date( $file->getTimestamp() ),
+ $wgLang->time( $file->getTimestamp() ) );
$wgOut->addHTML(
Xml::openElement( 'form', array(
'method' => 'POST',
@@ -925,7 +931,7 @@ class UndeleteForm {
$store->stream( $key );
}
- private function showHistory() {
+ private function showHistory( ) {
global $wgLang, $wgUser, $wgOut;
$sk = $wgUser->getSkin();
@@ -984,7 +990,7 @@ class UndeleteForm {
$action = $titleObj->getLocalURL( "action=submit" );
# Start the form here
$top = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $action, 'id' => 'undelete' ) );
- $wgOut->addHtml( $top );
+ $wgOut->addHTML( $top );
}
# Show relevant lines from the deletion log:
@@ -1007,8 +1013,7 @@ class UndeleteForm {
$unsuppressBox = "";
}
$table =
- Xml::openElement( 'fieldset' ) .
- Xml::element( 'legend', null, wfMsg( 'undelete-fieldset-title' ) ).
+ Xml::fieldset( wfMsg( 'undelete-fieldset-title' ) ) .
Xml::openElement( 'table', array( 'id' => 'mw-undelete-table' ) ) .
"<tr>
<td colspan='2'>" .
@@ -1026,15 +1031,16 @@ class UndeleteForm {
<tr>
<td>&nbsp;</td>
<td class='mw-submit'>" .
- Xml::submitButton( wfMsg( 'undeletebtn' ), array( 'name' => 'restore', 'id' => 'mw-undelete-submit' ) ) .
- Xml::element( 'input', array( 'type' => 'reset', 'value' => wfMsg( 'undeletereset' ), 'id' => 'mw-undelete-reset' ) ) .
+ Xml::submitButton( wfMsg( 'undeletebtn' ), array( 'name' => 'restore', 'id' => 'mw-undelete-submit' ) ) . ' ' .
+ Xml::element( 'input', array( 'type' => 'reset', 'value' => wfMsg( 'undeletereset' ), 'id' => 'mw-undelete-reset' ) ) . ' ' .
+ Xml::submitButton( wfMsg( 'undeleteinvert' ), array( 'name' => 'invert', 'id' => 'mw-undelete-invert' ) ) .
"</td>
</tr>" .
$unsuppressBox .
Xml::closeElement( 'table' ) .
Xml::closeElement( 'fieldset' );
- $wgOut->addHtml( $table );
+ $wgOut->addHTML( $table );
}
$wgOut->addHTML( Xml::element( 'h2', null, wfMsg( 'history' ) ) . "\n" );
@@ -1044,7 +1050,7 @@ class UndeleteForm {
$wgOut->addHTML("<ul>");
$target = urlencode( $this->mTarget );
$remaining = $revisions->numRows();
- $earliestLiveTime = $this->getEarliestTime( $this->mTargetObj );
+ $earliestLiveTime = $this->mTargetObj->getEarliestRevTime();
while( $row = $revisions->fetchObject() ) {
$remaining--;
@@ -1057,8 +1063,8 @@ class UndeleteForm {
}
if( $haveFiles ) {
- $wgOut->addHtml( Xml::element( 'h2', null, wfMsg( 'filehist' ) ) . "\n" );
- $wgOut->addHtml( "<ul>" );
+ $wgOut->addHTML( Xml::element( 'h2', null, wfMsg( 'filehist' ) ) . "\n" );
+ $wgOut->addHTML( "<ul>" );
while( $row = $files->fetchObject() ) {
$wgOut->addHTML( $this->formatFileRow( $row, $sk ) );
}
@@ -1071,7 +1077,7 @@ class UndeleteForm {
$misc = Xml::hidden( 'target', $this->mTarget );
$misc .= Xml::hidden( 'wpEditToken', $wgUser->editToken() );
$misc .= Xml::closeElement( 'form' );
- $wgOut->addHtml( $misc );
+ $wgOut->addHTML( $misc );
}
return true;
@@ -1093,7 +1099,15 @@ class UndeleteForm {
$stxt = '';
$ts = wfTimestamp( TS_MW, $row->ar_timestamp );
if( $this->mAllowed ) {
- $checkBox = Xml::check( "ts$ts" );
+ if( $this->mInvert){
+ if( in_array( $ts, $this->mTargetTimestamp ) ) {
+ $checkBox = Xml::check( "ts$ts");
+ } else {
+ $checkBox = Xml::check( "ts$ts", true );
+ }
+ } else {
+ $checkBox = Xml::check( "ts$ts" );
+ }
$titleObj = SpecialPage::getTitleFor( "Undelete" );
$pageLink = $this->getPageLink( $rev, $titleObj, $ts, $sk );
# Last link
@@ -1123,7 +1137,6 @@ class UndeleteForm {
// If revision was hidden from sysops
$del = wfMsgHtml('rev-delundel');
} else {
- $ts = wfTimestamp( TS_MW, $row->ar_timestamp );
$del = $sk->makeKnownLinkObj( $revdel,
wfMsgHtml('rev-delundel'),
'target=' . $this->mTargetObj->getPrefixedUrl() . "&artimestamp=$ts" );
@@ -1183,18 +1196,6 @@ class UndeleteForm {
return "<li>$checkBox $revdlink $pageLink . . $userLink $data $comment</li>\n";
}
- private function getEarliestTime( $title ) {
- $dbr = wfGetDB( DB_SLAVE );
- if( $title->exists() ) {
- $min = $dbr->selectField( 'revision',
- 'MIN(rev_timestamp)',
- array( 'rev_page' => $title->getArticleId() ),
- __METHOD__ );
- return wfTimestampOrNull( TS_MW, $min );
- }
- return null;
- }
-
/**
* Fetch revision text link if it's available to all users
* @return string
@@ -1286,10 +1287,10 @@ class UndeleteForm {
$skin = $wgUser->getSkin();
$link = $skin->makeKnownLinkObj( $this->mTargetObj );
- $wgOut->addHtml( wfMsgWikiHtml( 'undeletedpage', $link ) );
+ $wgOut->addHTML( wfMsgWikiHtml( 'undeletedpage', $link ) );
} else {
$wgOut->showFatalError( wfMsg( "cannotundelete" ) );
- $wgOut->addHtml( '<p>' . wfMsgHtml( "undeleterevdel" ) . '</p>' );
+ $wgOut->addHTML( '<p>' . wfMsgHtml( "undeleterevdel" ) . '</p>' );
}
// Show file deletion warnings and errors