From 80b68ec0cc29d1e329ed18ee5397789483143564 Mon Sep 17 00:00:00 2001 From: Marius Hoch Date: Sat, 3 May 2014 18:47:25 +0200 Subject: [PATCH] Don't estimate the revision count for page deletions Often the estimated revision count is several thousands away from the real one, thus disallowing normal sysops to delete pages which they actually should be able to delete. This also changes the revision number shown to users on action=delete to the real one, as that code path is only being hit for users that can delete the page. Bug: 69556 Change-Id: Id0d02aa9960477a0cec8752ef714b6bc6b9ff2ac --- includes/Title.php | 30 +++++++++++++++++++++++++++--- includes/page/Article.php | 17 +++++++++++++++-- languages/i18n/en.json | 2 +- languages/i18n/qqq.json | 2 +- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/includes/Title.php b/includes/Title.php index a1b2352f5e..2fba4f7efd 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -158,6 +158,9 @@ class Title { /** @var TitleValue A corresponding TitleValue object */ private $mTitleValue = null; + + /** @var bool Would deleting this page be a big deletion? */ + private $mIsBigDeletion = null; // @} /** @@ -3258,6 +3261,7 @@ class Title { $this->mEstimateRevisions = null; $this->mPageLanguage = false; $this->mDbPageLanguage = null; + $this->mIsBigDeletion = null; } /** @@ -4364,12 +4368,32 @@ class Title { return false; } - $revCount = $this->estimateRevisionCount(); - return $revCount > $wgDeleteRevisionsLimit; + if ( $this->mIsBigDeletion === null ) { + $dbr = wfGetDB( DB_SLAVE ); + + $innerQuery = $dbr->selectSQLText( + 'revision', + '1', + array( 'rev_page' => $this->getArticleID() ), + __METHOD__, + array( 'LIMIT' => $wgDeleteRevisionsLimit + 1 ) + ); + + $revCount = $dbr->query( + 'SELECT COUNT(*) FROM (' . $innerQuery . ') AS innerQuery', + __METHOD__ + ); + $revCount = $revCount->fetchRow(); + $revCount = $revCount['COUNT(*)']; + + $this->mIsBigDeletion = $revCount > $wgDeleteRevisionsLimit; + } + + return $this->mIsBigDeletion; } /** - * Get the approximate revision count of this page. + * Get the approximate revision count of this page. * * @return int */ diff --git a/includes/page/Article.php b/includes/page/Article.php index c54c6928ea..da88a69c1d 100644 --- a/includes/page/Article.php +++ b/includes/page/Article.php @@ -1624,7 +1624,20 @@ class Article implements Page { // If the page has a history, insert a warning if ( $hasHistory ) { - $revisions = $this->mTitle->estimateRevisionCount(); + $title = $this->getTitle(); + + // The following can use the real revision count as this is only being shown for users that can delete + // this page. + // This, as a side-effect, also makes sure that the following query isn't being run for pages with a + // larger history, unless the user has the 'bigdelete' right (and is about to delete this page). + $dbr = wfGetDB( DB_SLAVE ); + $revisions = $edits = (int)$dbr->selectField( + 'revision', + 'COUNT(rev_page)', + array( 'rev_page' => $title->getArticleID() ), + __METHOD__ + ); + // @todo FIXME: i18n issue/patchwork message $this->getContext()->getOutput()->addHTML( '' . wfMessage( 'historywarning' )->numParams( $revisions )->parse() . @@ -1635,7 +1648,7 @@ class Article implements Page { '' ); - if ( $this->mTitle->isBigDeletion() ) { + if ( $title->isBigDeletion() ) { global $wgDeleteRevisionsLimit; $this->getContext()->getOutput()->wrapWikiMsg( "
\n$1\n
\n", array( diff --git a/languages/i18n/en.json b/languages/i18n/en.json index a43a7421a0..6b1ed8c8a6 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -1860,7 +1860,7 @@ "exbeforeblank": "content before blanking was: \"$1\"", "delete-confirm": "Delete \"$1\"", "delete-legend": "Delete", - "historywarning": "Warning: The page you are about to delete has a history with approximately $1 {{PLURAL:$1|revision|revisions}}:", + "historywarning": "Warning: The page you are about to delete has a history with $1 {{PLURAL:$1|revision|revisions}}:", "confirmdeletetext": "You are about to delete a page along with all of its history.\nPlease confirm that you intend to do this, that you understand the consequences, and that you are doing this in accordance with [[{{MediaWiki:Policy-url}}|the policy]].", "actioncomplete": "Action complete", "actionfailed": "Action failed", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index e135277e88..040b7fea76 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -2022,7 +2022,7 @@ "exbeforeblank": "Automated deletion reason when deleting a page for admins providing that the page was blanked before deletion.\n\nParameters:\n* $1 - content before blanking", "delete-confirm": "Used as page title. Parameters:\n* $1 - the page title\n{{Identical|Delete}}", "delete-legend": "{{Identical|Delete}}", - "historywarning": "Warning when about to delete a page that has history.\n\nFollowed by a link which points to the history page.\n\nParameters:\n* $1 - the approximate number of revisions that the page has, the message should not claim to give an exact count", + "historywarning": "Warning when about to delete a page that has history.\n\nFollowed by a link which points to the history page.\n\nParameters:\n* $1 - the number of revisions that the page has", "confirmdeletetext": "Introduction shown when deleting a page.\n\nRefers to {{msg-mw|Policy-url}}.", "actioncomplete": "Used in several situations, for example when a page has been deleted.\n\nSee also:\n* {{msg-mw|Actionfailed|page title}}", "actionfailed": "Used as page title when the submit operation failed, in [[Special:RevisionDelete]].\n\nSee also:\n* {{msg-mw|Actioncomplete|page title}}", -- 2.20.1