* 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)
This commit is contained in:
Alexandre Emsenhuber 2011-12-27 15:29:44 +00:00
parent f0faee8ae9
commit 4f68ae8939
5 changed files with 64 additions and 39 deletions

View file

@ -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( "<div class='error'>\n$1\n</div>\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( '<strong class="mw-delete-warning-revisions">' .
wfMsgExt( 'historywarning', array( 'parseinline' ), $wgLang->formatNum( $revisions ) ) .

View file

@ -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.

View file

@ -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();
}
/**

View file

@ -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 ) ) {

View file

@ -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;