From c1f9b1f7b1b77776192048005dcc66dcf3df2bfb Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sat, 27 Dec 2014 15:41:37 +0100 Subject: Update to MediaWiki 1.24.1 --- includes/specials/SpecialUndelete.php | 393 +++++++++++++++++++++------------- 1 file changed, 243 insertions(+), 150 deletions(-) (limited to 'includes/specials/SpecialUndelete.php') diff --git a/includes/specials/SpecialUndelete.php b/includes/specials/SpecialUndelete.php index d4aed113..c3e871b8 100644 --- a/includes/specials/SpecialUndelete.php +++ b/includes/specials/SpecialUndelete.php @@ -27,26 +27,28 @@ * @ingroup SpecialPage */ class PageArchive { - /** - * @var Title - */ + /** @var Title */ protected $title; - /** - * @var Status - */ + /** @var Status */ protected $fileStatus; - /** - * @var Status - */ + /** @var Status */ protected $revisionStatus; - function __construct( $title ) { + /** @var Config */ + protected $config; + + function __construct( $title, Config $config = null ) { if ( is_null( $title ) ) { throw new MWException( __METHOD__ . ' given a null title.' ); } $this->title = $title; + if ( $config === null ) { + wfDebug( __METHOD__ . ' did not have a Config object passed to it' ); + $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' ); + } + $this->config = $config; } /** @@ -58,6 +60,7 @@ class PageArchive { */ public static function listAllPages() { $dbr = wfGetDB( DB_SLAVE ); + return self::listPages( $dbr, '' ); } @@ -96,7 +99,7 @@ class PageArchive { * @return bool|ResultWrapper */ protected static function listPages( $dbr, $condition ) { - return $dbr->resultObject( $dbr->select( + return $dbr->select( array( 'archive' ), array( 'ar_namespace', @@ -110,7 +113,7 @@ class PageArchive { 'ORDER BY' => array( 'ar_namespace', 'ar_title' ), 'LIMIT' => 100, ) - ) ); + ); } /** @@ -120,28 +123,42 @@ class PageArchive { * @return ResultWrapper */ function listRevisions() { - global $wgContentHandlerUseDB; - $dbr = wfGetDB( DB_SLAVE ); + $tables = array( 'archive' ); + $fields = array( 'ar_minor_edit', 'ar_timestamp', 'ar_user', 'ar_user_text', 'ar_comment', 'ar_len', 'ar_deleted', 'ar_rev_id', 'ar_sha1', ); - if ( $wgContentHandlerUseDB ) { + if ( $this->config->get( 'ContentHandlerUseDB' ) ) { $fields[] = 'ar_content_format'; $fields[] = 'ar_content_model'; } - $res = $dbr->select( 'archive', + $conds = array( 'ar_namespace' => $this->title->getNamespace(), + 'ar_title' => $this->title->getDBkey() ); + + $options = array( 'ORDER BY' => 'ar_timestamp DESC' ); + + $join_conds = array(); + + ChangeTags::modifyDisplayQuery( + $tables, $fields, - array( 'ar_namespace' => $this->title->getNamespace(), - 'ar_title' => $this->title->getDBkey() ), - __METHOD__, - array( 'ORDER BY' => 'ar_timestamp DESC' ) ); + $conds, + $join_conds, + $options + ); - return $dbr->resultObject( $res ); + return $dbr->select( $tables, + $fields, + $conds, + __METHOD__, + $options, + $join_conds + ); } /** @@ -158,15 +175,13 @@ class PageArchive { } $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( + return $dbr->select( 'filearchive', ArchivedFile::selectFields(), array( 'fa_name' => $this->title->getDBkey() ), __METHOD__, array( 'ORDER BY' => 'fa_timestamp DESC' ) ); - - return $dbr->resultObject( $res ); } /** @@ -177,8 +192,6 @@ class PageArchive { * @return Revision|null */ function getRevision( $timestamp ) { - global $wgContentHandlerUseDB; - $dbr = wfGetDB( DB_SLAVE ); $fields = array( @@ -196,7 +209,7 @@ class PageArchive { 'ar_sha1', ); - if ( $wgContentHandlerUseDB ) { + if ( $this->config->get( 'ContentHandlerUseDB' ) ) { $fields[] = 'ar_content_format'; $fields[] = 'ar_content_model'; } @@ -318,7 +331,7 @@ class PageArchive { /** * Quick check if any archived revisions are present for the page. * - * @return boolean + * @return bool */ function isDeleted() { $dbr = wfGetDB( DB_SLAVE ); @@ -336,16 +349,18 @@ class PageArchive { * 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 array $timestamps Pass an empty array to restore all revisions, + * otherwise list the ones to undelete. * @param string $comment * @param array $fileVersions * @param bool $unsuppress * @param User $user User performing the action, or null to use $wgUser - * - * @return array(number of file revisions restored, number of image revisions restored, log message) - * on success, false on failure + * @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(), $unsuppress = false, User $user = null ) { + function undelete( $timestamps, $comment = '', $fileVersions = array(), + $unsuppress = false, User $user = null + ) { // 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 ); @@ -388,6 +403,7 @@ class PageArchive { ->inContentLanguage()->text(); } else { wfDebug( "Undelete: nothing undeleted...\n" ); + return false; } @@ -418,15 +434,14 @@ class PageArchive { * 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 array $timestamps Pass an empty array to restore all revisions, + * otherwise list the ones to undelete. * @param bool $unsuppress Remove all ar_deleted/fa_deleted restrictions of seletected revs * @param string $comment * @throws ReadOnlyError - * @return Status Object containing the number of revisions restored on success + * @return Status Status object containing the number of revisions restored on success */ private function undeleteRevisions( $timestamps, $unsuppress = false, $comment = '' ) { - global $wgContentHandlerUseDB; - if ( wfReadOnly() ) { throw new ReadOnlyError(); } @@ -475,15 +490,12 @@ class PageArchive { $previousTimestamp = 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} )"; + $oldWhere = array( + 'ar_namespace' => $this->title->getNamespace(), + 'ar_title' => $this->title->getDBkey(), + ); + if ( !$restoreAll ) { + $oldWhere['ar_timestamp'] = array_map( array( &$dbw, 'timestamp' ), $timestamps ); } $fields = array( @@ -502,7 +514,7 @@ class PageArchive { 'ar_sha1' ); - if ( $wgContentHandlerUseDB ) { + if ( $this->config->get( 'ContentHandlerUseDB' ) ) { $fields[] = 'ar_content_format'; $fields[] = 'ar_content_model'; } @@ -512,27 +524,25 @@ class PageArchive { */ $result = $dbw->select( 'archive', $fields, - /* WHERE */ array( - 'ar_namespace' => $this->title->getNamespace(), - 'ar_title' => $this->title->getDBkey(), - $oldones ), + $oldWhere, __METHOD__, /* options */ array( 'ORDER BY' => 'ar_timestamp' ) ); - $ret = $dbw->resultObject( $result ); - $rev_count = $dbw->numRows( $result ); + $rev_count = $result->numRows(); if ( !$rev_count ) { wfDebug( __METHOD__ . ": no revisions to restore\n" ); $status = Status::newGood( 0 ); $status->warning( "undelete-no-results" ); + return $status; } - $ret->seek( $rev_count - 1 ); // move to last - $row = $ret->fetchObject(); // get newest archived rev - $ret->seek( 0 ); // move back + $result->seek( $rev_count - 1 ); // move to last + $row = $result->fetchObject(); // get newest archived rev + $oldPageId = (int)$row->ar_page_id; // pass this to ArticleUndelete hook + $result->seek( 0 ); // move back // grab the content to check consistency with global state before restoring the page. $revision = Revision::newFromArchiveRow( $row, @@ -574,7 +584,7 @@ class PageArchive { $revision = null; $restored = 0; - foreach ( $ret as $row ) { + foreach ( $result as $row ) { // Check for key dupes due to shitty archive integrity. if ( $row->ar_rev_id ) { $exists = $dbw->selectField( 'revision', '1', @@ -599,10 +609,7 @@ class PageArchive { } # 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 ), + $oldWhere, __METHOD__ ); // Was anything restored at all? @@ -617,10 +624,14 @@ class PageArchive { if ( $created || $wasnew ) { // Update site stats, link tables, etc $user = User::newFromName( $revision->getRawUserText(), false ); - $article->doEditUpdates( $revision, $user, array( 'created' => $created, 'oldcountable' => $oldcountable ) ); + $article->doEditUpdates( + $revision, + $user, + array( 'created' => $created, 'oldcountable' => $oldcountable ) + ); } - wfRunHooks( 'ArticleUndelete', array( &$this->title, $created, $comment ) ); + wfRunHooks( 'ArticleUndelete', array( &$this->title, $created, $comment, $oldPageId ) ); if ( $this->title->getNamespace() == NS_FILE ) { $update = new HTMLCacheUpdate( $this->title, 'imagelinks' ); @@ -652,13 +663,20 @@ class PageArchive { * @ingroup SpecialPage */ class SpecialUndelete extends SpecialPage { - var $mAction, $mTarget, $mTimestamp, $mRestore, $mInvert, $mFilename; - var $mTargetTimestamp, $mAllowed, $mCanView, $mComment, $mToken; - - /** - * @var Title - */ - var $mTargetObj; + private $mAction; + private $mTarget; + private $mTimestamp; + private $mRestore; + private $mInvert; + private $mFilename; + private $mTargetTimestamp; + private $mAllowed; + private $mCanView; + private $mComment; + private $mToken; + + /** @var Title */ + private $mTargetObj; function __construct() { parent::__construct( 'Undelete', 'deletedhistory' ); @@ -697,10 +715,10 @@ class SpecialUndelete extends SpecialPage { $this->mUnsuppress = $request->getVal( 'wpUnsuppress' ) && $user->isAllowed( 'suppressrevision' ); $this->mToken = $request->getVal( 'token' ); - if ( $user->isAllowed( 'undelete' ) && !$user->isBlocked() ) { + if ( $this->isAllowed( 'undelete' ) && !$user->isBlocked() ) { $this->mAllowed = true; // user can restore $this->mCanView = true; // user can view content - } elseif ( $user->isAllowed( 'deletedtext' ) ) { + } elseif ( $this->isAllowed( 'deletedtext' ) ) { $this->mAllowed = false; // user cannot restore $this->mCanView = true; // user can view content $this->mRestore = false; @@ -729,14 +747,35 @@ class SpecialUndelete extends SpecialPage { } } + /** + * Checks whether a user is allowed the permission for the + * specific title if one is set. + * + * @param string $permission + * @param User $user + * @return bool + */ + private function isAllowed( $permission, User $user = null ) { + $user = $user ? : $this->getUser(); + if ( $this->mTargetObj !== null ) { + return $this->mTargetObj->userCan( $permission, $user ); + } else { + return $user->isAllowed( $permission ); + } + } + + function userCanExecute( User $user ) { + return $this->isAllowed( $this->mRestriction, $user ); + } + function execute( $par ) { - $this->checkPermissions(); $user = $this->getUser(); $this->setHeaders(); $this->outputHeader(); $this->loadRequest( $par ); + $this->checkPermissions(); // Needs to be after mTargetObj is set $out = $this->getOutput(); @@ -747,6 +786,7 @@ class SpecialUndelete extends SpecialPage { if ( $user->isAllowed( 'browsearchive' ) ) { $this->showSearchForm(); } + return; } @@ -784,14 +824,12 @@ class SpecialUndelete extends SpecialPage { } function showSearchForm() { - global $wgScript; - $out = $this->getOutput(); $out->setPageTitle( $this->msg( 'undelete-search-title' ) ); $out->addHTML( - Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) . + Xml::openElement( 'form', array( 'method' => 'get', 'action' => wfScript() ) ) . Xml::fieldset( $this->msg( 'undelete-search-box' )->text() ) . - Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . + Html::hidden( 'title', $this->getPageTitle()->getPrefixedDBkey() ) . Html::rawElement( 'label', array( 'for' => 'prefix' ), @@ -826,12 +864,13 @@ class SpecialUndelete extends SpecialPage { if ( $result->numRows() == 0 ) { $out->addWikiMsg( 'undelete-no-results' ); + return false; } $out->addWikiMsg( 'undeletepagetext', $this->getLanguage()->formatNum( $result->numRows() ) ); - $undelete = $this->getTitle(); + $undelete = $this->getPageTitle(); $out->addHTML( "