From 396b28f3d881f5debd888ba9bb9b47c2d478a76f Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Mon, 15 Dec 2008 18:02:47 +0100 Subject: update to Mediawiki 1.13.3; some cleanups --- includes/SpecialUndelete.php | 1075 ------------------------------------------ 1 file changed, 1075 deletions(-) delete mode 100644 includes/SpecialUndelete.php (limited to 'includes/SpecialUndelete.php') diff --git a/includes/SpecialUndelete.php b/includes/SpecialUndelete.php deleted file mode 100644 index e6f6298c..00000000 --- a/includes/SpecialUndelete.php +++ /dev/null @@ -1,1075 +0,0 @@ -execute(); -} - -/** - * Used to show archived pages and eventually restore them. - * @addtogroup SpecialPage - */ -class PageArchive { - protected $title; - var $fileStatus; - - function __construct( $title ) { - if( is_null( $title ) ) { - throw new MWException( 'Archiver() given a null title.'); - } - $this->title = $title; - } - - /** - * List all deleted pages recorded in the archive table. Returns result - * wrapper with (ar_namespace, ar_title, count) fields, ordered by page - * namespace/title. - * - * @return ResultWrapper - */ - public static function listAllPages() { - $dbr = wfGetDB( DB_SLAVE ); - return self::listPages( $dbr, '' ); - } - - /** - * List deleted pages recorded in the archive table matching the - * given title prefix. - * Returns result wrapper with (ar_namespace, ar_title, count) fields. - * - * @return ResultWrapper - */ - public static function listPagesByPrefix( $prefix ) { - $dbr = wfGetDB( DB_SLAVE ); - - $title = Title::newFromText( $prefix ); - if( $title ) { - $ns = $title->getNamespace(); - $encPrefix = $dbr->escapeLike( $title->getDBkey() ); - } else { - // Prolly won't work too good - // @todo handle bare namespace names cleanly? - $ns = 0; - $encPrefix = $dbr->escapeLike( $prefix ); - } - $conds = array( - 'ar_namespace' => $ns, - "ar_title LIKE '$encPrefix%'", - ); - return self::listPages( $dbr, $conds ); - } - - protected static function listPages( $dbr, $condition ) { - return $dbr->resultObject( - $dbr->select( - array( 'archive' ), - array( - 'ar_namespace', - 'ar_title', - 'COUNT(*) AS count', - ), - $condition, - __METHOD__, - array( - 'GROUP BY' => 'ar_namespace,ar_title', - 'ORDER BY' => 'ar_namespace,ar_title', - 'LIMIT' => 100, - ) - ) - ); - } - - /** - * List the revisions of the given page. Returns result wrapper with - * (ar_minor_edit, ar_timestamp, ar_user, ar_user_text, ar_comment) fields. - * - * @return ResultWrapper - */ - function listRevisions() { - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'archive', - array( 'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text', 'ar_comment', 'ar_len' ), - array( 'ar_namespace' => $this->title->getNamespace(), - 'ar_title' => $this->title->getDBkey() ), - 'PageArchive::listRevisions', - array( 'ORDER BY' => 'ar_timestamp DESC' ) ); - $ret = $dbr->resultObject( $res ); - return $ret; - } - - /** - * List the deleted file revisions for this page, if it's a file page. - * Returns a result wrapper with various filearchive fields, or null - * if not a file page. - * - * @return ResultWrapper - * @todo Does this belong in Image for fuller encapsulation? - */ - function listFiles() { - if( $this->title->getNamespace() == NS_IMAGE ) { - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'filearchive', - array( - 'fa_id', - 'fa_name', - 'fa_storage_key', - 'fa_size', - 'fa_width', - 'fa_height', - 'fa_description', - 'fa_user', - 'fa_user_text', - 'fa_timestamp' ), - array( 'fa_name' => $this->title->getDBkey() ), - __METHOD__, - array( 'ORDER BY' => 'fa_timestamp DESC' ) ); - $ret = $dbr->resultObject( $res ); - return $ret; - } - return null; - } - - /** - * Fetch (and decompress if necessary) the stored text for the deleted - * revision of the page with the given timestamp. - * - * @return string - * @deprecated Use getRevision() for more flexible information - */ - function getRevisionText( $timestamp ) { - $rev = $this->getRevision( $timestamp ); - return $rev ? $rev->getText() : null; - } - - /** - * Return a Revision object containing data for the deleted revision. - * Note that the result *may* or *may not* have a null page ID. - * @param string $timestamp - * @return Revision - */ - function getRevision( $timestamp ) { - $dbr = wfGetDB( DB_SLAVE ); - $row = $dbr->selectRow( 'archive', - array( - 'ar_rev_id', - 'ar_text', - 'ar_comment', - 'ar_user', - 'ar_user_text', - 'ar_timestamp', - 'ar_minor_edit', - 'ar_flags', - 'ar_text_id', - 'ar_len' ), - array( 'ar_namespace' => $this->title->getNamespace(), - 'ar_title' => $this->title->getDBkey(), - '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 ) ); - } else { - return null; - } - } - - /** - * Return the most-previous revision, either live or deleted, against - * the deleted revision given by timestamp. - * - * May produce unexpected results in case of history merges or other - * unusual time issues. - * - * @param string $timestamp - * @return Revision or null - */ - function getPreviousRevision( $timestamp ) { - $dbr = wfGetDB( DB_SLAVE ); - - // Check the previous deleted revision... - $row = $dbr->selectRow( 'archive', - 'ar_timestamp', - array( 'ar_namespace' => $this->title->getNamespace(), - 'ar_title' => $this->title->getDBkey(), - 'ar_timestamp < ' . - $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ), - __METHOD__, - array( - 'ORDER BY' => 'ar_timestamp DESC', - 'LIMIT' => 1 ) ); - $prevDeleted = $row ? wfTimestamp( TS_MW, $row->ar_timestamp ) : false; - - $row = $dbr->selectRow( array( 'page', 'revision' ), - array( 'rev_id', 'rev_timestamp' ), - array( - 'page_namespace' => $this->title->getNamespace(), - 'page_title' => $this->title->getDBkey(), - 'page_id = rev_page', - 'rev_timestamp < ' . - $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ), - __METHOD__, - array( - 'ORDER BY' => 'rev_timestamp DESC', - 'LIMIT' => 1 ) ); - $prevLive = $row ? wfTimestamp( TS_MW, $row->rev_timestamp ) : false; - $prevLiveId = $row ? intval( $row->rev_id ) : null; - - if( $prevLive && $prevLive > $prevDeleted ) { - // Most prior revision was live - return Revision::newFromId( $prevLiveId ); - } elseif( $prevDeleted ) { - // Most prior revision was deleted - return $this->getRevision( $prevDeleted ); - } else { - // No prior revision on this page. - return null; - } - } - - /** - * Get the text from an archive row containing ar_text, ar_flags and ar_text_id - */ - function getTextFromRow( $row ) { - if( is_null( $row->ar_text_id ) ) { - // An old row from MediaWiki 1.4 or previous. - // Text is embedded in this row in classic compression format. - return Revision::getRevisionText( $row, "ar_" ); - } else { - // New-style: keyed to the text storage backend. - $dbr = wfGetDB( DB_SLAVE ); - $text = $dbr->selectRow( 'text', - array( 'old_text', 'old_flags' ), - array( 'old_id' => $row->ar_text_id ), - __METHOD__ ); - return Revision::getRevisionText( $text ); - } - } - - - /** - * Fetch (and decompress if necessary) the stored text of the most - * recently edited deleted revision of the page. - * - * If there are no archived revisions for the page, returns NULL. - * - * @return string - */ - function getLastRevisionText() { - $dbr = wfGetDB( DB_SLAVE ); - $row = $dbr->selectRow( 'archive', - array( 'ar_text', 'ar_flags', 'ar_text_id' ), - array( 'ar_namespace' => $this->title->getNamespace(), - 'ar_title' => $this->title->getDBkey() ), - 'PageArchive::getLastRevisionText', - array( 'ORDER BY' => 'ar_timestamp DESC' ) ); - if( $row ) { - return $this->getTextFromRow( $row ); - } else { - return NULL; - } - } - - /** - * Quick check if any archived revisions are present for the page. - * @return bool - */ - function isDeleted() { - $dbr = wfGetDB( DB_SLAVE ); - $n = $dbr->selectField( 'archive', 'COUNT(ar_title)', - array( 'ar_namespace' => $this->title->getNamespace(), - 'ar_title' => $this->title->getDBkey() ) ); - return ($n > 0); - } - - /** - * Restore the given (or all) text and file revisions for the page. - * Once restored, the items will be removed from the archive tables. - * The deletion log will be updated with an undeletion notice. - * - * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete. - * @param string $comment - * @param array $fileVersions - * - * @return array(number of file revisions restored, number of image revisions restored, log message) - * on success, false on failure - */ - function undelete( $timestamps, $comment = '', $fileVersions = array() ) { - // If both the set of text revisions and file revisions are empty, - // restore everything. Otherwise, just restore the requested items. - $restoreAll = empty( $timestamps ) && empty( $fileVersions ); - - $restoreText = $restoreAll || !empty( $timestamps ); - $restoreFiles = $restoreAll || !empty( $fileVersions ); - - if( $restoreFiles && $this->title->getNamespace() == NS_IMAGE ) { - $img = wfLocalFile( $this->title ); - $this->fileStatus = $img->restore( $fileVersions ); - $filesRestored = $this->fileStatus->successCount; - } else { - $filesRestored = 0; - } - - if( $restoreText ) { - $textRestored = $this->undeleteRevisions( $timestamps ); - if($textRestored === false) // It must be one of UNDELETE_* - return false; - } else { - $textRestored = 0; - } - - // Touch the log! - global $wgContLang; - $log = new LogPage( 'delete' ); - - if( $textRestored && $filesRestored ) { - $reason = wfMsgExt( 'undeletedrevisions-files', array( 'content', 'parsemag' ), - $wgContLang->formatNum( $textRestored ), - $wgContLang->formatNum( $filesRestored ) ); - } elseif( $textRestored ) { - $reason = wfMsgExt( 'undeletedrevisions', array( 'content', 'parsemag' ), - $wgContLang->formatNum( $textRestored ) ); - } elseif( $filesRestored ) { - $reason = wfMsgExt( 'undeletedfiles', array( 'content', 'parsemag' ), - $wgContLang->formatNum( $filesRestored ) ); - } else { - wfDebug( "Undelete: nothing undeleted...\n" ); - return false; - } - - if( trim( $comment ) != '' ) - $reason .= ": {$comment}"; - $log->addEntry( 'restore', $this->title, $reason ); - - return array($textRestored, $filesRestored, $reason); - } - - /** - * This is the meaty bit -- restores archived revisions of the given page - * to the cur/old tables. If the page currently exists, all revisions will - * be stuffed into old, otherwise the most recent will go into cur. - * - * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete. - * @param string $comment - * @param array $fileVersions - * - * @return mixed number of revisions restored or false on failure - */ - private function undeleteRevisions( $timestamps ) { - if ( wfReadOnly() ) - return false; - - $restoreAll = empty( $timestamps ); - - $dbw = wfGetDB( DB_MASTER ); - - # Does this page already exist? We'll have to update it... - $article = new Article( $this->title ); - $options = 'FOR UPDATE'; - $page = $dbw->selectRow( 'page', - array( 'page_id', 'page_latest' ), - array( 'page_namespace' => $this->title->getNamespace(), - 'page_title' => $this->title->getDBkey() ), - __METHOD__, - $options ); - if( $page ) { - # Page already exists. Import the history, and if necessary - # we'll update the latest revision field in the record. - $newid = 0; - $pageId = $page->page_id; - $previousRevId = $page->page_latest; - } else { - # Have to create a new article... - $newid = $article->insertOn( $dbw ); - $pageId = $newid; - $previousRevId = 0; - } - - if( $restoreAll ) { - $oldones = '1 = 1'; # All revisions... - } else { - $oldts = implode( ',', - array_map( array( &$dbw, 'addQuotes' ), - array_map( array( &$dbw, 'timestamp' ), - $timestamps ) ) ); - - $oldones = "ar_timestamp IN ( {$oldts} )"; - } - - /** - * Restore each revision... - */ - $result = $dbw->select( 'archive', - /* fields */ array( - 'ar_rev_id', - 'ar_text', - 'ar_comment', - 'ar_user', - 'ar_user_text', - 'ar_timestamp', - 'ar_minor_edit', - 'ar_flags', - 'ar_text_id', - 'ar_page_id', - 'ar_len' ), - /* WHERE */ array( - 'ar_namespace' => $this->title->getNamespace(), - 'ar_title' => $this->title->getDBkey(), - $oldones ), - __METHOD__, - /* options */ array( - 'ORDER BY' => 'ar_timestamp' ) - ); - if( $dbw->numRows( $result ) < count( $timestamps ) ) { - wfDebug( __METHOD__.": couldn't find all requested rows\n" ); - return false; - } - - $revision = null; - $restored = 0; - - while( $row = $dbw->fetchObject( $result ) ) { - 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_' ); - } - $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, - 'len' => $row->ar_len - ) ); - $revision->insertOn( $dbw ); - $restored++; - - wfRunHooks( 'ArticleRevisionUndeleted', array( &$this->title, $revision, $row->ar_page_id ) ); - } - // Was anything restored at all? - 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 ); - } - - if( $newid ) { - wfRunHooks( 'ArticleUndelete', array( &$this->title, true ) ); - Article::onArticleCreate( $this->title ); - } else { - wfRunHooks( 'ArticleUndelete', array( &$this->title, false ) ); - Article::onArticleEdit( $this->title ); - } - - if( $this->title->getNamespace() == NS_IMAGE ) { - $update = new HTMLCacheUpdate( $this->title, 'imagelinks' ); - $update->doUpdate(); - } - } else { - // Revision couldn't be created. This is very weird - 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; - } - - function getFileStatus() { return $this->fileStatus; } -} - -/** - * The HTML form for Special:Undelete, which allows users with the appropriate - * permissions to view and restore deleted content. - * @addtogroup SpecialPage - */ -class UndeleteForm { - var $mAction, $mTarget, $mTimestamp, $mRestore, $mTargetObj; - var $mTargetTimestamp, $mAllowed, $mComment; - - function UndeleteForm( $request, $par = "" ) { - global $wgUser; - $this->mAction = $request->getVal( 'action' ); - $this->mTarget = $request->getVal( 'target' ); - $this->mSearchPrefix = $request->getText( 'prefix' ); - $time = $request->getVal( 'timestamp' ); - $this->mTimestamp = $time ? wfTimestamp( TS_MW, $time ) : ''; - $this->mFile = $request->getVal( 'file' ); - - $posted = $request->wasPosted() && - $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) ); - $this->mRestore = $request->getCheck( 'restore' ) && $posted; - $this->mPreview = $request->getCheck( 'preview' ) && $posted; - $this->mDiff = $request->getCheck( 'diff' ); - $this->mComment = $request->getText( 'wpComment' ); - - if( $par != "" ) { - $this->mTarget = $par; - } - if ( $wgUser->isAllowed( 'undelete' ) && !$wgUser->isBlocked() ) { - $this->mAllowed = true; - } else { - $this->mAllowed = false; - $this->mTimestamp = ''; - $this->mRestore = false; - } - if ( $this->mTarget !== "" ) { - $this->mTargetObj = Title::newFromURL( $this->mTarget ); - } else { - $this->mTargetObj = NULL; - } - if( $this->mRestore ) { - $timestamps = array(); - $this->mFileVersions = array(); - foreach( $_REQUEST as $key => $val ) { - $matches = array(); - if( preg_match( '/^ts(\d{14})$/', $key, $matches ) ) { - array_push( $timestamps, $matches[1] ); - } - - if( preg_match( '/^fileid(\d+)$/', $key, $matches ) ) { - $this->mFileVersions[] = intval( $matches[1] ); - } - } - rsort( $timestamps ); - $this->mTargetTimestamp = $timestamps; - } - } - - function execute() { - global $wgOut; - if ( $this->mAllowed ) { - $wgOut->setPagetitle( wfMsg( "undeletepage" ) ); - } else { - $wgOut->setPagetitle( wfMsg( "viewdeletedpage" ) ); - } - - if( is_null( $this->mTargetObj ) ) { - $this->showSearchForm(); - - # List undeletable articles - if( $this->mSearchPrefix ) { - $result = PageArchive::listPagesByPrefix( - $this->mSearchPrefix ); - $this->showList( $result ); - } - return; - } - if( $this->mTimestamp !== '' ) { - return $this->showRevision( $this->mTimestamp ); - } - if( $this->mFile !== null ) { - return $this->showFile( $this->mFile ); - } - if( $this->mRestore && $this->mAction == "submit" ) { - return $this->undelete(); - } - return $this->showHistory(); - } - - function showSearchForm() { - global $wgOut, $wgScript; - $wgOut->addWikiMsg( 'undelete-header' ); - - $wgOut->addHtml( - Xml::openElement( 'form', array( - 'method' => 'get', - 'action' => $wgScript ) ) . - '
' . - Xml::element( 'legend', array(), - wfMsg( 'undelete-search-box' ) ) . - Xml::hidden( 'title', - SpecialPage::getTitleFor( 'Undelete' )->getPrefixedDbKey() ) . - Xml::inputLabel( wfMsg( 'undelete-search-prefix' ), - 'prefix', 'prefix', 20, - $this->mSearchPrefix ) . - Xml::submitButton( wfMsg( 'undelete-search-submit' ) ) . - '
' . - '' ); - } - - /* private */ function showList( $result ) { - global $wgLang, $wgContLang, $wgUser, $wgOut; - - if( $result->numRows() == 0 ) { - $wgOut->addWikiMsg( 'undelete-no-results' ); - return; - } - - $wgOut->addWikiMsg( "undeletepagetext" ); - - $sk = $wgUser->getSkin(); - $undelete = SpecialPage::getTitleFor( 'Undelete' ); - $wgOut->addHTML( "\n" ); - - return true; - } - - /* private */ function showRevision( $timestamp ) { - global $wgLang, $wgUser, $wgOut; - $self = SpecialPage::getTitleFor( 'Undelete' ); - $skin = $wgUser->getSkin(); - - if(!preg_match("/[0-9]{14}/",$timestamp)) return 0; - - $archive = new PageArchive( $this->mTargetObj ); - $rev = $archive->getRevision( $timestamp ); - - if( !$rev ) { - $wgOut->addWikiMsg( 'undeleterevision-missing' ); - return; - } - - $wgOut->setPageTitle( wfMsg( 'undeletepage' ) ); - - $link = $skin->makeKnownLinkObj( - SpecialPage::getTitleFor( 'Undelete', $this->mTargetObj->getPrefixedDBkey() ), - htmlspecialchars( $this->mTargetObj->getPrefixedText() ) - ); - $time = htmlspecialchars( $wgLang->timeAndDate( $timestamp, true ) ); - $user = $skin->userLink( $rev->getUser(), $rev->getUserText() ) - . $skin->userToolLinks( $rev->getUser(), $rev->getUserText() ); - - if( $this->mDiff ) { - $previousRev = $archive->getPreviousRevision( $timestamp ); - if( $previousRev ) { - $this->showDiff( $previousRev, $rev ); - if( $wgUser->getOption( 'diffonly' ) ) { - return; - } else { - $wgOut->addHtml( '
' ); - } - } else { - $wgOut->addHtml( wfMsgHtml( 'undelete-nodiff' ) ); - } - } - - $wgOut->addHtml( '

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

' ); - - wfRunHooks( 'UndeleteShowRevision', array( $this->mTargetObj, $rev ) ); - - if( $this->mPreview ) { - $wgOut->addHtml( "
\n" ); - $wgOut->addWikiTextTitleTidy( $rev->getText(), $this->mTargetObj, false ); - } - - $wgOut->addHtml( - wfElement( 'textarea', array( - 'readonly' => 'readonly', - 'cols' => intval( $wgUser->getOption( 'cols' ) ), - 'rows' => intval( $wgUser->getOption( 'rows' ) ) ), - $rev->getText() . "\n" ) . - wfOpenElement( 'div' ) . - wfOpenElement( 'form', array( - 'method' => 'post', - 'action' => $self->getLocalURL( "action=submit" ) ) ) . - wfElement( 'input', array( - 'type' => 'hidden', - 'name' => 'target', - 'value' => $this->mTargetObj->getPrefixedDbKey() ) ) . - wfElement( 'input', array( - 'type' => 'hidden', - 'name' => 'timestamp', - 'value' => $timestamp ) ) . - wfElement( 'input', array( - 'type' => 'hidden', - 'name' => 'wpEditToken', - 'value' => $wgUser->editToken() ) ) . - wfElement( 'input', array( - 'type' => 'submit', - 'name' => 'preview', - 'value' => wfMsg( 'showpreview' ) ) ) . - wfElement( 'input', array( - 'name' => 'diff', - 'type' => 'submit', - 'value' => wfMsg( 'showdiff' ) ) ) . - wfCloseElement( 'form' ) . - wfCloseElement( 'div' ) ); - } - - /** - * Build a diff display between this and the previous either deleted - * or non-deleted edit. - * @param Revision $previousRev - * @param Revision $currentRev - * @return string HTML - */ - function showDiff( $previousRev, $currentRev ) { - global $wgOut, $wgUser; - - $diffEngine = new DifferenceEngine(); - $diffEngine->showDiffStyle(); - $wgOut->addHtml( - "
" . - "" . - "" . - "" . - "" . - "" . - "" . - "" . - "" . - "" . - $diffEngine->generateDiffBody( - $previousRev->getText(), $currentRev->getText() ) . - "
" . - $this->diffHeader( $previousRev ) . - "" . - $this->diffHeader( $currentRev ) . - "
" . - "
\n" ); - - } - - private function diffHeader( $rev ) { - 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() ); - } else { - /// @fixme getId() may return non-zero for deleted revs... - $targetPage = $rev->getTitle(); - $targetQuery = 'oldid=' . $rev->getId(); - } - return - '
' . - $sk->makeLinkObj( $targetPage, - wfMsgHtml( 'revisionasof', - $wgLang->timeanddate( $rev->getTimestamp(), true ) ), - $targetQuery ) . - ( $isDeleted ? ' ' . wfMsgHtml( 'deletedrev' ) : '' ) . - '
' . - '
' . - $sk->revUserTools( $rev ) . '
' . - '
' . - '
' . - $sk->revComment( $rev ) . '
' . - '
'; - } - - /** - * Show a deleted file version requested by the visitor. - */ - function showFile( $key ) { - global $wgOut, $wgRequest; - $wgOut->disable(); - - # We mustn't allow the output to be Squid cached, otherwise - # if an admin previews a deleted image, and it's cached, then - # a user without appropriate permissions can toddle off and - # nab the image, and Squid will serve it - $wgRequest->response()->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' ); - $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 ); - } - - /* private */ function showHistory() { - global $wgLang, $wgContLang, $wgUser, $wgOut; - - $sk = $wgUser->getSkin(); - if ( $this->mAllowed ) { - $wgOut->setPagetitle( wfMsg( "undeletepage" ) ); - } else { - $wgOut->setPagetitle( wfMsg( 'viewdeletedpage' ) ); - } - - $archive = new PageArchive( $this->mTargetObj ); - /* - $text = $archive->getLastRevisionText(); - if( is_null( $text ) ) { - $wgOut->addWikiMsg( "nohistory" ); - return; - } - */ - if ( $this->mAllowed ) { - $wgOut->addWikiMsg( "undeletehistory" ); - } else { - $wgOut->addWikiMsg( "undeletehistorynoadmin" ); - } - - # List all stored revisions - $revisions = $archive->listRevisions(); - $files = $archive->listFiles(); - - $haveRevisions = $revisions && $revisions->numRows() > 0; - $haveFiles = $files && $files->numRows() > 0; - - # Batch existence check on user and talk pages - if( $haveRevisions ) { - $batch = new LinkBatch(); - while( $row = $revisions->fetchObject() ) { - $batch->addObj( Title::makeTitleSafe( NS_USER, $row->ar_user_text ) ); - $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->ar_user_text ) ); - } - $batch->execute(); - $revisions->seek( 0 ); - } - if( $haveFiles ) { - $batch = new LinkBatch(); - while( $row = $files->fetchObject() ) { - $batch->addObj( Title::makeTitleSafe( NS_USER, $row->fa_user_text ) ); - $batch->addObj( Title::makeTitleSafe( NS_USER_TALK, $row->fa_user_text ) ); - } - $batch->execute(); - $files->seek( 0 ); - } - - if ( $this->mAllowed ) { - $titleObj = SpecialPage::getTitleFor( "Undelete" ); - $action = $titleObj->getLocalURL( "action=submit" ); - # Start the form here - $top = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $action, 'id' => 'undelete' ) ); - $wgOut->addHtml( $top ); - } - - # Show relevant lines from the deletion log: - $wgOut->addHTML( "

" . htmlspecialchars( LogPage::logName( 'delete' ) ) . "

\n" ); - $logViewer = new LogViewer( - new LogReader( - new FauxRequest( - array( - 'page' => $this->mTargetObj->getPrefixedText(), - 'type' => 'delete' - ) - ) - ), LogViewer::NO_ACTION_LINK - ); - $logViewer->showList( $wgOut ); - - if( $this->mAllowed && ( $haveRevisions || $haveFiles ) ) { - # Format the user-visible controls (comment field, submission button) - # in a nice little table - $align = $wgContLang->isRtl() ? 'left' : 'right'; - $table = - Xml::openElement( 'fieldset' ) . - Xml::openElement( 'table' ) . - " - " . - wfMsgWikiHtml( 'undeleteextrahelp' ) . - " - - - " . - Xml::label( wfMsg( 'undeletecomment' ), 'wpComment' ) . - " - " . - Xml::input( 'wpComment', 50, $this->mComment ) . - " - - -   - " . - 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::closeElement( 'table' ) . - Xml::closeElement( 'fieldset' ); - - $wgOut->addHtml( $table ); - } - - $wgOut->addHTML( "

" . htmlspecialchars( wfMsg( "history" ) ) . "

\n" ); - - if( $haveRevisions ) { - # The page's stored (deleted) history: - $wgOut->addHTML(""); - } else { - $wgOut->addWikiMsg( "nohistory" ); - } - - if( $haveFiles ) { - $wgOut->addHtml( "

" . wfMsgHtml( 'filehist' ) . "

\n" ); - $wgOut->addHtml( "" ); - } - - if ( $this->mAllowed ) { - # Slip in the hidden controls here - $misc = Xml::hidden( 'target', $this->mTarget ); - $misc .= Xml::hidden( 'wpEditToken', $wgUser->editToken() ); - $misc .= Xml::closeElement( 'form' ); - $wgOut->addHtml( $misc ); - } - - return true; - } - - 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; - } - - function undelete() { - global $wgOut, $wgUser; - if ( wfReadOnly() ) { - $wgOut->readOnlyPage(); - return; - } - if( !is_null( $this->mTargetObj ) ) { - $archive = new PageArchive( $this->mTargetObj ); - - $ok = $archive->undelete( - $this->mTargetTimestamp, - $this->mComment, - $this->mFileVersions ); - - if( is_array($ok) ) { - $skin = $wgUser->getSkin(); - $link = $skin->makeKnownLinkObj( $this->mTargetObj ); - $wgOut->addHtml( wfMsgWikiHtml( 'undeletedpage', $link ) ); - } else { - $wgOut->showFatalError( wfMsg( "cannotundelete" ) ); - } - - // Show file deletion warnings and errors - $status = $archive->getFileStatus(); - if ( $status && !$status->isGood() ) { - $wgOut->addWikiText( $status->getWikiText( 'undelete-error-short', 'undelete-error-long' ) ); - } - } else { - $wgOut->showFatalError( wfMsg( "cannotundelete" ) ); - } - return false; - } -} -- cgit v1.2.3-54-g00ecf