X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fspecials%2FSpecialUndelete.php;h=d8c9d1310b531fc514ed2492131ee4c9e991fefc;hb=35049ad88b74d322fd7c910231292d5fb4f8b406;hp=c0318654891849fbdb0fe01d80190790c001b2b4;hpb=c1fb11dd90ffd9135af65cc4341b474e95b35684;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/specials/SpecialUndelete.php b/includes/specials/SpecialUndelete.php index c031865489..d8c9d1310b 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( @@ -188,20 +188,7 @@ class PageArchive { 'ar_timestamp' => $dbr->timestamp( $timestamp ) ), __METHOD__ ); if( $row ) { - return new Revision( array( - 'page' => $this->title->getArticleId(), - 'id' => $row->ar_rev_id, - 'text' => ($row->ar_text_id - ? null - : Revision::getRevisionText( $row, 'ar_' ) ), - 'comment' => $row->ar_comment, - 'user' => $row->ar_user, - 'user_text' => $row->ar_user_text, - 'timestamp' => $row->ar_timestamp, - 'minor_edit' => $row->ar_minor_edit, - 'text_id' => $row->ar_text_id, - 'deleted' => $row->ar_deleted, - 'len' => $row->ar_len) ); + return Revision::newFromArchiveRow( $row, array( 'page' => $this->title->getArticleId() ) ); } else { return null; } @@ -336,7 +323,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 +399,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 +448,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 ); @@ -490,45 +462,49 @@ class PageArchive { $restored = 0; while( $row = $ret->fetchObject() ) { - if( $row->ar_text_id ) { - // Revision was deleted in 1.5+; text is in - // the regular text table, use the reference. - // Specify null here so the so the text is - // dereferenced for page length info if needed. - $revText = null; - } else { - // Revision was deleted in 1.4 or earlier. - // Text is squashed into the archive row, and - // 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, - 'text' => $revText, - 'comment' => $row->ar_comment, - 'user' => $row->ar_user, - 'user_text' => $row->ar_user_text, - 'timestamp' => $row->ar_timestamp, - 'minor_edit' => $row->ar_minor_edit, - 'text_id' => $row->ar_text_id, - 'deleted' => $unsuppress ? 0 : $row->ar_deleted, - 'len' => $row->ar_len + + $revision = Revision::newFromArchiveRow( $row, + array( + 'page' => $pageId, + 'deleted' => $unsuppress ? 0 : $row->ar_deleted ) ); + $revision->insertOn( $dbw ); $restored++; 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 ) { + // We don't handle well with top revision deleted + // FIXME: any sysop can unsuppress any revision by just undeleting it into a non-existent page! + if( $revision->getVisibility() ) { + $dbw->update( 'revision', + array( 'rev_deleted' => 0 ), + array( 'rev_id' => $revision->getId() ), + __METHOD__ + ); + $revision->mDeleted = 0; // Don't pollute the parser cache + } // Update site stats, link tables, etc $article->createUpdates( $revision ); } @@ -541,7 +517,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 +526,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,8 +538,8 @@ class PageArchive { * @ingroup SpecialPage */ class UndeleteForm { - var $mAction, $mTarget, $mTimestamp, $mRestore, $mTargetObj; - var $mTargetTimestamp, $mAllowed, $mComment; + var $mAction, $mTarget, $mTimestamp, $mRestore, $mInvert, $mTargetObj; + var $mTargetTimestamp, $mAllowed, $mComment, $mToken; function UndeleteForm( $request, $par = "" ) { global $wgUser; @@ -585,10 +553,12 @@ 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' ); $this->mUnsuppress = $request->getVal( 'wpUnsuppress' ) && $wgUser->isAllowed( 'suppressrevision' ); + $this->mToken = $request->getVal( 'token' ); if( $par != "" ) { $this->mTarget = $par; @@ -605,7 +575,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 ) { @@ -642,7 +612,7 @@ class UndeleteForm { $this->showList( $result ); } } else { - $wgOut->addWikiText( wfMsgHtml( 'undelete-header' ) ); + $wgOut->addWikiMsg( 'undelete-header' ); } return; } @@ -655,6 +625,9 @@ class UndeleteForm { if( !$file->userCan( File::DELETED_FILE ) ) { $wgOut->permissionRequired( 'suppressrevision' ); return false; + } elseif ( !$wgUser->matchEditToken( $this->mToken, $this->mFile ) ) { + $this->showFileConfirmationForm( $this->mFile ); + return false; } else { return $this->showFile( $this->mFile ); } @@ -662,6 +635,9 @@ class UndeleteForm { if( $this->mRestore && $this->mAction == "submit" ) { return $this->undelete(); } + if( $this->mInvert && $this->mAction == "submit" ) { + return $this->showHistory( ); + } return $this->showHistory(); } @@ -669,21 +645,20 @@ class UndeleteForm { global $wgOut, $wgScript; $wgOut->addWikiMsg( 'undelete-header' ); - $wgOut->addHtml( + $wgOut->addHTML( Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) . - '
' . - 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' ) ) . - '
' . - '' ); + Xml::closeElement( 'fieldset' ) . + Xml::closeElement( 'form' ) + ); } // Generic list of deleted pages @@ -695,20 +670,23 @@ class UndeleteForm { return; } - $wgOut->addWikiMsg( "undeletepagetext" ); + $wgOut->addWikiMsg( 'undeletepagetext', $wgLang->formatNum( $result->numRows() ) ); $sk = $wgUser->getSkin(); $undelete = SpecialPage::getTitleFor( 'Undelete' ); $wgOut->addHTML( "\n" ); @@ -733,10 +711,10 @@ class UndeleteForm { if( $rev->isDeleted(Revision::DELETED_TEXT) ) { if( !$rev->userCan(Revision::DELETED_TEXT) ) { - $wgOut->addWikiText( wfMsg( 'rev-deleted-text-permission' ) ); + $wgOut->wrapWikiMsg( "\n", 'rev-deleted-text-permission' ); return; } else { - $wgOut->addWikiText( wfMsg( 'rev-deleted-text-view' ) ); + $wgOut->wrapWikiMsg( "\n", 'rev-deleted-text-view' ); $wgOut->addHTML( '
' ); // and we are allowed to see... } @@ -744,12 +722,10 @@ class UndeleteForm { $wgOut->setPageTitle( wfMsg( 'undeletepage' ) ); - $link = $skin->makeKnownLinkObj( + $link = $skin->linkKnown( 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 ); @@ -758,59 +734,69 @@ class UndeleteForm { if( $wgUser->getOption( 'diffonly' ) ) { return; } else { - $wgOut->addHtml( '
' ); + $wgOut->addHTML( '
' ); } } else { - $wgOut->addHtml( wfMsgHtml( 'undelete-nodiff' ) ); + $wgOut->addWikiMsg( 'undelete-nodiff' ); } } - $wgOut->addHtml( '

' . wfMsgHtml( 'undelete-revision', $link, $time, $user ) . '

' ); + // 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 ); + if( $this->mPreview ) { + $openDiv = '
'; + } else { + $openDiv = '
'; + } + + $wgOut->addHTML( $openDiv . wfMsgWikiHtml( 'undelete-revision', $link, $time, $user, $d, $t ) . '
' ); wfRunHooks( 'UndeleteShowRevision', array( $this->mTargetObj, $rev ) ); if( $this->mPreview ) { - $wgOut->addHtml( "
\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( + 'action' => $self->getLocalURL( array( 'action' => 'submit' ) ) ) ) . + 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' ) ); } /** @@ -821,11 +807,11 @@ class UndeleteForm { * @return string HTML */ function showDiff( $previousRev, $currentRev ) { - global $wgOut, $wgUser; + global $wgOut; $diffEngine = new DifferenceEngine(); $diffEngine->showDiffStyle(); - $wgOut->addHtml( + $wgOut->addHTML( "
" . "" . "" . @@ -834,11 +820,11 @@ class UndeleteForm { "" . "" . "" . + $this->diffHeader( $previousRev, 'o' ) . + "\n" . "" . + $this->diffHeader( $currentRev, 'n' ) . + "\n" . "" . $diffEngine->generateDiffBody( $previousRev->getText(), $currentRev->getText() ) . @@ -847,38 +833,86 @@ class UndeleteForm { } - private function diffHeader( $rev ) { + private function diffHeader( $rev, $prefix ) { global $wgUser, $wgLang, $wgLang; $sk = $wgUser->getSkin(); $isDeleted = !( $rev->getId() && $rev->getTitle() ); if( $isDeleted ) { /// @fixme $rev->getTitle() is null for deleted revs...? $targetPage = SpecialPage::getTitleFor( 'Undelete' ); - $targetQuery = 'target=' . - $this->mTargetObj->getPrefixedUrl() . - '×tamp=' . - wfTimestamp( TS_MW, $rev->getTimestamp() ); + $targetQuery = array( + 'target' => $this->mTargetObj->getPrefixedText(), + 'timestamp' => wfTimestamp( TS_MW, $rev->getTimestamp() ) + ); } else { /// @fixme getId() may return non-zero for deleted revs... $targetPage = $rev->getTitle(); - $targetQuery = 'oldid=' . $rev->getId(); + $targetQuery = array( 'oldid' => $rev->getId() ); + } + // Add show/hide link if available + if( $wgUser->isAllowed( 'deleterevision' ) ) { + // If revision was hidden from sysops + if( !$rev->userCan( Revision::DELETED_RESTRICTED ) ) { + $del = ' ' . Xml::tags( 'span', array( 'class'=>'mw-revdelundel-link' ), + '(' . wfMsgHtml('rev-delundel') . ')' ); + // Otherwise, show the link... + } else { + $query = array( + 'type' => 'archive', + 'target' => $this->mTargetObj->getPrefixedDbkey(), + 'ids' => $rev->getTimestamp() ); + $del = ' ' . $sk->revDeleteLink( $query, + $rev->isDeleted( Revision::DELETED_RESTRICTED ) ); + } + } else { + $del = ''; } return - '
' . - $sk->makeLinkObj( $targetPage, - wfMsgHtml( 'revisionasof', - $wgLang->timeanddate( $rev->getTimestamp(), true ) ), - $targetQuery ) . - ( $isDeleted ? ' ' . wfMsgHtml( 'deletedrev' ) : '' ) . + '
' . + $sk->link( + $targetPage, + wfMsgHtml( + 'revisionasof', + htmlspecialchars( $wgLang->timeanddate( $rev->getTimestamp(), true ) ), + htmlspecialchars( $wgLang->date( $rev->getTimestamp(), true ) ), + htmlspecialchars( $wgLang->time( $rev->getTimestamp(), true ) ) + ), + array(), + $targetQuery + ) . '
' . - '
' . + '
' . $sk->revUserTools( $rev ) . '
' . '
' . - '
' . - $sk->revComment( $rev ) . '
' . + '
' . + $sk->revComment( $rev ) . $del . '
' . '
'; } + /** + * Show a form confirming whether a tokenless user really wants to see a file + */ + private function showFileConfirmationForm( $key ) { + global $wgOut, $wgUser, $wgLang; + $file = new ArchivedFile( $this->mTargetObj, '', $this->mFile ); + $wgOut->addWikiMsg( 'undelete-show-file-confirm', + $this->mTargetObj->getText(), + $wgLang->date( $file->getTimestamp() ), + $wgLang->time( $file->getTimestamp() ) ); + $wgOut->addHTML( + Xml::openElement( 'form', array( + 'method' => 'POST', + 'action' => SpecialPage::getTitleFor( 'Undelete' )->getLocalUrl( + 'target=' . urlencode( $this->mTarget ) . + '&file=' . urlencode( $key ) . + '&token=' . urlencode( $wgUser->editToken( $key ) ) ) + ) + ) . + Xml::submitButton( wfMsg( 'undelete-show-file-submit' ) ) . + '' + ); + } + /** * Show a deleted file version requested by the visitor. */ @@ -894,11 +928,14 @@ class UndeleteForm { $wgRequest->response()->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' ); $wgRequest->response()->header( 'Pragma: no-cache' ); - $store = FileStore::get( 'deleted' ); - $store->stream( $key ); + global $IP; + require_once( "$IP/includes/StreamFile.php" ); + $repo = RepoGroup::singleton()->getLocalRepo(); + $path = $repo->getZonePath( 'deleted' ) . '/' . $repo->getDeletedHashPath( $key ) . $key; + wfStreamFile( $path ); } - private function showHistory() { + private function showHistory( ) { global $wgLang, $wgUser, $wgOut; $sk = $wgUser->getSkin(); @@ -908,7 +945,7 @@ class UndeleteForm { $wgOut->setPagetitle( wfMsg( 'viewdeletedpage' ) ); } - $wgOut->addWikiText( wfMsgHtml( 'undeletepagetitle', $this->mTargetObj->getPrefixedText()) ); + $wgOut->wrapWikiMsg( "
\n$1
\n", array ( 'undeletepagetitle', $this->mTargetObj->getPrefixedText() ) ); $archive = new PageArchive( $this->mTargetObj ); /* @@ -918,12 +955,14 @@ class UndeleteForm { return; } */ + $wgOut->addHTML( '
' ); if ( $this->mAllowed ) { $wgOut->addWikiMsg( "undeletehistory" ); $wgOut->addWikiMsg( "undeleterevdel" ); } else { $wgOut->addWikiMsg( "undeletehistorynoadmin" ); } + $wgOut->addHTML( '
' ); # List all stored revisions $revisions = $archive->listRevisions(); @@ -954,15 +993,20 @@ class UndeleteForm { if ( $this->mAllowed ) { $titleObj = SpecialPage::getTitleFor( "Undelete" ); - $action = $titleObj->getLocalURL( "action=submit" ); + $action = $titleObj->getLocalURL( array( '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: $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) . "\n" ); LogEventsList::showLogExtract( $wgOut, 'delete', $this->mTargetObj->getPrefixedText() ); + # Show relevant lines from the suppression log: + if( $wgUser->isAllowed( 'suppressionlog' ) ) { + $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'suppress' ) ) . "\n" ); + LogEventsList::showLogExtract( $wgOut, 'suppress', $this->mTargetObj->getPrefixedText() ); + } if( $this->mAllowed && ( $haveRevisions || $haveFiles ) ) { # Format the user-visible controls (comment field, submission button) @@ -980,11 +1024,10 @@ 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' ) ) . "
- @@ -999,15 +1042,16 @@ class UndeleteForm { " . $unsuppressBox . Xml::closeElement( 'table' ) . Xml::closeElement( 'fieldset' ); - $wgOut->addHtml( $table ); + $wgOut->addHTML( $table ); } $wgOut->addHTML( Xml::element( 'h2', null, wfMsg( 'history' ) ) . "\n" ); @@ -1017,7 +1061,7 @@ class UndeleteForm { $wgOut->addHTML("
    "); $target = urlencode( $this->mTarget ); $remaining = $revisions->numRows(); - $earliestLiveTime = $this->getEarliestTime( $this->mTargetObj ); + $earliestLiveTime = $this->mTargetObj->getEarliestRevTime(); while( $row = $revisions->fetchObject() ) { $remaining--; @@ -1030,8 +1074,8 @@ class UndeleteForm { } if( $haveFiles ) { - $wgOut->addHtml( Xml::element( 'h2', null, wfMsg( 'filehist' ) ) . "\n" ); - $wgOut->addHtml( "
      " ); + $wgOut->addHTML( Xml::element( 'h2', null, wfMsg( 'filehist' ) ) . "\n" ); + $wgOut->addHTML( "
        " ); while( $row = $files->fetchObject() ) { $wgOut->addHTML( $this->formatFileRow( $row, $sk ) ); } @@ -1044,7 +1088,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; @@ -1053,61 +1097,64 @@ class UndeleteForm { private function formatRevisionRow( $row, $earliestLiveTime, $remaining, $sk ) { global $wgUser, $wgLang; - $rev = new Revision( array( - 'page' => $this->mTargetObj->getArticleId(), - 'comment' => $row->ar_comment, - 'user' => $row->ar_user, - 'user_text' => $row->ar_user_text, - 'timestamp' => $row->ar_timestamp, - 'minor_edit' => $row->ar_minor_edit, - 'deleted' => $row->ar_deleted, - 'len' => $row->ar_len ) ); - + $rev = Revision::newFromArchiveRow( $row, + array( 'page' => $this->mTargetObj->getArticleId() ) ); $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 if( !$rev->userCan( Revision::DELETED_TEXT ) ) { $last = wfMsgHtml('diff'); } else if( $remaining > 0 || ($earliestLiveTime && $ts > $earliestLiveTime) ) { - $last = $sk->makeKnownLinkObj( $titleObj, wfMsgHtml('diff'), - "target=" . $this->mTargetObj->getPrefixedUrl() . "×tamp=$ts&diff=prev" ); + $last = $sk->linkKnown( + $titleObj, + wfMsgHtml('diff'), + array(), + array( + 'target' => $this->mTargetObj->getPrefixedText(), + 'timestamp' => $ts, + 'diff' => 'prev' + ) + ); } else { $last = wfMsgHtml('diff'); } } else { $checkBox = ''; - $pageLink = $wgLang->timeanddate( $ts, true ); + $pageLink = htmlspecialchars( $wgLang->timeanddate( $ts, true ) ); $last = wfMsgHtml('diff'); } $userLink = $sk->revUserTools( $rev ); if(!is_null($size = $row->ar_len)) { - if($size == 0) - $stxt = wfMsgHtml('historyempty'); - else - $stxt = wfMsgHtml('historysize', $wgLang->formatNum( $size ) ); + $stxt = $sk->formatRevisionSize( $size ); } $comment = $sk->revComment( $rev ); $revdlink = ''; if( $wgUser->isAllowed( 'deleterevision' ) ) { - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' ); if( !$rev->userCan( Revision::DELETED_RESTRICTED ) ) { // If revision was hidden from sysops - $del = wfMsgHtml('rev-delundel'); + $revdlink = Xml::tags( 'span', array( 'class'=>'mw-revdelundel-link' ), + '('.wfMsgHtml('rev-delundel').')' ); } else { - $ts = wfTimestamp( TS_MW, $row->ar_timestamp ); - $del = $sk->makeKnownLinkObj( $revdel, - wfMsgHtml('rev-delundel'), - 'target=' . $this->mTargetObj->getPrefixedUrl() . "&artimestamp=$ts" ); - // Bolden oversighted content - if( $rev->isDeleted( Revision::DELETED_RESTRICTED ) ) - $del = "$del"; + $query = array( + 'type' => 'archive', + 'target' => $this->mTargetObj->getPrefixedDBkey(), + 'ids' => $ts + ); + $revdlink = $sk->revDeleteLink( $query, $rev->isDeleted( Revision::DELETED_RESTRICTED ) ); } - $revdlink = "($del)"; } return "
      • $checkBox $revdlink ($last) $pageLink . . $userLink $stxt $comment
      • "; @@ -1131,45 +1178,31 @@ class UndeleteForm { } $userLink = $this->getFileUser( $file, $sk ); $data = - wfMsgHtml( 'widthheight', + wfMsg( 'widthheight', $wgLang->formatNum( $row->fa_width ), $wgLang->formatNum( $row->fa_height ) ) . ' (' . - wfMsgHtml( 'nbytes', $wgLang->formatNum( $row->fa_size ) ) . + wfMsg( 'nbytes', $wgLang->formatNum( $row->fa_size ) ) . ')'; + $data = htmlspecialchars( $data ); $comment = $this->getFileComment( $file, $sk ); $revdlink = ''; if( $wgUser->isAllowed( 'deleterevision' ) ) { - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' ); if( !$file->userCan(File::DELETED_RESTRICTED ) ) { // If revision was hidden from sysops - $del = wfMsgHtml('rev-delundel'); + $revdlink = Xml::tags( 'span', array( 'class'=>'mw-revdelundel-link' ), '('.wfMsgHtml('rev-delundel').')' ); } else { - $del = $sk->makeKnownLinkObj( $revdel, - wfMsgHtml('rev-delundel'), - 'target=' . $this->mTargetObj->getPrefixedUrl() . - '&fileid=' . $row->fa_id ); - // Bolden oversighted content - if( $file->isDeleted( File::DELETED_RESTRICTED ) ) - $del = "$del"; + $query = array( + 'type' => 'filearchive', + 'target' => $this->mTargetObj->getPrefixedDBkey(), + 'ids' => $row->fa_id + ); + $revdlink = $sk->revDeleteLink( $query, $file->isDeleted( File::DELETED_RESTRICTED ) ); } - $revdlink = "($del)"; } return "
      • $checkBox $revdlink $pageLink . . $userLink $data $comment
      • \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 @@ -1177,11 +1210,20 @@ class UndeleteForm { function getPageLink( $rev, $titleObj, $ts, $sk ) { global $wgLang; + $time = htmlspecialchars( $wgLang->timeanddate( $ts, true ) ); + if( !$rev->userCan(Revision::DELETED_TEXT) ) { - return '' . $wgLang->timeanddate( $ts, true ) . ''; + return '' . $time . ''; } else { - $link = $sk->makeKnownLinkObj( $titleObj, $wgLang->timeanddate( $ts, true ), - "target=".$this->mTargetObj->getPrefixedUrl()."×tamp=$ts" ); + $link = $sk->linkKnown( + $titleObj, + $time, + array(), + array( + 'target' => $this->mTargetObj->getPrefixedText(), + 'timestamp' => $ts + ) + ); if( $rev->isDeleted(Revision::DELETED_TEXT) ) $link = '' . $link . ''; return $link; @@ -1193,13 +1235,21 @@ class UndeleteForm { * @return string */ function getFileLink( $file, $titleObj, $ts, $key, $sk ) { - global $wgLang; + global $wgLang, $wgUser; if( !$file->userCan(File::DELETED_FILE) ) { return '' . $wgLang->timeanddate( $ts, true ) . ''; } else { - $link = $sk->makeKnownLinkObj( $titleObj, $wgLang->timeanddate( $ts, true ), - "target=".$this->mTargetObj->getPrefixedUrl()."&file=$key" ); + $link = $sk->linkKnown( + $titleObj, + $wgLang->timeanddate( $ts, true ), + array(), + array( + 'target' => $this->mTargetObj->getPrefixedText(), + 'file' => $key, + 'token' => $wgUser->editToken( $key ) + ) + ); if( $file->isDeleted(File::DELETED_FILE) ) $link = '' . $link . ''; return $link; @@ -1258,11 +1308,11 @@ class UndeleteForm { $wgUser, $this->mComment) ); $skin = $wgUser->getSkin(); - $link = $skin->makeKnownLinkObj( $this->mTargetObj ); - $wgOut->addHtml( wfMsgWikiHtml( 'undeletedpage', $link ) ); + $link = $skin->linkKnown( $this->mTargetObj ); + $wgOut->addHTML( wfMsgWikiHtml( 'undeletedpage', $link ) ); } else { $wgOut->showFatalError( wfMsg( "cannotundelete" ) ); - $wgOut->addHtml( '

        ' . wfMsgHtml( "undeleterevdel" ) . '

        ' ); + $wgOut->addHTML( '

        ' . wfMsgHtml( "undeleterevdel" ) . '

        ' ); } // Show file deletion warnings and errors
" . - $this->diffHeader( $previousRev ) . - "" . - $this->diffHeader( $currentRev ) . - "
" . + " . wfMsgWikiHtml( 'undeleteextrahelp' ) . "
  " . - 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' ) ) . "