Don't estimate the revision count for page deletions
authorMarius Hoch <hoo@online.de>
Sat, 3 May 2014 16:47:25 +0000 (18:47 +0200)
committerMarius Hoch <hoo@online.de>
Sun, 17 Aug 2014 04:30:55 +0000 (06:30 +0200)
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
includes/page/Article.php
languages/i18n/en.json
languages/i18n/qqq.json

index a1b2352..2fba4f7 100644 (file)
@@ -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
         */
index c54c692..da88a69 100644 (file)
@@ -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( '<strong class="mw-delete-warning-revisions">' .
                                wfMessage( 'historywarning' )->numParams( $revisions )->parse() .
@@ -1635,7 +1648,7 @@ class Article implements Page {
                                '</strong>'
                        );
 
-                       if ( $this->mTitle->isBigDeletion() ) {
+                       if ( $title->isBigDeletion() ) {
                                global $wgDeleteRevisionsLimit;
                                $this->getContext()->getOutput()->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
                                        array(
index a43a742..6b1ed8c 100644 (file)
        "exbeforeblank": "content before blanking was: \"$1\"",
        "delete-confirm": "Delete \"$1\"",
        "delete-legend": "Delete",
-       "historywarning": "<strong>Warning:</strong> The page you are about to delete has a history with approximately $1 {{PLURAL:$1|revision|revisions}}:",
+       "historywarning": "<strong>Warning:</strong> 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",
index e135277..040b7fe 100644 (file)
        "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 <b>approximate</b> 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}}",