jenkins-bot has submitted this change and it was merged.
Change subject: Make it slightly easier for extensions to hook into page
protection.
......................................................................
Make it slightly easier for extensions to hook into page protection.
Split parts of doUpdateRestrictions() into several more concise functions.
The biggest drawback is increasing $dbw->encodeExpiry() calls times 3. This is
not much of a problem given that's a very inexpensive function and it is only
called very few times ($limit holds 2 values in current codebase)
Added $reason to the ProtectionForm::save hook, so that other code hooking into
and adding their own settings into page protection form can also process the
reason for the protection change.
Change-Id: I879290ed83e4e47e9561d4c352fbd50c07d7e18a
---
M RELEASE-NOTES-1.22
M docs/hooks.txt
M includes/ProtectionForm.php
M includes/WikiPage.php
4 files changed, 152 insertions(+), 98 deletions(-)
Approvals:
Matthias Mullie: Looks good to me, approved
jenkins-bot: Verified
diff --git a/RELEASE-NOTES-1.22 b/RELEASE-NOTES-1.22
index f5c1e13..43c0c12 100644
--- a/RELEASE-NOTES-1.22
+++ b/RELEASE-NOTES-1.22
@@ -107,6 +107,8 @@
which can be cascading (previously 'sysop' was hard-coded as the only one).
* XHTML5 support has been improved. If you set $wgMimeType =
'application/xhtml+xml'
MediaWiki will try outputting markup acording to XHTML5 rules.
+* Altered hook 'ProtectionForm::save', adding the reason page protection is
+ changed as third parameter.
* New hook 'TitleSquidURLs' for manipulating the list of URLs to be purged from
HTTP caches when a page is changed.
* Changed the patrolling system to always show the link for patrolling in case
the
diff --git a/docs/hooks.txt b/docs/hooks.txt
index 1b44d14..02413b3 100644
--- a/docs/hooks.txt
+++ b/docs/hooks.txt
@@ -1916,9 +1916,10 @@
$output: a string of the form HTML so far
'ProtectionForm::save': Called when a protection form is submitted.
-$article: the title being (un)protected
-$errorMsg: an html message string of an error or an array of message name and
+$article: the Page being (un)protected
+&$errorMsg: an html message string of an error or an array of message name and
its parameters
+$reasonstr: a string describing the reason page protection level is altered
'ProtectionForm::showLogExtract': Called after the protection log extract is
shown.
diff --git a/includes/ProtectionForm.php b/includes/ProtectionForm.php
index 4d41d9e..47c56b0 100644
--- a/includes/ProtectionForm.php
+++ b/includes/ProtectionForm.php
@@ -318,7 +318,7 @@
* you can also return an array of message name and
its parameters
*/
$errorMsg = '';
- if ( !wfRunHooks( 'ProtectionForm::save', array(
$this->mArticle, &$errorMsg ) ) ) {
+ if ( !wfRunHooks( 'ProtectionForm::save', array(
$this->mArticle, &$errorMsg, $reasonstr ) ) ) {
if ( $errorMsg == '' ) {
$errorMsg = array( 'hookaborted' );
}
diff --git a/includes/WikiPage.php b/includes/WikiPage.php
index 9d61abc..be02402 100644
--- a/includes/WikiPage.php
+++ b/includes/WikiPage.php
@@ -2215,14 +2215,14 @@
* This works for protection both existing and non-existing pages.
*
* @param array $limit set of restriction keys
- * @param $reason String
- * @param &$cascade Integer. Set to false if cascading protection isn't
allowed.
* @param array $expiry per restriction type expiration
- * @param $user User The user updating the restrictions
+ * @param int &$cascade Set to false if cascading protection isn't
allowed.
+ * @param string $reason
+ * @param User $user The user updating the restrictions
* @return Status
*/
public function doUpdateRestrictions( array $limit, array $expiry,
&$cascade, $reason, User $user ) {
- global $wgContLang, $wgCascadingRestrictionLevels;
+ global $wgCascadingRestrictionLevels;
if ( wfReadOnly() ) {
return Status::newFatal( 'readonlytext',
wfReadOnlyReason() );
@@ -2295,51 +2295,6 @@
$logAction = 'protect';
}
- $encodedExpiry = array();
- $protectDescription = '';
- # Some bots may parse IRC lines, which are generated from log
entries which contain plain
- # protect description text. Keep them in old format to avoid
breaking compatibility.
- # TODO: Fix protection log to store structured description and
format it on-the-fly.
- $protectDescriptionLog = '';
- foreach ( $limit as $action => $restrictions ) {
- $encodedExpiry[$action] = $dbw->encodeExpiry(
$expiry[$action] );
- if ( $restrictions != '' ) {
- $protectDescriptionLog .=
$wgContLang->getDirMark() . "[$action=$restrictions] (";
- # $action is one of $wgRestrictionTypes =
array( 'create', 'edit', 'move', 'upload' ).
- # All possible message keys are listed here for
easier grepping:
- # * restriction-create
- # * restriction-edit
- # * restriction-move
- # * restriction-upload
- $actionText = wfMessage( 'restriction-' .
$action )->inContentLanguage()->text();
- # $restrictions is one of $wgRestrictionLevels
= array( '', 'autoconfirmed', 'sysop' ),
- # with '' filtered out. All possible message
keys are listed below:
- # * protect-level-autoconfirmed
- # * protect-level-sysop
- $restrictionsText = wfMessage( 'protect-level-'
. $restrictions )->inContentLanguage()->text();
- if ( $encodedExpiry[$action] != 'infinity' ) {
- $expiryText = wfMessage(
- 'protect-expiring',
- $wgContLang->timeanddate(
$expiry[$action], false, false ),
- $wgContLang->date(
$expiry[$action], false, false ),
- $wgContLang->time(
$expiry[$action], false, false )
- )->inContentLanguage()->text();
- } else {
- $expiryText = wfMessage(
'protect-expiry-indefinite' )
- ->inContentLanguage()->text();
- }
-
- if ( $protectDescription !== '' ) {
- $protectDescription .= wfMessage(
'word-separator' )->inContentLanguage()->text();
- }
- $protectDescription .= wfMessage(
'protect-summary-desc' )
- ->params( $actionText,
$restrictionsText, $expiryText )
- ->inContentLanguage()->text();
- $protectDescriptionLog .= $expiryText . ') ';
- }
- }
- $protectDescriptionLog = trim( $protectDescriptionLog );
-
if ( $id ) { // Protection of existing page
if ( !wfRunHooks( 'ArticleProtect', array( &$this,
&$user, $limit, $reason ) ) ) {
return Status::newGood();
@@ -2367,28 +2322,9 @@
$cascade = false;
}
- // Prepare a null revision to be added to the history
- $editComment = $wgContLang->ucfirst(
- wfMessage(
- $revCommentMsg,
- $this->mTitle->getPrefixedText()
- )->inContentLanguage()->text()
- );
- if ( $reason ) {
- $editComment .= wfMessage( 'colon-separator'
)->inContentLanguage()->text() . $reason;
- }
- if ( $protectDescription ) {
- $editComment .= wfMessage( 'word-separator'
)->inContentLanguage()->text();
- $editComment .= wfMessage( 'parentheses'
)->params( $protectDescription )->inContentLanguage()->text();
- }
- if ( $cascade ) {
- $editComment .= wfMessage( 'word-separator'
)->inContentLanguage()->text();
- $editComment .= wfMessage( 'brackets' )->params(
- wfMessage( 'protect-summary-cascade'
)->inContentLanguage()->text()
- )->inContentLanguage()->text();
- }
-
- $nullRevision = Revision::newNullRevision( $dbw, $id,
$editComment, true );
+ // insert null revision to identify the page protection
change as edit summary
+ $latest = $this->getLatest();
+ $nullRevision = $this->insertProtectNullRevision(
$revCommentMsg, $limit, $expiry, $cascade, $reason );
if ( $nullRevision === null ) {
return Status::newFatal( 'no-null-revision',
$this->mTitle->getPrefixedText() );
}
@@ -2401,7 +2337,7 @@
'pr_type' => $action,
'pr_level' =>
$restrictions,
'pr_cascade' => (
$cascade && $action == 'edit' ) ? 1 : 0,
- 'pr_expiry' =>
$encodedExpiry[$action]
+ 'pr_expiry' =>
$dbw->encodeExpiry( $expiry[$action] )
),
__METHOD__
);
@@ -2410,21 +2346,6 @@
'pr_type' => $action ),
__METHOD__ );
}
}
-
- // Insert a null revision
- $nullRevId = $nullRevision->insertOn( $dbw );
-
- $latest = $this->getLatest();
- // Update page record
- $dbw->update( 'page',
- array( /* SET */
- 'page_touched' => $dbw->timestamp(),
- 'page_restrictions' => '',
- 'page_latest' => $nullRevId
- ), array( /* WHERE */
- 'page_id' => $id
- ), __METHOD__
- );
wfRunHooks( 'NewRevisionFromEditComplete', array(
$this, $nullRevision, $latest, $user ) );
wfRunHooks( 'ArticleProtectComplete', array( &$this,
&$user, $limit, $reason ) );
@@ -2440,7 +2361,7 @@
'pt_title' =>
$this->mTitle->getDBkey(),
'pt_create_perm' =>
$limit['create'],
'pt_timestamp' =>
$dbw->encodeExpiry( wfTimestampNow() ),
- 'pt_expiry' =>
$encodedExpiry['create'],
+ 'pt_expiry' =>
$dbw->encodeExpiry( $expiry['create'] ),
'pt_user' => $user->getId(),
'pt_reason' => $reason,
), __METHOD__
@@ -2459,16 +2380,148 @@
InfoAction::invalidateCache( $this->mTitle );
if ( $logAction == 'unprotect' ) {
- $logParams = array();
+ $params = array();
} else {
- $logParams = array( $protectDescriptionLog, $cascade ?
'cascade' : '' );
+ $protectDescriptionLog = $this->protectDescriptionLog(
$limit, $expiry );
+ $params = array( $protectDescriptionLog, $cascade ?
'cascade' : '' );
}
// Update the protection log
$log = new LogPage( 'protect' );
- $log->addEntry( $logAction, $this->mTitle, trim( $reason ),
$logParams, $user );
+ $log->addEntry( $logAction, $this->mTitle, trim( $reason ),
$params, $user );
return Status::newGood();
+ }
+
+ /**
+ * Insert a new null revision for this page.
+ *
+ * @param string $revCommentMsg comment message key for the revision
+ * @param array $limit set of restriction keys
+ * @param array $expiry per restriction type expiration
+ * @param int $cascade Set to false if cascading protection isn't
allowed.
+ * @param string $reason
+ * @return Revision|null on error
+ */
+ public function insertProtectNullRevision( $revCommentMsg, array
$limit, array $expiry, $cascade, $reason ) {
+ global $wgContLang;
+ $dbw = wfGetDB( DB_MASTER );
+
+ // Prepare a null revision to be added to the history
+ $editComment = $wgContLang->ucfirst(
+ wfMessage(
+ $revCommentMsg,
+ $this->mTitle->getPrefixedText()
+ )->inContentLanguage()->text()
+ );
+ if ( $reason ) {
+ $editComment .= wfMessage( 'colon-separator'
)->inContentLanguage()->text() . $reason;
+ }
+ $protectDescription = $this->protectDescription( $limit,
$expiry );
+ if ( $protectDescription ) {
+ $editComment .= wfMessage( 'word-separator'
)->inContentLanguage()->text();
+ $editComment .= wfMessage( 'parentheses' )->params(
$protectDescription )->inContentLanguage()->text();
+ }
+ if ( $cascade ) {
+ $editComment .= wfMessage( 'word-separator'
)->inContentLanguage()->text();
+ $editComment .= wfMessage( 'brackets' )->params(
+ wfMessage( 'protect-summary-cascade'
)->inContentLanguage()->text()
+ )->inContentLanguage()->text();
+ }
+
+ $nullRev = Revision::newNullRevision( $dbw, $this->getId(),
$editComment, true );
+ if ( $nullRev ) {
+ $nullRev->insertOn( $dbw );
+
+ // Update page record and touch page
+ $oldLatest = $nullRev->getParentId();
+ $this->updateRevisionOn( $dbw, $nullRev, $oldLatest );
+ }
+
+ return $nullRev;
+ }
+
+ /**
+ * @param string $expiry 14-char timestamp or "infinity", or false if
the input was invalid
+ * @return string
+ */
+ protected function formatExpiry( $expiry ) {
+ global $wgContLang;
+ $dbr = wfGetDB( DB_SLAVE );
+
+ $encodedExpiry = $dbr->encodeExpiry( $expiry );
+ if ( $encodedExpiry != 'infinity' ) {
+ return wfMessage(
+ 'protect-expiring',
+ $wgContLang->timeanddate( $expiry, false, false
),
+ $wgContLang->date( $expiry, false, false ),
+ $wgContLang->time( $expiry, false, false )
+ )->inContentLanguage()->text();
+ } else {
+ return wfMessage( 'protect-expiry-indefinite' )
+ ->inContentLanguage()->text();
+ }
+ }
+
+ /**
+ * Builds the description to serve as comment for the edit.
+ *
+ * @param array $limit set of restriction keys
+ * @param array $expiry per restriction type expiration
+ * @return string
+ */
+ public function protectDescription( array $limit, array $expiry ) {
+ $protectDescription = '';
+
+ foreach ( array_filter( $limit ) as $action => $restrictions ) {
+ # $action is one of $wgRestrictionTypes = array(
'create', 'edit', 'move', 'upload' ).
+ # All possible message keys are listed here for easier
grepping:
+ # * restriction-create
+ # * restriction-edit
+ # * restriction-move
+ # * restriction-upload
+ $actionText = wfMessage( 'restriction-' . $action
)->inContentLanguage()->text();
+ # $restrictions is one of $wgRestrictionLevels = array(
'', 'autoconfirmed', 'sysop' ),
+ # with '' filtered out. All possible message keys are
listed below:
+ # * protect-level-autoconfirmed
+ # * protect-level-sysop
+ $restrictionsText = wfMessage( 'protect-level-' .
$restrictions )->inContentLanguage()->text();
+
+ $expiryText = $this->formatExpiry( $expiry[$action] );
+
+ if ( $protectDescription !== '' ) {
+ $protectDescription .= wfMessage(
'word-separator' )->inContentLanguage()->text();
+ }
+ $protectDescription .= wfMessage(
'protect-summary-desc' )
+ ->params( $actionText, $restrictionsText,
$expiryText )
+ ->inContentLanguage()->text();
+ }
+
+ return $protectDescription;
+ }
+
+ /**
+ * Builds the description to serve as comment for the log entry.
+ *
+ * Some bots may parse IRC lines, which are generated from log entries
which contain plain
+ * protect description text. Keep them in old format to avoid breaking
compatibility.
+ * TODO: Fix protection log to store structured description and format
it on-the-fly.
+ *
+ * @param array $limit set of restriction keys
+ * @param array $expiry per restriction type expiration
+ * @return string
+ */
+ public function protectDescriptionLog( array $limit, array $expiry ) {
+ global $wgContLang;
+
+ $protectDescriptionLog = '';
+
+ foreach ( array_filter( $limit ) as $action => $restrictions ) {
+ $expiryText = $this->formatExpiry( $expiry[$action] );
+ $protectDescriptionLog .= $wgContLang->getDirMark() .
"[$action=$restrictions] ($expiryText)";
+ }
+
+ return trim( $protectDescriptionLog );
}
/**
@@ -2486,10 +2539,8 @@
$bits = array();
ksort( $limit );
- foreach ( $limit as $action => $restrictions ) {
- if ( $restrictions != '' ) {
- $bits[] = "$action=$restrictions";
- }
+ foreach ( array_filter( $limit ) as $action => $restrictions ) {
+ $bits[] = "$action=$restrictions";
}
return implode( ':', $bits );
--
To view, visit https://gerrit.wikimedia.org/r/81259
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I879290ed83e4e47e9561d4c352fbd50c07d7e18a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: wmf/1.22wmf13
Gerrit-Owner: Matthias Mullie <[email protected]>
Gerrit-Reviewer: Matthias Mullie <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits