From 4f68ae893915980542a87bfa44aff010df1f92d7 Mon Sep 17 00:00:00 2001 From: Alexandre Emsenhuber Date: Tue, 27 Dec 2011 15:29:44 +0000 Subject: [PATCH] * Integrate $wgDeleteRevisionsLimit in Title::getUserPermissionsErrors() (only if doing expensive checks) * Moved WikiPage::estimateRevisionCount() and WikiPage::isBigDeletion() to Title and marked those WikiPage methods as deprecated (only call in extensions removed in r107385) * Show an error message when deleting a page to move another one in Special:MovePage and the deletion fails due to permissions errors (previously the form would simply show again) * Cache the result of Title::estimateRevisionCount() since it's called two times when showing the deletion form and the user doesn't have 'bigdelete' right (one for the permissions check and the other when showing the number of revisions) --- includes/Article.php | 14 +-------- includes/Title.php | 45 +++++++++++++++++++++++++++ includes/WikiPage.php | 26 +++++++--------- includes/api/ApiDelete.php | 5 --- includes/specials/SpecialMovepage.php | 13 ++++---- 5 files changed, 64 insertions(+), 39 deletions(-) diff --git a/includes/Article.php b/includes/Article.php index d32bec7f12..b6c8042a81 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -1289,18 +1289,6 @@ class Article extends Page { return; } - # Hack for big sites - $bigHistory = $this->mPage->isBigDeletion(); - if ( $bigHistory && !$title->userCan( 'bigdelete' ) ) { - global $wgDeleteRevisionsLimit; - - $wgOut->setPageTitle( wfMessage( 'cannotdelete-title', $title->getPrefixedText() ) ); - $wgOut->wrapWikiMsg( "
\n$1\n
\n", - array( 'delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) ); - - return; - } - $deleteReasonList = $wgRequest->getText( 'wpDeleteReasonList', 'other' ); $deleteReason = $wgRequest->getText( 'wpReason' ); @@ -1338,7 +1326,7 @@ class Article extends Page { // If the page has a history, insert a warning if ( $hasHistory ) { - $revisions = $this->mPage->estimateRevisionCount(); + $revisions = $this->mTitle->estimateRevisionCount(); // @todo FIXME: i18n issue/patchwork message $wgOut->addHTML( '' . wfMsgExt( 'historywarning', array( 'parseinline' ), $wgLang->formatNum( $revisions ) ) . diff --git a/includes/Title.php b/includes/Title.php index a20ca281e6..31bfbf859b 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -64,6 +64,7 @@ class Title { var $mArticleID = -1; // /< Article ID, fetched from the link cache on demand var $mLatestID = false; // /< ID of most recent revision var $mCounter = -1; // /< Number of times this page has been viewed (-1 means "not loaded") + private $mEstimateRevisions; // /< Estimated number of revisions; null of not loaded var $mRestrictions = array(); // /< Array of groups allowed to edit this article var $mOldRestrictions = false; var $mCascadeRestriction; ///< Cascade restrictions on this page to included templates and images? @@ -1843,6 +1844,8 @@ class Title { * @return Array list of errors */ private function checkActionPermissions( $action, $user, $errors, $doExpensiveQueries, $short ) { + global $wgDeleteRevisionsLimit, $wgLang; + if ( $action == 'protect' ) { if ( count( $this->getUserPermissionsErrorsInternal( 'edit', $user, $doExpensiveQueries, true ) ) ) { // If they can't edit, they shouldn't protect. @@ -1875,6 +1878,12 @@ class Title { } elseif ( !$this->isMovable() ) { $errors[] = array( 'immobile-target-page' ); } + } elseif ( $action == 'delete' ) { + if ( $doExpensiveQueries && $wgDeleteRevisionsLimit + && !$this->userCan( 'bigdelete', $user ) && $this->isBigDeletion() ) + { + $errors[] = array( 'delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ); + } } return $errors; } @@ -2887,6 +2896,7 @@ class Title { $this->mLength = -1; $this->mLatestID = false; $this->mCounter = -1; + $this->mEstimateRevisions = null; } /** @@ -4000,6 +4010,41 @@ class Title { return (bool)$dbr->selectField( 'page', 'page_is_new', $this->pageCond(), __METHOD__ ); } + /** + * Check whether the number of revisions of this page surpasses $wgDeleteRevisionsLimit + * + * @return bool + */ + public function isBigDeletion() { + global $wgDeleteRevisionsLimit; + + if ( !$wgDeleteRevisionsLimit ) { + return false; + } + + $revCount = $this->estimateRevisionCount(); + return $revCount > $wgDeleteRevisionsLimit; + } + + /** + * Get the approximate revision count of this page. + * + * @return int + */ + public function estimateRevisionCount() { + if ( !$this->exists() ) { + return 0; + } + + if ( $this->mEstimateRevisions === null ) { + $dbr = wfGetDB( DB_SLAVE ); + $this->mEstimateRevisions = $dbr->estimateRowCount( 'revision', '*', + array( 'rev_page' => $this->getArticleId() ), __METHOD__ ); + } + + return $this->mEstimateRevisions; + } + /** * Get the number of revisions between the given revision. * Used for diffs and other things that really need it. diff --git a/includes/WikiPage.php b/includes/WikiPage.php index c61efe5375..9c77e0a8ab 100644 --- a/includes/WikiPage.php +++ b/includes/WikiPage.php @@ -1560,27 +1560,25 @@ class WikiPage extends Page { } /** - * @return bool whether or not the page surpasses $wgDeleteRevisionsLimit revisions + * Check whether the number of revisions of this page surpasses $wgDeleteRevisionsLimit + * + * @deprecated in 1.19; use Title::isBigDeletion() instead. + * @return bool */ public function isBigDeletion() { - global $wgDeleteRevisionsLimit; - - if ( $wgDeleteRevisionsLimit ) { - $revCount = $this->estimateRevisionCount(); - - return $revCount > $wgDeleteRevisionsLimit; - } - - return false; + wfDeprecated( __METHOD__, '1.19' ); + return $this->mTitle->isBigDeletion(); } /** - * @return int approximate revision count + * Get the approximate revision count of this page. + * + * @deprecated in 1.19; use Title::estimateRevisionCount() instead. + * @return int */ public function estimateRevisionCount() { - $dbr = wfGetDB( DB_SLAVE ); - return $dbr->estimateRowCount( 'revision', '*', - array( 'rev_page' => $this->getId() ), __METHOD__ ); + wfDeprecated( __METHOD__, '1.19' ); + return $this->mTitle->estimateRevisionCount(); } /** diff --git a/includes/api/ApiDelete.php b/includes/api/ApiDelete.php index 6d9a3004bd..4ffa66cc55 100644 --- a/includes/api/ApiDelete.php +++ b/includes/api/ApiDelete.php @@ -112,11 +112,6 @@ class ApiDelete extends ApiBase { * @return Title::getUserPermissionsErrors()-like array */ public static function delete( Page $page, User $user, $token, &$reason = null ) { - if ( $page->isBigDeletion() && !$user->isAllowed( 'bigdelete' ) ) { - global $wgDeleteRevisionsLimit; - return array( array( 'delete-toobig', $wgDeleteRevisionsLimit ) ); - } - $title = $page->getTitle(); $errors = self::getPermissionsError( $title, $user, $token ); if ( count( $errors ) ) { diff --git a/includes/specials/SpecialMovepage.php b/includes/specials/SpecialMovepage.php index 392882c353..800be7fa43 100644 --- a/includes/specials/SpecialMovepage.php +++ b/includes/specials/SpecialMovepage.php @@ -360,13 +360,11 @@ class MovePageForm extends UnlistedSpecialPage { $nt = $this->newTitle; # Delete to make way if requested - if ( !count( $nt->getUserPermissionsErrors( 'delete', $user ) ) && $this->deleteAndMove ) { - $page = WikiPage::factory( $nt ); - - # Disallow deletions of big articles - $bigHistory = $page->isBigDeletion(); - if( $bigHistory && count( $nt->getUserPermissionsErrors( 'bigdelete', $user ) ) ) { - $this->showForm( array( 'delete-toobig', $this->getLanguage()->formatNum( $wgDeleteRevisionsLimit ) ) ); + if ( $this->deleteAndMove ) { + $permErrors = $nt->getUserPermissionsErrors( 'delete', $user ); + if ( count( $permErrors ) ) { + # Only show the first error + $this->showForm( $permErrors[0] ); return; } @@ -381,6 +379,7 @@ class MovePageForm extends UnlistedSpecialPage { } $error = ''; // passed by ref + $page = WikiPage::factory( $nt ); if ( !$page->doDeleteArticle( $reason, false, 0, true, $error, $user ) ) { $this->showForm( array( 'cannotdelete', wfEscapeWikiText( $nt->getPrefixedText() ) ) ); return; -- 2.20.1