summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Wight <awight@wikimedia.org>2012-09-11 20:43:37 -0400
committerAdam Wight <awight@wikimedia.org>2012-09-14 18:01:09 -0700
commit3b42ef29b30c7eb4662c1c47913d67d48ff02815 (patch)
tree10c66623f985bcd90ae51d11ae6ce210d27a1fcd
parentf25ee7006ff73f1cdf22cdd11401af31ef691b12 (diff)
Remove page and title protection from core.origin/sandbox/adamw/no_protection_in_core
The code has been moved into an extension, "Protection", which is supposed to have identical functionality. Several hooks have been added to core: * APIGetPossibleErrors * APIQueryAllpages::RunAlter * CheckActionPermissions * EditPage::showRestrictions * EditPage::showTextboxAlter * UpdateRestrictions (XXX not implemented) The extension code can be downloaded from https://github.com/adamwight/wmf-ext-protection Change-Id: I89a1c1778adf6c1c2ad419fd10d36a4d98e24c65
-rw-r--r--includes/Article.php38
-rw-r--r--includes/AutoLoader.php8
-rw-r--r--includes/DefaultSettings.php32
-rw-r--r--includes/EditPage.php77
-rw-r--r--includes/FakeTitle.php13
-rw-r--r--includes/Linker.php11
-rw-r--r--includes/OutputPage.php3
-rw-r--r--includes/ProtectionForm.php614
-rw-r--r--includes/SkinLegacy.php28
-rw-r--r--includes/SkinTemplate.php10
-rw-r--r--includes/SpecialPageFactory.php2
-rw-r--r--includes/Title.php655
-rw-r--r--includes/WikiPage.php314
-rw-r--r--includes/actions/ProtectAction.php56
-rw-r--r--includes/api/ApiBase.php15
-rw-r--r--includes/api/ApiMain.php1
-rw-r--r--includes/api/ApiParamInfo.php2
-rw-r--r--includes/api/ApiProtect.php225
-rw-r--r--includes/api/ApiQuery.php1
-rw-r--r--includes/api/ApiQueryAllpages.php78
-rw-r--r--includes/api/ApiQueryBase.php8
-rw-r--r--includes/api/ApiQueryProtectedTitles.php234
-rw-r--r--includes/logging/LogEventsList.php20
-rw-r--r--includes/parser/CoreParserFunctions.php10
-rw-r--r--includes/specials/SpecialMovepage.php16
-rw-r--r--includes/specials/SpecialProtectedpages.php358
-rw-r--r--includes/specials/SpecialProtectedtitles.php243
-rw-r--r--languages/messages/MessagesEn.php122
-rw-r--r--maintenance/ibm_db2/foreignkeys.sql6
-rw-r--r--maintenance/ibm_db2/tables.sql15
-rw-r--r--maintenance/importImages.php51
-rw-r--r--maintenance/language/messages.inc103
-rw-r--r--maintenance/mssql/tables.sql14
-rw-r--r--maintenance/oracle/tables.sql11
-rw-r--r--maintenance/postgres/tables.sql11
-rw-r--r--maintenance/protect.php84
-rw-r--r--maintenance/tables.sql15
-rw-r--r--maintenance/updateRestrictions.php111
-rw-r--r--resources/Resources.php10
-rw-r--r--skins/CologneBlue.php6
-rw-r--r--skins/Standard.php3
-rw-r--r--skins/common/protect.js357
-rw-r--r--skins/common/shared.css4
43 files changed, 48 insertions, 3947 deletions
diff --git a/includes/Article.php b/includes/Article.php
index b07f309c88aa..549fa48dcd79 100644
--- a/includes/Article.php
+++ b/includes/Article.php
@@ -1253,21 +1253,6 @@ class Article extends Page {
}
/**
- * action=protect handler
- */
- public function protect() {
- $form = new ProtectionForm( $this );
- $form->execute();
- }
-
- /**
- * action=unprotect handler (alias)
- */
- public function unprotect() {
- $this->protect();
- }
-
- /**
* UI entry point for page deletion
*/
public function delete() {
@@ -1788,29 +1773,6 @@ class Article extends Page {
// ****** B/C functions to work-around PHP silliness with __call and references ****** //
/**
- * @param $limit array
- * @param $expiry array
- * @param $cascade bool
- * @param $reason string
- * @param $user User
- * @return Status
- */
- public function doUpdateRestrictions( array $limit, array $expiry, &$cascade, $reason, User $user ) {
- return $this->mPage->doUpdateRestrictions( $limit, $expiry, $cascade, $reason, $user );
- }
-
- /**
- * @param $limit array
- * @param $reason string
- * @param $cascade int
- * @param $expiry array
- * @return bool
- */
- public function updateRestrictions( $limit = array(), $reason = '', &$cascade = 0, $expiry = array() ) {
- return $this->mPage->updateRestrictions( $limit, $reason, $cascade, $expiry );
- }
-
- /**
* @param $reason string
* @param $suppress bool
* @param $id int
diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php
index 93fac45f9300..9248fe73729a 100644
--- a/includes/AutoLoader.php
+++ b/includes/AutoLoader.php
@@ -173,7 +173,6 @@ $wgAutoloadLocalClasses = array(
'Preferences' => 'includes/Preferences.php',
'PreferencesForm' => 'includes/Preferences.php',
'PrefixSearch' => 'includes/PrefixSearch.php',
- 'ProtectionForm' => 'includes/ProtectionForm.php',
'QueryPage' => 'includes/QueryPage.php',
'QuickTemplate' => 'includes/SkinTemplate.php',
'RCCacheEntry' => 'includes/ChangesList.php',
@@ -263,7 +262,6 @@ $wgAutoloadLocalClasses = array(
'HistoryPager' => 'includes/actions/HistoryAction.php',
'InfoAction' => 'includes/actions/InfoAction.php',
'MarkpatrolledAction' => 'includes/actions/MarkpatrolledAction.php',
- 'ProtectAction' => 'includes/actions/ProtectAction.php',
'PurgeAction' => 'includes/actions/PurgeAction.php',
'RawAction' => 'includes/actions/RawAction.php',
'RawPage' => 'includes/actions/RawAction.php',
@@ -273,7 +271,6 @@ $wgAutoloadLocalClasses = array(
'RevisiondeleteAction' => 'includes/actions/RevisiondeleteAction.php',
'RollbackAction' => 'includes/actions/RollbackAction.php',
'SubmitAction' => 'includes/actions/EditAction.php',
- 'UnprotectAction' => 'includes/actions/ProtectAction.php',
'UnwatchAction' => 'includes/actions/WatchAction.php',
'ViewAction' => 'includes/actions/ViewAction.php',
'WatchAction' => 'includes/actions/WatchAction.php',
@@ -314,7 +311,6 @@ $wgAutoloadLocalClasses = array(
'ApiParamInfo' => 'includes/api/ApiParamInfo.php',
'ApiParse' => 'includes/api/ApiParse.php',
'ApiPatrol' => 'includes/api/ApiPatrol.php',
- 'ApiProtect' => 'includes/api/ApiProtect.php',
'ApiPurge' => 'includes/api/ApiPurge.php',
'ApiQuery' => 'includes/api/ApiQuery.php',
'ApiQueryAllCategories' => 'includes/api/ApiQueryAllCategories.php',
@@ -347,7 +343,6 @@ $wgAutoloadLocalClasses = array(
'ApiQueryLinks' => 'includes/api/ApiQueryLinks.php',
'ApiQueryLogEvents' => 'includes/api/ApiQueryLogEvents.php',
'ApiQueryPageProps' => 'includes/api/ApiQueryPageProps.php',
- 'ApiQueryProtectedTitles' => 'includes/api/ApiQueryProtectedTitles.php',
'ApiQueryQueryPage' => 'includes/api/ApiQueryQueryPage.php',
'ApiQueryRandom' => 'includes/api/ApiQueryRandom.php',
'ApiQueryRecentChanges' => 'includes/api/ApiQueryRecentChanges.php',
@@ -838,8 +833,6 @@ $wgAutoloadLocalClasses = array(
'SpecialPermanentLink' => 'includes/SpecialPage.php',
'SpecialPreferences' => 'includes/specials/SpecialPreferences.php',
'SpecialPrefixindex' => 'includes/specials/SpecialPrefixindex.php',
- 'SpecialProtectedpages' => 'includes/specials/SpecialProtectedpages.php',
- 'SpecialProtectedtitles' => 'includes/specials/SpecialProtectedtitles.php',
'SpecialRandomredirect' => 'includes/specials/SpecialRandomredirect.php',
'SpecialRecentChanges' => 'includes/specials/SpecialRecentchanges.php',
'SpecialRecentchangeslinked' => 'includes/specials/SpecialRecentchangeslinked.php',
@@ -923,7 +916,6 @@ $wgAutoloadLocalClasses = array(
'SevenZipStream' => 'maintenance/7zip.inc',
'Sqlite' => 'maintenance/sqlite.inc',
'UpdateCollation' => 'maintenance/updateCollation.php',
- 'UpdateRestrictions' => 'maintenance/updateRestrictions.php',
'UserDupes' => 'maintenance/userDupes.inc',
# maintenance/language
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index acd89bde55e2..09b87acb1d2e 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -3615,27 +3615,6 @@ $wgGroupsAddToSelf = array();
$wgGroupsRemoveFromSelf = array();
/**
- * Set of available actions that can be restricted via action=protect
- * You probably shouldn't change this.
- * Translated through restriction-* messages.
- * Title::getRestrictionTypes() will remove restrictions that are not
- * applicable to a specific title (create and upload)
- */
-$wgRestrictionTypes = array( 'create', 'edit', 'move', 'upload' );
-
-/**
- * Rights which can be required for each protection level (via action=protect)
- *
- * You can add a new protection level that requires a specific
- * permission by manipulating this array. The ordering of elements
- * dictates the order on the protection form's lists.
- *
- * - '' will be ignored (i.e. unprotected)
- * - 'sysop' is quietly rewritten to 'protect' for backwards compatibility
- */
-$wgRestrictionLevels = array( '', 'autoconfirmed', 'sysop' );
-
-/**
* Set the minimum permissions required to edit pages in each
* namespace. If you list more than one permission, a user must
* have all of them to edit pages in that namespace.
@@ -5039,7 +5018,6 @@ $wgCategoryCollation = 'uppercase';
$wgLogTypes = array(
'',
'block',
- 'protect',
'rights',
'delete',
'upload',
@@ -5097,7 +5075,6 @@ $wgFilterLogTypes = array(
$wgLogNames = array(
'' => 'all-logs-page',
'block' => 'blocklogpage',
- 'protect' => 'protectlogpage',
'rights' => 'rightslog',
'delete' => 'dellogpage',
'upload' => 'uploadlogpage',
@@ -5120,7 +5097,6 @@ $wgLogNames = array(
$wgLogHeaders = array(
'' => 'alllogstext',
'block' => 'blocklogtext',
- 'protect' => 'protectlogtext',
'rights' => 'rightslogtext',
'delete' => 'dellogpagetext',
'upload' => 'uploadlogpagetext',
@@ -5141,10 +5117,6 @@ $wgLogActions = array(
'block/block' => 'blocklogentry',
'block/unblock' => 'unblocklogentry',
'block/reblock' => 'reblock-logentry',
- 'protect/protect' => 'protectedarticle',
- 'protect/modify' => 'modifiedarticleprotection',
- 'protect/unprotect' => 'unprotectedarticle',
- 'protect/move_prot' => 'movedarticleprotection',
'rights/rights' => 'rightslogentry',
'rights/autopromote' => 'rightslogentry-autopromote',
'upload/upload' => 'uploadedimage',
@@ -5211,8 +5183,6 @@ $wgSpecialPageGroups = array(
'Uncategorizedtemplates' => 'maintenance',
'Unusedcategories' => 'maintenance',
'Unusedimages' => 'maintenance',
- 'Protectedpages' => 'maintenance',
- 'Protectedtitles' => 'maintenance',
'Unusedtemplates' => 'maintenance',
'Withoutinterwiki' => 'maintenance',
'Longpages' => 'maintenance',
@@ -5344,7 +5314,6 @@ $wgActions = array(
'history' => true,
'info' => true,
'markpatrolled' => true,
- 'protect' => true,
'purge' => true,
'raw' => true,
'render' => true,
@@ -5352,7 +5321,6 @@ $wgActions = array(
'revisiondelete' => true,
'rollback' => true,
'submit' => true,
- 'unprotect' => true,
'unwatch' => true,
'view' => true,
'watch' => true,
diff --git a/includes/EditPage.php b/includes/EditPage.php
index d00d9114945d..ab00a69dfa80 100644
--- a/includes/EditPage.php
+++ b/includes/EditPage.php
@@ -462,26 +462,6 @@ class EditPage {
}
/**
- * Show a read-only error
- * Parameters are the same as OutputPage:readOnlyPage()
- * Redirect to the article page if redlink=1
- * @deprecated in 1.19; use displayPermissionsError() instead
- */
- function readOnlyPage( $source = null, $protected = false, $reasons = array(), $action = null ) {
- wfDeprecated( __METHOD__, '1.19' );
-
- global $wgRequest, $wgOut;
- if ( $wgRequest->getBool( 'redlink' ) ) {
- // The edit page was reached via a red link.
- // Redirect to the article page and let them click the edit tab if
- // they really want a permission error.
- $wgOut->redirect( $this->mTitle->getFullUrl() );
- } else {
- $wgOut->readOnlyPage( $source, $protected, $reasons, $action );
- }
- }
-
- /**
* Should we show a preview when the edit form is first shown?
*
* @return bool
@@ -1997,38 +1977,7 @@ class EditPage {
}
}
- if ( $this->mTitle->getNamespace() != NS_MEDIAWIKI && $this->mTitle->isProtected( 'edit' ) ) {
- # Is the title semi-protected?
- if ( $this->mTitle->isSemiProtected() ) {
- $noticeMsg = 'semiprotectedpagewarning';
- } else {
- # Then it must be protected based on static groups (regular)
- $noticeMsg = 'protectedpagewarning';
- }
- LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
- array( 'lim' => 1, 'msgKey' => array( $noticeMsg ) ) );
- }
- if ( $this->mTitle->isCascadeProtected() ) {
- # Is this page under cascading protection from some source pages?
- list($cascadeSources, /* $restrictions */) = $this->mTitle->getCascadeProtectionSources();
- $notice = "<div class='mw-cascadeprotectedwarning'>\n$1\n";
- $cascadeSourcesCount = count( $cascadeSources );
- if ( $cascadeSourcesCount > 0 ) {
- # Explain, and list the titles responsible
- foreach( $cascadeSources as $page ) {
- $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
- }
- }
- $notice .= '</div>';
- $wgOut->wrapWikiMsg( $notice, array( 'cascadeprotectedwarning', $cascadeSourcesCount ) );
- }
- if ( !$this->mTitle->exists() && $this->mTitle->getRestrictions( 'create' ) ) {
- LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
- array( 'lim' => 1,
- 'showIfEmpty' => false,
- 'msgKey' => array( 'titleprotectedwarning' ),
- 'wrap' => "<div class=\"mw-titleprotectedwarning\">\n$1</div>" ) );
- }
+ wfRunHooks( 'EditPage::showRestrictions', array( $this ) );
if ( $this->kblength === false ) {
$this->kblength = (int)( strlen( $this->textbox1 ) / 1024 );
@@ -2190,35 +2139,15 @@ HTML
if ( $this->wasDeletedSinceLastEdit() && $this->formtype == 'save' ) {
$attribs = array( 'style' => 'display:none;' );
} else {
- $classes = array(); // Textarea CSS
- if ( $this->mTitle->getNamespace() != NS_MEDIAWIKI && $this->mTitle->isProtected( 'edit' ) ) {
- # Is the title semi-protected?
- if ( $this->mTitle->isSemiProtected() ) {
- $classes[] = 'mw-textarea-sprotected';
- } else {
- # Then it must be protected based on static groups (regular)
- $classes[] = 'mw-textarea-protected';
- }
- # Is the title cascade-protected?
- if ( $this->mTitle->isCascadeProtected() ) {
- $classes[] = 'mw-textarea-cprotected';
- }
- }
-
$attribs = array( 'tabindex' => 1 );
if ( is_array( $customAttribs ) ) {
$attribs += $customAttribs;
}
-
- if ( count( $classes ) ) {
- if ( isset( $attribs['class'] ) ) {
- $classes[] = $attribs['class'];
- }
- $attribs['class'] = implode( ' ', $classes );
- }
}
+ wfRunHooks( 'EditPage::showTextboxAlter', array( $this, &$attribs ) );
+
$this->showTextbox( $textoverride !== null ? $textoverride : $this->textbox1, 'wpTextbox1', $attribs );
}
diff --git a/includes/FakeTitle.php b/includes/FakeTitle.php
index 8415ec08bdfe..75357a2148d3 100644
--- a/includes/FakeTitle.php
+++ b/includes/FakeTitle.php
@@ -38,16 +38,11 @@ class FakeTitle extends Title {
function getEditURL() { $this->error(); }
function getEscapedText() { $this->error(); }
function isExternal() { $this->error(); }
- function isSemiProtected( $action = 'edit' ) { $this->error(); }
- function isProtected( $action = '' ) { $this->error(); }
function isConversionTable() { $this->error(); }
function userIsWatching() { $this->error(); }
function quickUserCan( $action, $user = null ) { $this->error(); }
- function isNamespaceProtected( User $user ) { $this->error(); }
function userCan( $action, $user = null, $doExpensiveQueries = true ) { $this->error(); }
function getUserPermissionsErrors( $action, $user, $doExpensiveQueries = true, $ignoreErrors = array() ) { $this->error(); }
- function updateTitleProtection( $create_perm, $reason, $expiry ) { $this->error(); }
- function deleteTitleProtection() { $this->error(); }
function isMovable() { $this->error(); }
function userCanRead() { $this->error(); }
function isTalkPage() { $this->error(); }
@@ -62,13 +57,6 @@ class FakeTitle extends Title {
function userCanEditCssJsSubpage() { $this->error(); }
function userCanEditCssSubpage() { $this->error(); }
function userCanEditJsSubpage() { $this->error(); }
- function isCascadeProtected() { $this->error(); }
- function getCascadeProtectionSources( $get_pages = true ) { $this->error(); }
- function areRestrictionsCascading() { $this->error(); }
- function loadRestrictionsFromRows( $rows, $oldFashionedRestrictions = null ) { $this->error(); }
- function loadRestrictions( $res = null ) { $this->error(); }
- function getRestrictions( $action ) { $this->error(); }
- function getRestrictionExpiry( $action ) { $this->error(); }
function isDeleted() { $this->error(); }
function isDeletedQuick() { $this->error(); }
function getArticleID( $flags = 0 ) { $this->error(); }
@@ -120,5 +108,4 @@ class FakeTitle extends Title {
function isValidRedirectTarget() { $this->error(); }
function getBacklinkCache() { $this->error(); }
function canUseNoindex() { $this->error(); }
- function getRestrictionTypes() { $this->error(); }
}
diff --git a/includes/Linker.php b/includes/Linker.php
index 0b813ac095b7..3fecc8d65902 100644
--- a/includes/Linker.php
+++ b/includes/Linker.php
@@ -1646,14 +1646,6 @@ class Linker {
usort( $templates, array( 'Title', 'compare' ) );
foreach ( $templates as $titleObj ) {
- $r = $titleObj->getRestrictions( 'edit' );
- if ( in_array( 'sysop', $r ) ) {
- $protected = wfMsgExt( 'template-protected', array( 'parseinline' ) );
- } elseif ( in_array( 'autoconfirmed', $r ) ) {
- $protected = wfMsgExt( 'template-semiprotected', array( 'parseinline' ) );
- } else {
- $protected = '';
- }
if ( $titleObj->quickUserCan( 'edit' ) ) {
$editLink = self::link(
$titleObj,
@@ -1669,7 +1661,8 @@ class Linker {
array( 'action' => 'edit' )
);
}
- $outText .= '<li>' . self::link( $titleObj ) . ' (' . $editLink . ') ' . $protected . '</li>';
+ //TODO show restrictions
+ $outText .= '<li>' . self::link( $titleObj ) . ' (' . $editLink . ')</li>';
}
$outText .= '</ul>';
}
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
index a91d54657a64..4873332379aa 100644
--- a/includes/OutputPage.php
+++ b/includes/OutputPage.php
@@ -2890,9 +2890,6 @@ $templates
if ( $lang->hasVariants() ) {
$vars['wgUserVariant'] = $lang->getPreferredVariant();
}
- foreach ( $title->getRestrictionTypes() as $type ) {
- $vars['wgRestriction' . ucfirst( $type )] = $title->getRestrictions( $type );
- }
if ( $wgUseAjax && $wgEnableMWSuggest && !$this->getUser()->getOption( 'disablesuggest', false ) ) {
$vars['wgSearchNamespaces'] = SearchEngine::userNamespaces( $this->getUser() );
}
diff --git a/includes/ProtectionForm.php b/includes/ProtectionForm.php
deleted file mode 100644
index dbe06d49c6c2..000000000000
--- a/includes/ProtectionForm.php
+++ /dev/null
@@ -1,614 +0,0 @@
-<?php
-/**
- * Page protection
- *
- * Copyright © 2005 Brion Vibber <brion@pobox.com>
- * http://www.mediawiki.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Handles the page protection UI and backend
- */
-class ProtectionForm {
- /** A map of action to restriction level, from request or default */
- var $mRestrictions = array();
-
- /** The custom/additional protection reason */
- var $mReason = '';
-
- /** The reason selected from the list, blank for other/additional */
- var $mReasonSelection = '';
-
- /** True if the restrictions are cascading, from request or existing protection */
- var $mCascade = false;
-
- /** Map of action to "other" expiry time. Used in preference to mExpirySelection. */
- var $mExpiry = array();
-
- /**
- * Map of action to value selected in expiry drop-down list.
- * Will be set to 'othertime' whenever mExpiry is set.
- */
- var $mExpirySelection = array();
-
- /** Permissions errors for the protect action */
- var $mPermErrors = array();
-
- /** Types (i.e. actions) for which levels can be selected */
- var $mApplicableTypes = array();
-
- /** Map of action to the expiry time of the existing protection */
- var $mExistingExpiry = array();
-
- function __construct( Page $article ) {
- global $wgUser;
- // Set instance variables.
- $this->mArticle = $article;
- $this->mTitle = $article->getTitle();
- $this->mApplicableTypes = $this->mTitle->getRestrictionTypes();
-
- // Check if the form should be disabled.
- // If it is, the form will be available in read-only to show levels.
- $this->mPermErrors = $this->mTitle->getUserPermissionsErrors( 'protect', $wgUser );
- if ( wfReadOnly() ) {
- $this->mPermErrors[] = array( 'readonlytext', wfReadOnlyReason() );
- }
- $this->disabled = $this->mPermErrors != array();
- $this->disabledAttrib = $this->disabled
- ? array( 'disabled' => 'disabled' )
- : array();
-
- $this->loadData();
- }
-
- /**
- * Loads the current state of protection into the object.
- */
- function loadData() {
- global $wgRequest, $wgUser;
- global $wgRestrictionLevels;
-
- $this->mCascade = $this->mTitle->areRestrictionsCascading();
-
- $this->mReason = $wgRequest->getText( 'mwProtect-reason' );
- $this->mReasonSelection = $wgRequest->getText( 'wpProtectReasonSelection' );
- $this->mCascade = $wgRequest->getBool( 'mwProtect-cascade', $this->mCascade );
-
- foreach( $this->mApplicableTypes as $action ) {
- // @todo FIXME: This form currently requires individual selections,
- // but the db allows multiples separated by commas.
-
- // Pull the actual restriction from the DB
- $this->mRestrictions[$action] = implode( '', $this->mTitle->getRestrictions( $action ) );
-
- if ( !$this->mRestrictions[$action] ) {
- // No existing expiry
- $existingExpiry = '';
- } else {
- $existingExpiry = $this->mTitle->getRestrictionExpiry( $action );
- }
- $this->mExistingExpiry[$action] = $existingExpiry;
-
- $requestExpiry = $wgRequest->getText( "mwProtect-expiry-$action" );
- $requestExpirySelection = $wgRequest->getVal( "wpProtectExpirySelection-$action" );
-
- if ( $requestExpiry ) {
- // Custom expiry takes precedence
- $this->mExpiry[$action] = $requestExpiry;
- $this->mExpirySelection[$action] = 'othertime';
- } elseif ( $requestExpirySelection ) {
- // Expiry selected from list
- $this->mExpiry[$action] = '';
- $this->mExpirySelection[$action] = $requestExpirySelection;
- } elseif ( $existingExpiry == 'infinity' ) {
- // Existing expiry is infinite, use "infinite" in drop-down
- $this->mExpiry[$action] = '';
- $this->mExpirySelection[$action] = 'infinite';
- } elseif ( $existingExpiry ) {
- // Use existing expiry in its own list item
- $this->mExpiry[$action] = '';
- $this->mExpirySelection[$action] = $existingExpiry;
- } else {
- // Final default: infinite
- $this->mExpiry[$action] = '';
- $this->mExpirySelection[$action] = 'infinite';
- }
-
- $val = $wgRequest->getVal( "mwProtect-level-$action" );
- if( isset( $val ) && in_array( $val, $wgRestrictionLevels ) ) {
- // Prevent users from setting levels that they cannot later unset
- if( $val == 'sysop' ) {
- // Special case, rewrite sysop to either protect and editprotected
- if( !$wgUser->isAllowedAny( 'protect', 'editprotected' ) )
- continue;
- } else {
- if( !$wgUser->isAllowed($val) )
- continue;
- }
- $this->mRestrictions[$action] = $val;
- }
- }
- }
-
- /**
- * Get the expiry time for a given action, by combining the relevant inputs.
- *
- * @param $action string
- *
- * @return string 14-char timestamp or "infinity", or false if the input was invalid
- */
- function getExpiry( $action ) {
- if ( $this->mExpirySelection[$action] == 'existing' ) {
- return $this->mExistingExpiry[$action];
- } elseif ( $this->mExpirySelection[$action] == 'othertime' ) {
- $value = $this->mExpiry[$action];
- } else {
- $value = $this->mExpirySelection[$action];
- }
- if ( $value == 'infinite' || $value == 'indefinite' || $value == 'infinity' ) {
- $time = wfGetDB( DB_SLAVE )->getInfinity();
- } else {
- $unix = strtotime( $value );
-
- if ( !$unix || $unix === -1 ) {
- return false;
- }
-
- // @todo FIXME: Non-qualified absolute times are not in users specified timezone
- // and there isn't notice about it in the ui
- $time = wfTimestamp( TS_MW, $unix );
- }
- return $time;
- }
-
- /**
- * Main entry point for action=protect and action=unprotect
- */
- function execute() {
- global $wgRequest, $wgOut;
-
- if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
- throw new ErrorPageError( 'protect-badnamespace-title', 'protect-badnamespace-text' );
- }
-
- if( $wgRequest->wasPosted() ) {
- if( $this->save() ) {
- $q = $this->mArticle->isRedirect() ? 'redirect=no' : '';
- $wgOut->redirect( $this->mTitle->getFullUrl( $q ) );
- }
- } else {
- $this->show();
- }
- }
-
- /**
- * Show the input form with optional error message
- *
- * @param $err String: error message or null if there's no error
- */
- function show( $err = null ) {
- global $wgOut;
-
- $wgOut->setRobotPolicy( 'noindex,nofollow' );
-
- if ( is_array( $err ) ) {
- $wgOut->wrapWikiMsg( "<p class='error'>\n$1\n</p>\n", $err );
- } elseif ( is_string( $err ) ) {
- $wgOut->addHTML( "<p class='error'>{$err}</p>\n" );
- }
-
- list( $cascadeSources, /* $restrictions */ ) = $this->mTitle->getCascadeProtectionSources();
- if ( $cascadeSources && count($cascadeSources) > 0 ) {
- $titles = '';
-
- foreach ( $cascadeSources as $title ) {
- $titles .= '* [[:' . $title->getPrefixedText() . "]]\n";
- }
-
- $wgOut->wrapWikiMsg( "<div id=\"mw-protect-cascadeon\">\n$1\n" . $titles . "</div>", array( 'protect-cascadeon', count($cascadeSources) ) );
- }
-
- # Show an appropriate message if the user isn't allowed or able to change
- # the protection settings at this time
- if ( $this->disabled ) {
- $wgOut->setPageTitle( wfMessage( 'protect-title-notallowed', $this->mTitle->getPrefixedText() ) );
- $wgOut->addWikiText( $wgOut->formatPermissionsErrorMessage( $this->mPermErrors, 'protect' ) );
- } else {
- $wgOut->setPageTitle( wfMessage( 'protect-title', $this->mTitle->getPrefixedText() ) );
- $wgOut->addWikiMsg( 'protect-text',
- wfEscapeWikiText( $this->mTitle->getPrefixedText() ) );
- }
-
- $wgOut->addBacklinkSubtitle( $this->mTitle );
- $wgOut->addHTML( $this->buildForm() );
- $this->showLogExtract( $wgOut );
- }
-
- /**
- * Save submitted protection form
- *
- * @return Boolean: success
- */
- function save() {
- global $wgRequest, $wgUser, $wgOut;
-
- # Permission check!
- if ( $this->disabled ) {
- $this->show();
- return false;
- }
-
- $token = $wgRequest->getVal( 'wpEditToken' );
- if ( !$wgUser->matchEditToken( $token, array( 'protect', $this->mTitle->getPrefixedDBkey() ) ) ) {
- $this->show( array( 'sessionfailure' ) );
- return false;
- }
-
- # Create reason string. Use list and/or custom string.
- $reasonstr = $this->mReasonSelection;
- if ( $reasonstr != 'other' && $this->mReason != '' ) {
- // Entry from drop down menu + additional comment
- $reasonstr .= wfMsgForContent( 'colon-separator' ) . $this->mReason;
- } elseif ( $reasonstr == 'other' ) {
- $reasonstr = $this->mReason;
- }
- $expiry = array();
- foreach( $this->mApplicableTypes as $action ) {
- $expiry[$action] = $this->getExpiry( $action );
- if( empty($this->mRestrictions[$action]) )
- continue; // unprotected
- if ( !$expiry[$action] ) {
- $this->show( array( 'protect_expiry_invalid' ) );
- return false;
- }
- if ( $expiry[$action] < wfTimestampNow() ) {
- $this->show( array( 'protect_expiry_old' ) );
- return false;
- }
- }
-
- # They shouldn't be able to do this anyway, but just to make sure, ensure that cascading restrictions aren't being applied
- # to a semi-protected page.
- global $wgGroupPermissions;
-
- $edit_restriction = isset( $this->mRestrictions['edit'] ) ? $this->mRestrictions['edit'] : '';
- $this->mCascade = $wgRequest->getBool( 'mwProtect-cascade' );
- if ($this->mCascade && ($edit_restriction != 'protect') &&
- !(isset($wgGroupPermissions[$edit_restriction]['protect']) && $wgGroupPermissions[$edit_restriction]['protect'] ) )
- $this->mCascade = false;
-
- $status = $this->mArticle->doUpdateRestrictions( $this->mRestrictions, $expiry, $this->mCascade, $reasonstr, $wgUser );
-
- if ( !$status->isOK() ) {
- $this->show( $wgOut->parseInline( $status->getWikiText() ) );
- return false;
- }
-
- /**
- * Give extensions a change to handle added form items
- *
- * @since 1.19 you can (and you should) return false to abort saving;
- * you can also return an array of message name and its parameters
- */
- $errorMsg = '';
- if( !wfRunHooks( 'ProtectionForm::save', array( $this->mArticle, &$errorMsg ) ) ) {
- if ( $errorMsg == '' ) {
- $errorMsg = array( 'hookaborted' );
- }
- }
- if( $errorMsg != '' ) {
- $this->show( $errorMsg );
- return false;
- }
-
- if ( $wgRequest->getCheck( 'mwProtectWatch' ) && $wgUser->isLoggedIn() ) {
- WatchAction::doWatch( $this->mTitle, $wgUser );
- } elseif ( $this->mTitle->userIsWatching() ) {
- WatchAction::doUnwatch( $this->mTitle, $wgUser );
- }
- return true;
- }
-
- /**
- * Build the input form
- *
- * @return String: HTML form
- */
- function buildForm() {
- global $wgUser, $wgLang, $wgOut;
-
- $mProtectreasonother = Xml::label( wfMsg( 'protectcomment' ), 'wpProtectReasonSelection' );
- $mProtectreason = Xml::label( wfMsg( 'protect-otherreason' ), 'mwProtect-reason' );
-
- $out = '';
- if( !$this->disabled ) {
- $wgOut->addModules( 'mediawiki.legacy.protect' );
- $out .= Xml::openElement( 'form', array( 'method' => 'post',
- 'action' => $this->mTitle->getLocalUrl( 'action=protect' ),
- 'id' => 'mw-Protect-Form', 'onsubmit' => 'ProtectionForm.enableUnchainedInputs(true)' ) );
- }
-
- $out .= Xml::openElement( 'fieldset' ) .
- Xml::element( 'legend', null, wfMsg( 'protect-legend' ) ) .
- Xml::openElement( 'table', array( 'id' => 'mwProtectSet' ) ) .
- Xml::openElement( 'tbody' );
-
- foreach( $this->mRestrictions as $action => $selected ) {
- /* Not all languages have V_x <-> N_x relation */
- $msg = wfMessage( 'restriction-' . $action );
- $out .= "<tr><td>".
- Xml::openElement( 'fieldset' ) .
- Xml::element( 'legend', null, $msg->exists() ? $msg->text() : $action ) .
- Xml::openElement( 'table', array( 'id' => "mw-protect-table-$action" ) ) .
- "<tr><td>" . $this->buildSelector( $action, $selected ) . "</td></tr><tr><td>";
-
- $reasonDropDown = Xml::listDropDown( 'wpProtectReasonSelection',
- wfMsgForContent( 'protect-dropdown' ),
- wfMsgForContent( 'protect-otherreason-op' ),
- $this->mReasonSelection,
- 'mwProtect-reason', 4 );
- $scExpiryOptions = wfMsgForContent( 'protect-expiry-options' );
-
- $showProtectOptions = ($scExpiryOptions !== '-' && !$this->disabled);
-
- $mProtectexpiry = Xml::label( wfMsg( 'protectexpiry' ), "mwProtectExpirySelection-$action" );
- $mProtectother = Xml::label( wfMsg( 'protect-othertime' ), "mwProtect-$action-expires" );
-
- $expiryFormOptions = '';
- if ( $this->mExistingExpiry[$action] && $this->mExistingExpiry[$action] != 'infinity' ) {
- $timestamp = $wgLang->timeanddate( $this->mExistingExpiry[$action], true );
- $d = $wgLang->date( $this->mExistingExpiry[$action], true );
- $t = $wgLang->time( $this->mExistingExpiry[$action], true );
- $expiryFormOptions .=
- Xml::option(
- wfMsg( 'protect-existing-expiry', $timestamp, $d, $t ),
- 'existing',
- $this->mExpirySelection[$action] == 'existing'
- ) . "\n";
- }
-
- $expiryFormOptions .= Xml::option( wfMsg( 'protect-othertime-op' ), "othertime" ) . "\n";
- foreach( explode(',', $scExpiryOptions) as $option ) {
- if ( strpos($option, ":") === false ) {
- $show = $value = $option;
- } else {
- list($show, $value) = explode(":", $option);
- }
- $show = htmlspecialchars($show);
- $value = htmlspecialchars($value);
- $expiryFormOptions .= Xml::option( $show, $value, $this->mExpirySelection[$action] === $value ) . "\n";
- }
- # Add expiry dropdown
- if( $showProtectOptions && !$this->disabled ) {
- $out .= "
- <table><tr>
- <td class='mw-label'>
- {$mProtectexpiry}
- </td>
- <td class='mw-input'>" .
- Xml::tags( 'select',
- array(
- 'id' => "mwProtectExpirySelection-$action",
- 'name' => "wpProtectExpirySelection-$action",
- 'onchange' => "ProtectionForm.updateExpiryList(this)",
- 'tabindex' => '2' ) + $this->disabledAttrib,
- $expiryFormOptions ) .
- "</td>
- </tr></table>";
- }
- # Add custom expiry field
- $attribs = array( 'id' => "mwProtect-$action-expires",
- 'onkeyup' => 'ProtectionForm.updateExpiry(this)',
- 'onchange' => 'ProtectionForm.updateExpiry(this)' ) + $this->disabledAttrib;
- $out .= "<table><tr>
- <td class='mw-label'>" .
- $mProtectother .
- '</td>
- <td class="mw-input">' .
- Xml::input( "mwProtect-expiry-$action", 50, $this->mExpiry[$action], $attribs ) .
- '</td>
- </tr></table>';
- $out .= "</td></tr>" .
- Xml::closeElement( 'table' ) .
- Xml::closeElement( 'fieldset' ) .
- "</td></tr>";
- }
- # Give extensions a chance to add items to the form
- wfRunHooks( 'ProtectionForm::buildForm', array($this->mArticle,&$out) );
-
- $out .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' );
-
- // JavaScript will add another row with a value-chaining checkbox
- if( $this->mTitle->exists() ) {
- $out .= Xml::openElement( 'table', array( 'id' => 'mw-protect-table2' ) ) .
- Xml::openElement( 'tbody' );
- $out .= '<tr>
- <td></td>
- <td class="mw-input">' .
- Xml::checkLabel( wfMsg( 'protect-cascade' ), 'mwProtect-cascade', 'mwProtect-cascade',
- $this->mCascade, $this->disabledAttrib ) .
- "</td>
- </tr>\n";
- $out .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' );
- }
-
- # Add manual and custom reason field/selects as well as submit
- if( !$this->disabled ) {
- $out .= Xml::openElement( 'table', array( 'id' => 'mw-protect-table3' ) ) .
- Xml::openElement( 'tbody' );
- $out .= "
- <tr>
- <td class='mw-label'>
- {$mProtectreasonother}
- </td>
- <td class='mw-input'>
- {$reasonDropDown}
- </td>
- </tr>
- <tr>
- <td class='mw-label'>
- {$mProtectreason}
- </td>
- <td class='mw-input'>" .
- Xml::input( 'mwProtect-reason', 60, $this->mReason, array( 'type' => 'text',
- 'id' => 'mwProtect-reason', 'maxlength' => 180 ) ) .
- // Limited maxlength as the database trims at 255 bytes and other texts
- // chosen by dropdown menus on this page are also included in this database field.
- // The byte limit of 180 bytes is enforced in javascript
- "</td>
- </tr>";
- # Disallow watching is user is not logged in
- if( $wgUser->isLoggedIn() ) {
- $out .= "
- <tr>
- <td></td>
- <td class='mw-input'>" .
- Xml::checkLabel( wfMsg( 'watchthis' ),
- 'mwProtectWatch', 'mwProtectWatch',
- $this->mTitle->userIsWatching() || $wgUser->getOption( 'watchdefault' ) ) .
- "</td>
- </tr>";
- }
- $out .= "
- <tr>
- <td></td>
- <td class='mw-submit'>" .
- Xml::submitButton( wfMsg( 'confirm' ), array( 'id' => 'mw-Protect-submit' ) ) .
- "</td>
- </tr>\n";
- $out .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' );
- }
- $out .= Xml::closeElement( 'fieldset' );
-
- if ( $wgUser->isAllowed( 'editinterface' ) ) {
- $title = Title::makeTitle( NS_MEDIAWIKI, 'Protect-dropdown' );
- $link = Linker::link(
- $title,
- wfMsgHtml( 'protect-edit-reasonlist' ),
- array(),
- array( 'action' => 'edit' )
- );
- $out .= '<p class="mw-protect-editreasons">' . $link . '</p>';
- }
-
- if ( !$this->disabled ) {
- $out .= Html::hidden( 'wpEditToken', $wgUser->getEditToken( array( 'protect', $this->mTitle->getPrefixedDBkey() ) ) );
- $out .= Xml::closeElement( 'form' );
- $wgOut->addScript( $this->buildCleanupScript() );
- }
-
- return $out;
- }
-
- /**
- * Build protection level selector
- *
- * @param $action String: action to protect
- * @param $selected String: current protection level
- * @return String: HTML fragment
- */
- function buildSelector( $action, $selected ) {
- global $wgRestrictionLevels, $wgUser;
-
- $levels = array();
- foreach( $wgRestrictionLevels as $key ) {
- //don't let them choose levels above their own (aka so they can still unprotect and edit the page). but only when the form isn't disabled
- if( $key == 'sysop' ) {
- //special case, rewrite sysop to protect and editprotected
- if( !$wgUser->isAllowedAny( 'protect', 'editprotected' ) && !$this->disabled )
- continue;
- } else {
- if( !$wgUser->isAllowed($key) && !$this->disabled )
- continue;
- }
- $levels[] = $key;
- }
-
- $id = 'mwProtect-level-' . $action;
- $attribs = array(
- 'id' => $id,
- 'name' => $id,
- 'size' => count( $levels ),
- 'onchange' => 'ProtectionForm.updateLevels(this)',
- ) + $this->disabledAttrib;
-
- $out = Xml::openElement( 'select', $attribs );
- foreach( $levels as $key ) {
- $out .= Xml::option( $this->getOptionLabel( $key ), $key, $key == $selected );
- }
- $out .= Xml::closeElement( 'select' );
- return $out;
- }
-
- /**
- * Prepare the label for a protection selector option
- *
- * @param $permission String: permission required
- * @return String
- */
- private function getOptionLabel( $permission ) {
- if( $permission == '' ) {
- return wfMsg( 'protect-default' );
- } else {
- $msg = wfMessage( "protect-level-{$permission}" );
- if( $msg->exists() ) {
- return $msg->text();
- }
- return wfMsg( 'protect-fallback', $permission );
- }
- }
-
- function buildCleanupScript() {
- global $wgRestrictionLevels, $wgGroupPermissions, $wgOut;
-
- $cascadeableLevels = array();
- foreach( $wgRestrictionLevels as $key ) {
- if ( ( isset( $wgGroupPermissions[$key]['protect'] ) && $wgGroupPermissions[$key]['protect'] )
- || $key == 'protect'
- ) {
- $cascadeableLevels[] = $key;
- }
- }
- $options = array(
- 'tableId' => 'mwProtectSet',
- 'labelText' => wfMessage( 'protect-unchain-permissions' )->plain(),
- 'numTypes' => count( $this->mApplicableTypes ),
- 'existingMatch' => count( array_unique( $this->mExistingExpiry ) ) === 1,
- );
-
- $wgOut->addJsConfigVars( 'wgCascadeableLevels', $cascadeableLevels );
- $script = Xml::encodeJsCall( 'ProtectionForm.init', array( $options ) );
- return Html::inlineScript( ResourceLoader::makeLoaderConditionalScript( $script ) );
- }
-
- /**
- * Show protection long extracts for this page
- *
- * @param $out OutputPage
- * @access private
- */
- function showLogExtract( &$out ) {
- # Show relevant lines from the protection log:
- $out->addHTML( Xml::element( 'h2', null, LogPage::logName( 'protect' ) ) );
- LogEventsList::showLogExtract( $out, 'protect', $this->mTitle );
- # Let extensions add other relevant log extracts
- wfRunHooks( 'ProtectionForm::showLogExtract', array($this->mArticle,$out) );
- }
-}
diff --git a/includes/SkinLegacy.php b/includes/SkinLegacy.php
index 77c85a88cb44..96b8a79ec9f3 100644
--- a/includes/SkinLegacy.php
+++ b/includes/SkinLegacy.php
@@ -584,34 +584,6 @@ class LegacyTemplate extends BaseTemplate {
return $s;
}
- function protectThisPage() {
- global $wgUser, $wgRequest;
-
- $diff = $wgRequest->getVal( 'diff' );
- $title = $this->getSkin()->getTitle();
-
- if ( $title->getArticleId() && ( ! $diff ) && $wgUser->isAllowed( 'protect' ) ) {
- if ( $title->isProtected() ) {
- $text = wfMsg( 'unprotectthispage' );
- $query = array( 'action' => 'unprotect' );
- } else {
- $text = wfMsg( 'protectthispage' );
- $query = array( 'action' => 'protect' );
- }
-
- $s = Linker::linkKnown(
- $title,
- $text,
- array(),
- $query
- );
- } else {
- $s = '';
- }
-
- return $s;
- }
-
function watchThisPage() {
global $wgOut, $wgUser;
++$this->mWatchLinkNum;
diff --git a/includes/SkinTemplate.php b/includes/SkinTemplate.php
index 2dd00980424e..2777b3f773f6 100644
--- a/includes/SkinTemplate.php
+++ b/includes/SkinTemplate.php
@@ -263,7 +263,6 @@ class SkinTemplate extends Skin {
$tpl->set( 'editable', ( !$title->isSpecialPage() ) );
$tpl->set( 'exists', $title->getArticleID() != 0 );
$tpl->set( 'watch', $title->userIsWatching() ? 'unwatch' : 'watch' );
- $tpl->set( 'protect', count( $title->isProtected() ) ? 'unprotect' : 'protect' );
$tpl->set( 'helppage', $this->msg( 'helppage' )->text() );
*/
$tpl->set( 'searchaction', $this->escapeSearchLink() );
@@ -946,15 +945,6 @@ class SkinTemplate extends Skin {
}
}
- if ( $title->getNamespace() !== NS_MEDIAWIKI && $title->quickUserCan( 'protect', $user ) ) {
- $mode = $title->isProtected() ? 'unprotect' : 'protect';
- $content_navigation['actions'][$mode] = array(
- 'class' => ( $onPage && $action == $mode ) ? 'selected' : false,
- 'text' => wfMessageFallback( "$skname-action-$mode", $mode )->setContext( $this->getContext() )->text(),
- 'href' => $title->getLocalURL( "action=$mode" )
- );
- }
-
wfProfileOut( __METHOD__ . '-live' );
// Checks if the user is logged in
diff --git a/includes/SpecialPageFactory.php b/includes/SpecialPageFactory.php
index 0a1631b0fe57..e17172944901 100644
--- a/includes/SpecialPageFactory.php
+++ b/includes/SpecialPageFactory.php
@@ -42,8 +42,6 @@ class SpecialPageFactory {
'Lonelypages' => 'LonelypagesPage',
'Fewestrevisions' => 'FewestrevisionsPage',
'Withoutinterwiki' => 'WithoutinterwikiPage',
- 'Protectedpages' => 'SpecialProtectedpages',
- 'Protectedtitles' => 'SpecialProtectedtitles',
'Shortpages' => 'ShortpagesPage',
'Uncategorizedcategories' => 'UncategorizedcategoriesPage',
'Uncategorizedimages' => 'UncategorizedimagesPage',
diff --git a/includes/Title.php b/includes/Title.php
index f3cf79d4e99a..05a2e390a1a5 100644
--- a/includes/Title.php
+++ b/includes/Title.php
@@ -64,16 +64,7 @@ class Title {
var $mArticleID = -1; // /< Article ID, fetched from the link cache on demand
var $mLatestID = false; // /< ID of most recent revision
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?
- var $mCascadingRestrictions; // Caching the results of getCascadeProtectionSources
- var $mRestrictionsExpiry = array(); ///< When do the restrictions on this page expire?
- var $mHasCascadingRestrictions; ///< Are cascading restrictions in effect on this page?
- var $mCascadeSources; ///< Where are the cascading restrictions coming from on this page?
- var $mRestrictionsLoaded = false; ///< Boolean for initialisation on demand
var $mPrefixedText; ///< Text form including namespace/interwiki, initialised on demand
- var $mTitleProtection; ///< Cached value for getTitleProtection (create protection)
# Don't change the following default, NS_MAIN is hardcoded in several
# places. See bug 696.
var $mDefaultNamespace = NS_MAIN; // /< Namespace index when there is no namespace
@@ -1574,7 +1565,7 @@ class Title {
* @param $action String action that permission needs to be checked for
* @param $user User to check
* @param $doExpensiveQueries Bool Set this to false to avoid doing unnecessary
- * queries by skipping checks for cascading protections and user blocks.
+ * queries by skipping checks for user blocks.
* @param $ignoreErrors Array of Strings Set this to a list of message keys
* whose corresponding errors may be ignored.
* @return Array of arguments to wfMsg to explain permissions problems.
@@ -1731,14 +1722,6 @@ class Title {
$errors[] = array( 'ns-specialprotected' );
}
- # Check $wgNamespaceProtection for restricted namespaces
- if ( $this->isNamespaceProtected( $user ) ) {
- $ns = $this->mNamespace == NS_MAIN ?
- wfMsg( 'nstab-main' ) : $this->getNsText();
- $errors[] = $this->mNamespace == NS_MEDIAWIKI ?
- array( 'protectedinterface' ) : array( 'namespaceprotected', $ns );
- }
-
return $errors;
}
@@ -1770,78 +1753,6 @@ class Title {
}
/**
- * Check against page_restrictions table requirements on this
- * page. The user must possess all required rights for this
- * action.
- *
- * @param $action String the action to check
- * @param $user User user to check
- * @param $errors Array list of current errors
- * @param $doExpensiveQueries Boolean whether or not to perform expensive queries
- * @param $short Boolean short circuit on first error
- *
- * @return Array list of errors
- */
- private function checkPageRestrictions( $action, $user, $errors, $doExpensiveQueries, $short ) {
- foreach ( $this->getRestrictions( $action ) as $right ) {
- // Backwards compatibility, rewrite sysop -> protect
- if ( $right == 'sysop' ) {
- $right = 'protect';
- }
- if ( $right != '' && !$user->isAllowed( $right ) ) {
- // Users with 'editprotected' permission can edit protected pages
- // without cascading option turned on.
- if ( $action != 'edit' || !$user->isAllowed( 'editprotected' )
- || $this->mCascadeRestriction )
- {
- $errors[] = array( 'protectedpagetext', $right );
- }
- }
- }
-
- return $errors;
- }
-
- /**
- * Check restrictions on cascading pages.
- *
- * @param $action String the action to check
- * @param $user User to check
- * @param $errors Array list of current errors
- * @param $doExpensiveQueries Boolean whether or not to perform expensive queries
- * @param $short Boolean short circuit on first error
- *
- * @return Array list of errors
- */
- private function checkCascadingSourcesRestrictions( $action, $user, $errors, $doExpensiveQueries, $short ) {
- if ( $doExpensiveQueries && !$this->isCssJsSubpage() ) {
- # We /could/ use the protection level on the source page, but it's
- # fairly ugly as we have to establish a precedence hierarchy for pages
- # included by multiple cascade-protected pages. So just restrict
- # it to people with 'protect' permission, as they could remove the
- # protection anyway.
- list( $cascadingSources, $restrictions ) = $this->getCascadeProtectionSources();
- # Cascading protection depends on more than this page...
- # Several cascading protected pages may include this page...
- # Check each cascading level
- # This is only for protection restrictions, not for all actions
- if ( isset( $restrictions[$action] ) ) {
- foreach ( $restrictions[$action] as $right ) {
- $right = ( $right == 'sysop' ) ? 'protect' : $right;
- if ( $right != '' && !$user->isAllowed( $right ) ) {
- $pages = '';
- foreach ( $cascadingSources as $page )
- $pages .= '* [[:' . $page->getPrefixedText() . "]]\n";
- $errors[] = array( 'cascadeprotected', count( $cascadingSources ), $pages );
- }
- }
- }
- }
-
- return $errors;
- }
-
- /**
* Check action permissions not already checked in checkQuickPermissions
*
* @param $action String the action to check
@@ -1855,24 +1766,7 @@ class Title {
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.
- $errors[] = array( 'protect-cantedit' );
- }
- } elseif ( $action == 'create' ) {
- $title_protection = $this->getTitleProtection();
- if( $title_protection ) {
- if( $title_protection['pt_create_perm'] == 'sysop' ) {
- $title_protection['pt_create_perm'] = 'protect'; // B/C
- }
- if( $title_protection['pt_create_perm'] == '' ||
- !$user->isAllowed( $title_protection['pt_create_perm'] ) )
- {
- $errors[] = array( 'titleprotected', User::whoIs( $title_protection['pt_user'] ), $title_protection['pt_reason'] );
- }
- }
- } elseif ( $action == 'move' ) {
+ if ( $action == 'move' ) {
// Check for immobile pages
if ( !MWNamespace::isMovable( $this->mNamespace ) ) {
// Specific message for this case
@@ -1894,6 +1788,9 @@ class Title {
$errors[] = array( 'delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) );
}
}
+
+ wfRunHooks( 'CheckActionPermissions', array( $this, $action, $user, &$errors, $doExpensiveQueries, $short ) );
+
return $errors;
}
@@ -2109,8 +2006,6 @@ class Title {
'checkPermissionHooks',
'checkSpecialsAndNSPermissions',
'checkCSSandJSPermissions',
- 'checkPageRestrictions',
- 'checkCascadingSourcesRestrictions',
'checkActionPermissions',
'checkUserBlock'
);
@@ -2156,514 +2051,6 @@ class Title {
}
/**
- * Get a filtered list of all restriction types supported by this wiki.
- * @param bool $exists True to get all restriction types that apply to
- * titles that do exist, False for all restriction types that apply to
- * titles that do not exist
- * @return array
- */
- public static function getFilteredRestrictionTypes( $exists = true ) {
- global $wgRestrictionTypes;
- $types = $wgRestrictionTypes;
- if ( $exists ) {
- # Remove the create restriction for existing titles
- $types = array_diff( $types, array( 'create' ) );
- } else {
- # Only the create and upload restrictions apply to non-existing titles
- $types = array_intersect( $types, array( 'create', 'upload' ) );
- }
- return $types;
- }
-
- /**
- * Returns restriction types for the current Title
- *
- * @return array applicable restriction types
- */
- public function getRestrictionTypes() {
- if ( $this->isSpecialPage() ) {
- return array();
- }
-
- $types = self::getFilteredRestrictionTypes( $this->exists() );
-
- if ( $this->getNamespace() != NS_FILE ) {
- # Remove the upload restriction for non-file titles
- $types = array_diff( $types, array( 'upload' ) );
- }
-
- wfRunHooks( 'TitleGetRestrictionTypes', array( $this, &$types ) );
-
- wfDebug( __METHOD__ . ': applicable restrictions to [[' .
- $this->getPrefixedText() . ']] are {' . implode( ',', $types ) . "}\n" );
-
- return $types;
- }
-
- /**
- * Is this title subject to title protection?
- * Title protection is the one applied against creation of such title.
- *
- * @return Mixed An associative array representing any existent title
- * protection, or false if there's none.
- */
- private function getTitleProtection() {
- // Can't protect pages in special namespaces
- if ( $this->getNamespace() < 0 ) {
- return false;
- }
-
- // Can't protect pages that exist.
- if ( $this->exists() ) {
- return false;
- }
-
- if ( !isset( $this->mTitleProtection ) ) {
- $dbr = wfGetDB( DB_SLAVE );
- $res = $dbr->select( 'protected_titles', '*',
- array( 'pt_namespace' => $this->getNamespace(), 'pt_title' => $this->getDBkey() ),
- __METHOD__ );
-
- // fetchRow returns false if there are no rows.
- $this->mTitleProtection = $dbr->fetchRow( $res );
- }
- return $this->mTitleProtection;
- }
-
- /**
- * Update the title protection status
- *
- * @deprecated in 1.19; will be removed in 1.20. Use WikiPage::doUpdateRestrictions() instead.
- * @param $create_perm String Permission required for creation
- * @param $reason String Reason for protection
- * @param $expiry String Expiry timestamp
- * @return boolean true
- */
- public function updateTitleProtection( $create_perm, $reason, $expiry ) {
- wfDeprecated( __METHOD__, '1.19' );
-
- global $wgUser;
-
- $limit = array( 'create' => $create_perm );
- $expiry = array( 'create' => $expiry );
-
- $page = WikiPage::factory( $this );
- $status = $page->doUpdateRestrictions( $limit, $expiry, false, $reason, $wgUser );
-
- return $status->isOK();
- }
-
- /**
- * Remove any title protection due to page existing
- */
- public function deleteTitleProtection() {
- $dbw = wfGetDB( DB_MASTER );
-
- $dbw->delete(
- 'protected_titles',
- array( 'pt_namespace' => $this->getNamespace(), 'pt_title' => $this->getDBkey() ),
- __METHOD__
- );
- $this->mTitleProtection = false;
- }
-
- /**
- * Is this page "semi-protected" - the *only* protection is autoconfirm?
- *
- * @param $action String Action to check (default: edit)
- * @return Bool
- */
- public function isSemiProtected( $action = 'edit' ) {
- if ( $this->exists() ) {
- $restrictions = $this->getRestrictions( $action );
- if ( count( $restrictions ) > 0 ) {
- foreach ( $restrictions as $restriction ) {
- if ( strtolower( $restriction ) != 'autoconfirmed' ) {
- return false;
- }
- }
- } else {
- # Not protected
- return false;
- }
- return true;
- } else {
- # If it doesn't exist, it can't be protected
- return false;
- }
- }
-
- /**
- * Does the title correspond to a protected article?
- *
- * @param $action String the action the page is protected from,
- * by default checks all actions.
- * @return Bool
- */
- public function isProtected( $action = '' ) {
- global $wgRestrictionLevels;
-
- $restrictionTypes = $this->getRestrictionTypes();
-
- # Special pages have inherent protection
- if( $this->isSpecialPage() ) {
- return true;
- }
-
- # Check regular protection levels
- foreach ( $restrictionTypes as $type ) {
- if ( $action == $type || $action == '' ) {
- $r = $this->getRestrictions( $type );
- foreach ( $wgRestrictionLevels as $level ) {
- if ( in_array( $level, $r ) && $level != '' ) {
- return true;
- }
- }
- }
- }
-
- return false;
- }
-
- /**
- * Determines if $user is unable to edit this page because it has been protected
- * by $wgNamespaceProtection.
- *
- * @param $user User object to check permissions
- * @return Bool
- */
- public function isNamespaceProtected( User $user ) {
- global $wgNamespaceProtection;
-
- if ( isset( $wgNamespaceProtection[$this->mNamespace] ) ) {
- foreach ( (array)$wgNamespaceProtection[$this->mNamespace] as $right ) {
- if ( $right != '' && !$user->isAllowed( $right ) ) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Cascading protection: Return true if cascading restrictions apply to this page, false if not.
- *
- * @return Bool If the page is subject to cascading restrictions.
- */
- public function isCascadeProtected() {
- list( $sources, /* $restrictions */ ) = $this->getCascadeProtectionSources( false );
- return ( $sources > 0 );
- }
-
- /**
- * Cascading protection: Get the source of any cascading restrictions on this page.
- *
- * @param $getPages Bool Whether or not to retrieve the actual pages
- * that the restrictions have come from.
- * @return Mixed Array of Title objects of the pages from which cascading restrictions
- * have come, false for none, or true if such restrictions exist, but $getPages
- * was not set. The restriction array is an array of each type, each of which
- * contains a array of unique groups.
- */
- public function getCascadeProtectionSources( $getPages = true ) {
- global $wgContLang;
- $pagerestrictions = array();
-
- if ( isset( $this->mCascadeSources ) && $getPages ) {
- return array( $this->mCascadeSources, $this->mCascadingRestrictions );
- } elseif ( isset( $this->mHasCascadingRestrictions ) && !$getPages ) {
- return array( $this->mHasCascadingRestrictions, $pagerestrictions );
- }
-
- wfProfileIn( __METHOD__ );
-
- $dbr = wfGetDB( DB_SLAVE );
-
- if ( $this->getNamespace() == NS_FILE ) {
- $tables = array( 'imagelinks', 'page_restrictions' );
- $where_clauses = array(
- 'il_to' => $this->getDBkey(),
- 'il_from=pr_page',
- 'pr_cascade' => 1
- );
- } else {
- $tables = array( 'templatelinks', 'page_restrictions' );
- $where_clauses = array(
- 'tl_namespace' => $this->getNamespace(),
- 'tl_title' => $this->getDBkey(),
- 'tl_from=pr_page',
- 'pr_cascade' => 1
- );
- }
-
- if ( $getPages ) {
- $cols = array( 'pr_page', 'page_namespace', 'page_title',
- 'pr_expiry', 'pr_type', 'pr_level' );
- $where_clauses[] = 'page_id=pr_page';
- $tables[] = 'page';
- } else {
- $cols = array( 'pr_expiry' );
- }
-
- $res = $dbr->select( $tables, $cols, $where_clauses, __METHOD__ );
-
- $sources = $getPages ? array() : false;
- $now = wfTimestampNow();
- $purgeExpired = false;
-
- foreach ( $res as $row ) {
- $expiry = $wgContLang->formatExpiry( $row->pr_expiry, TS_MW );
- if ( $expiry > $now ) {
- if ( $getPages ) {
- $page_id = $row->pr_page;
- $page_ns = $row->page_namespace;
- $page_title = $row->page_title;
- $sources[$page_id] = Title::makeTitle( $page_ns, $page_title );
- # Add groups needed for each restriction type if its not already there
- # Make sure this restriction type still exists
-
- if ( !isset( $pagerestrictions[$row->pr_type] ) ) {
- $pagerestrictions[$row->pr_type] = array();
- }
-
- if ( isset( $pagerestrictions[$row->pr_type] ) &&
- !in_array( $row->pr_level, $pagerestrictions[$row->pr_type] ) ) {
- $pagerestrictions[$row->pr_type][] = $row->pr_level;
- }
- } else {
- $sources = true;
- }
- } else {
- // Trigger lazy purge of expired restrictions from the db
- $purgeExpired = true;
- }
- }
- if ( $purgeExpired ) {
- Title::purgeExpiredRestrictions();
- }
-
- if ( $getPages ) {
- $this->mCascadeSources = $sources;
- $this->mCascadingRestrictions = $pagerestrictions;
- } else {
- $this->mHasCascadingRestrictions = $sources;
- }
-
- wfProfileOut( __METHOD__ );
- return array( $sources, $pagerestrictions );
- }
-
- /**
- * Accessor/initialisation for mRestrictions
- *
- * @param $action String action that permission needs to be checked for
- * @return Array of Strings the array of groups allowed to edit this article
- */
- public function getRestrictions( $action ) {
- if ( !$this->mRestrictionsLoaded ) {
- $this->loadRestrictions();
- }
- return isset( $this->mRestrictions[$action] )
- ? $this->mRestrictions[$action]
- : array();
- }
-
- /**
- * Get the expiry time for the restriction against a given action
- *
- * @return String|Bool 14-char timestamp, or 'infinity' if the page is protected forever
- * or not protected at all, or false if the action is not recognised.
- */
- public function getRestrictionExpiry( $action ) {
- if ( !$this->mRestrictionsLoaded ) {
- $this->loadRestrictions();
- }
- return isset( $this->mRestrictionsExpiry[$action] ) ? $this->mRestrictionsExpiry[$action] : false;
- }
-
- /**
- * Returns cascading restrictions for the current article
- *
- * @return Boolean
- */
- function areRestrictionsCascading() {
- if ( !$this->mRestrictionsLoaded ) {
- $this->loadRestrictions();
- }
-
- return $this->mCascadeRestriction;
- }
-
- /**
- * Loads a string into mRestrictions array
- *
- * @param $res Resource restrictions as an SQL result.
- * @param $oldFashionedRestrictions String comma-separated list of page
- * restrictions from page table (pre 1.10)
- */
- private function loadRestrictionsFromResultWrapper( $res, $oldFashionedRestrictions = null ) {
- $rows = array();
-
- foreach ( $res as $row ) {
- $rows[] = $row;
- }
-
- $this->loadRestrictionsFromRows( $rows, $oldFashionedRestrictions );
- }
-
- /**
- * Compiles list of active page restrictions from both page table (pre 1.10)
- * and page_restrictions table for this existing page.
- * Public for usage by LiquidThreads.
- *
- * @param $rows array of db result objects
- * @param $oldFashionedRestrictions string comma-separated list of page
- * restrictions from page table (pre 1.10)
- */
- public function loadRestrictionsFromRows( $rows, $oldFashionedRestrictions = null ) {
- global $wgContLang;
- $dbr = wfGetDB( DB_SLAVE );
-
- $restrictionTypes = $this->getRestrictionTypes();
-
- foreach ( $restrictionTypes as $type ) {
- $this->mRestrictions[$type] = array();
- $this->mRestrictionsExpiry[$type] = $wgContLang->formatExpiry( '', TS_MW );
- }
-
- $this->mCascadeRestriction = false;
-
- # Backwards-compatibility: also load the restrictions from the page record (old format).
-
- if ( $oldFashionedRestrictions === null ) {
- $oldFashionedRestrictions = $dbr->selectField( 'page', 'page_restrictions',
- array( 'page_id' => $this->getArticleId() ), __METHOD__ );
- }
-
- if ( $oldFashionedRestrictions != '' ) {
-
- foreach ( explode( ':', trim( $oldFashionedRestrictions ) ) as $restrict ) {
- $temp = explode( '=', trim( $restrict ) );
- if ( count( $temp ) == 1 ) {
- // old old format should be treated as edit/move restriction
- $this->mRestrictions['edit'] = explode( ',', trim( $temp[0] ) );
- $this->mRestrictions['move'] = explode( ',', trim( $temp[0] ) );
- } else {
- $this->mRestrictions[$temp[0]] = explode( ',', trim( $temp[1] ) );
- }
- }
-
- $this->mOldRestrictions = true;
-
- }
-
- if ( count( $rows ) ) {
- # Current system - load second to make them override.
- $now = wfTimestampNow();
- $purgeExpired = false;
-
- # Cycle through all the restrictions.
- foreach ( $rows as $row ) {
-
- // Don't take care of restrictions types that aren't allowed
- if ( !in_array( $row->pr_type, $restrictionTypes ) )
- continue;
-
- // This code should be refactored, now that it's being used more generally,
- // But I don't really see any harm in leaving it in Block for now -werdna
- $expiry = $wgContLang->formatExpiry( $row->pr_expiry, TS_MW );
-
- // Only apply the restrictions if they haven't expired!
- if ( !$expiry || $expiry > $now ) {
- $this->mRestrictionsExpiry[$row->pr_type] = $expiry;
- $this->mRestrictions[$row->pr_type] = explode( ',', trim( $row->pr_level ) );
-
- $this->mCascadeRestriction |= $row->pr_cascade;
- } else {
- // Trigger a lazy purge of expired restrictions
- $purgeExpired = true;
- }
- }
-
- if ( $purgeExpired ) {
- Title::purgeExpiredRestrictions();
- }
- }
-
- $this->mRestrictionsLoaded = true;
- }
-
- /**
- * Load restrictions from the page_restrictions table
- *
- * @param $oldFashionedRestrictions String comma-separated list of page
- * restrictions from page table (pre 1.10)
- */
- public function loadRestrictions( $oldFashionedRestrictions = null ) {
- global $wgContLang;
- if ( !$this->mRestrictionsLoaded ) {
- if ( $this->exists() ) {
- $dbr = wfGetDB( DB_SLAVE );
-
- $res = $dbr->select(
- 'page_restrictions',
- '*',
- array( 'pr_page' => $this->getArticleId() ),
- __METHOD__
- );
-
- $this->loadRestrictionsFromResultWrapper( $res, $oldFashionedRestrictions );
- } else {
- $title_protection = $this->getTitleProtection();
-
- if ( $title_protection ) {
- $now = wfTimestampNow();
- $expiry = $wgContLang->formatExpiry( $title_protection['pt_expiry'], TS_MW );
-
- if ( !$expiry || $expiry > $now ) {
- // Apply the restrictions
- $this->mRestrictionsExpiry['create'] = $expiry;
- $this->mRestrictions['create'] = explode( ',', trim( $title_protection['pt_create_perm'] ) );
- } else { // Get rid of the old restrictions
- Title::purgeExpiredRestrictions();
- $this->mTitleProtection = false;
- }
- } else {
- $this->mRestrictionsExpiry['create'] = $wgContLang->formatExpiry( '', TS_MW );
- }
- $this->mRestrictionsLoaded = true;
- }
- }
- }
-
- /**
- * Flush the protection cache in this object and force reload from the database.
- * This is used when updating protection from WikiPage::doUpdateRestrictions().
- */
- public function flushRestrictions() {
- $this->mRestrictionsLoaded = false;
- $this->mTitleProtection = null;
- }
-
- /**
- * Purge expired restrictions from the page_restrictions table
- */
- static function purgeExpiredRestrictions() {
- $dbw = wfGetDB( DB_MASTER );
- $dbw->delete(
- 'page_restrictions',
- array( 'pr_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ),
- __METHOD__
- );
-
- $dbw->delete(
- 'protected_titles',
- array( 'pt_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ),
- __METHOD__
- );
- }
-
- /**
* Does this have subpages? (Warning, usually requires an extra DB query.)
*
* @return Bool
@@ -3387,12 +2774,6 @@ class Title {
if ( !$this->isValidMoveTarget( $nt ) ) {
$errors[] = array( 'articleexists' );
}
- } else {
- $tp = $nt->getTitleProtection();
- $right = ( $tp['pt_create_perm'] == 'sysop' ) ? 'protect' : $tp['pt_create_perm'];
- if ( $tp and !$wgUser->isAllowed( $right ) ) {
- $errors[] = array( 'cantmove-titleprotected' );
- }
}
if ( empty( $errors ) ) {
return true;
@@ -3477,7 +2858,6 @@ class Title {
$dbw->begin(); # If $file was a LocalFile, its transaction would have closed our own.
$pageid = $this->getArticleID( self::GAID_FOR_UPDATE );
- $protected = $this->isProtected();
// Do the actual move
$err = $this->moveToInternal( $nt, $reason, $createRedirect );
@@ -3512,31 +2892,6 @@ class Title {
$redirid = $this->getArticleID();
- if ( $protected ) {
- # Protect the redirect title as the title used to be...
- $dbw->insertSelect( 'page_restrictions', 'page_restrictions',
- array(
- 'pr_page' => $redirid,
- 'pr_type' => 'pr_type',
- 'pr_level' => 'pr_level',
- 'pr_cascade' => 'pr_cascade',
- 'pr_user' => 'pr_user',
- 'pr_expiry' => 'pr_expiry'
- ),
- array( 'pr_page' => $pageid ),
- __METHOD__,
- array( 'IGNORE' )
- );
- # Update the protection log
- $log = new LogPage( 'protect' );
- $comment = wfMsgForContent( 'prot_1movedto2', $this->getPrefixedText(), $nt->getPrefixedText() );
- if ( $reason ) {
- $comment .= wfMsgForContent( 'colon-separator' ) . $reason;
- }
- // @todo FIXME: $params?
- $log->addEntry( 'move_prot', $nt, $comment, array( $this->getPrefixedText() ) );
- }
-
# Update watchlists
$oldnamespace = $this->getNamespace() & ~1;
$newnamespace = $nt->getNamespace() & ~1;
diff --git a/includes/WikiPage.php b/includes/WikiPage.php
index acc9831aa55a..728cb23aaf95 100644
--- a/includes/WikiPage.php
+++ b/includes/WikiPage.php
@@ -263,8 +263,7 @@ class WikiPage extends Page {
$this->mTitle->loadFromRow( $data );
- # Old-fashioned restrictions
- $this->mTitle->loadRestrictions( $data->page_restrictions );
+ //XXX there was a "loadRestrictions" here that is apparently for pre-1.10 compatibility
$this->mCounter = intval( $data->page_counter );
$this->mTouched = wfTimestamp( TS_MW, $data->page_touched );
@@ -1681,238 +1680,6 @@ class WikiPage extends Page {
}
/**
- * Update the article's restriction field, and leave a log entry.
- * This works for protection both existing and non-existing pages.
- *
- * @param $limit Array: set of restriction keys
- * @param $reason String
- * @param &$cascade Integer. Set to false if cascading protection isn't allowed.
- * @param $expiry Array: per restriction type expiration
- * @param $user User The user updating the restrictions
- * @return bool true on success
- */
- public function doUpdateRestrictions( array $limit, array $expiry, &$cascade, $reason, User $user ) {
- global $wgContLang;
-
- if ( wfReadOnly() ) {
- return Status::newFatal( 'readonlytext', wfReadOnlyReason() );
- }
-
- $restrictionTypes = $this->mTitle->getRestrictionTypes();
-
- $id = $this->mTitle->getArticleID();
-
- if ( !$cascade ) {
- $cascade = false;
- }
-
- // Take this opportunity to purge out expired restrictions
- Title::purgeExpiredRestrictions();
-
- # @todo FIXME: Same limitations as described in ProtectionForm.php (line 37);
- # we expect a single selection, but the schema allows otherwise.
- $isProtected = false;
- $protect = false;
- $changed = false;
-
- $dbw = wfGetDB( DB_MASTER );
-
- foreach ( $restrictionTypes as $action ) {
- if ( !isset( $expiry[$action] ) ) {
- $expiry[$action] = $dbw->getInfinity();
- }
- if ( !isset( $limit[$action] ) ) {
- $limit[$action] = '';
- } elseif ( $limit[$action] != '' ) {
- $protect = true;
- }
-
- # Get current restrictions on $action
- $current = implode( '', $this->mTitle->getRestrictions( $action ) );
- if ( $current != '' ) {
- $isProtected = true;
- }
-
- if ( $limit[$action] != $current ) {
- $changed = true;
- } elseif ( $limit[$action] != '' ) {
- # Only check expiry change if the action is actually being
- # protected, since expiry does nothing on an not-protected
- # action.
- if ( $this->mTitle->getRestrictionExpiry( $action ) != $expiry[$action] ) {
- $changed = true;
- }
- }
- }
-
- if ( !$changed && $protect && $this->mTitle->areRestrictionsCascading() != $cascade ) {
- $changed = true;
- }
-
- # If nothing's changed, do nothing
- if ( !$changed ) {
- return Status::newGood();
- }
-
- if ( !$protect ) { # No protection at all means unprotection
- $revCommentMsg = 'unprotectedarticle';
- $logAction = 'unprotect';
- } elseif ( $isProtected ) {
- $revCommentMsg = 'modifiedarticleprotection';
- $logAction = 'modify';
- } else {
- $revCommentMsg = 'protectedarticle';
- $logAction = 'protect';
- }
-
- $encodedExpiry = array();
- $protectDescription = '';
- foreach ( $limit as $action => $restrictions ) {
- $encodedExpiry[$action] = $dbw->encodeExpiry( $expiry[$action] );
- if ( $restrictions != '' ) {
- $protectDescription .= $wgContLang->getDirMark() . "[$action=$restrictions] (";
- if ( $encodedExpiry[$action] != 'infinity' ) {
- $protectDescription .= wfMsgForContent( 'protect-expiring',
- $wgContLang->timeanddate( $expiry[$action], false, false ) ,
- $wgContLang->date( $expiry[$action], false, false ) ,
- $wgContLang->time( $expiry[$action], false, false ) );
- } else {
- $protectDescription .= wfMsgForContent( 'protect-expiry-indefinite' );
- }
-
- $protectDescription .= ') ';
- }
- }
- $protectDescription = trim( $protectDescription );
-
- if ( $id ) { # Protection of existing page
- if ( !wfRunHooks( 'ArticleProtect', array( &$this, &$user, $limit, $reason ) ) ) {
- return Status::newGood();
- }
-
- # Only restrictions with the 'protect' right can cascade...
- # Otherwise, people who cannot normally protect can "protect" pages via transclusion
- $editrestriction = isset( $limit['edit'] ) ? array( $limit['edit'] ) : $this->mTitle->getRestrictions( 'edit' );
-
- # The schema allows multiple restrictions
- if ( !in_array( 'protect', $editrestriction ) && !in_array( 'sysop', $editrestriction ) ) {
- $cascade = false;
- }
-
- # Update restrictions table
- foreach ( $limit as $action => $restrictions ) {
- if ( $restrictions != '' ) {
- $dbw->replace( 'page_restrictions', array( array( 'pr_page', 'pr_type' ) ),
- array( 'pr_page' => $id,
- 'pr_type' => $action,
- 'pr_level' => $restrictions,
- 'pr_cascade' => ( $cascade && $action == 'edit' ) ? 1 : 0,
- 'pr_expiry' => $encodedExpiry[$action]
- ),
- __METHOD__
- );
- } else {
- $dbw->delete( 'page_restrictions', array( 'pr_page' => $id,
- 'pr_type' => $action ), __METHOD__ );
- }
- }
-
- # Prepare a null revision to be added to the history
- $editComment = $wgContLang->ucfirst( wfMsgForContent( $revCommentMsg, $this->mTitle->getPrefixedText() ) );
- if ( $reason ) {
- $editComment .= ": $reason";
- }
- if ( $protectDescription ) {
- $editComment .= " ($protectDescription)";
- }
- if ( $cascade ) {
- $editComment .= ' [' . wfMsgForContent( 'protect-summary-cascade' ) . ']';
- }
-
- # Insert a null revision
- $nullRevision = Revision::newNullRevision( $dbw, $id, $editComment, true );
- $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 ) );
- } else { # Protection of non-existing page (also known as "title protection")
- # Cascade protection is meaningless in this case
- $cascade = false;
-
- if ( $limit['create'] != '' ) {
- $dbw->replace( 'protected_titles',
- array( array( 'pt_namespace', 'pt_title' ) ),
- array(
- 'pt_namespace' => $this->mTitle->getNamespace(),
- 'pt_title' => $this->mTitle->getDBkey(),
- 'pt_create_perm' => $limit['create'],
- 'pt_timestamp' => $dbw->encodeExpiry( wfTimestampNow() ),
- 'pt_expiry' => $encodedExpiry['create'],
- 'pt_user' => $user->getId(),
- 'pt_reason' => $reason,
- ), __METHOD__
- );
- } else {
- $dbw->delete( 'protected_titles',
- array(
- 'pt_namespace' => $this->mTitle->getNamespace(),
- 'pt_title' => $this->mTitle->getDBkey()
- ), __METHOD__
- );
- }
- }
-
- $this->mTitle->flushRestrictions();
-
- if ( $logAction == 'unprotect' ) {
- $logParams = array();
- } else {
- $logParams = array( $protectDescription, $cascade ? 'cascade' : '' );
- }
-
- # Update the protection log
- $log = new LogPage( 'protect' );
- $log->addEntry( $logAction, $this->mTitle, trim( $reason ), $logParams, $user );
-
- return Status::newGood();
- }
-
- /**
- * Take an array of page restrictions and flatten it to a string
- * suitable for insertion into the page_restrictions field.
- * @param $limit Array
- * @return String
- */
- protected static function flattenRestrictions( $limit ) {
- if ( !is_array( $limit ) ) {
- throw new MWException( 'WikiPage::flattenRestrictions given non-array restriction set' );
- }
-
- $bits = array();
- ksort( $limit );
-
- foreach ( $limit as $action => $restrictions ) {
- if ( $restrictions != '' ) {
- $bits[] = "$action=$restrictions";
- }
- }
-
- return implode( ':', $bits );
- }
-
- /**
* Same as doDeleteArticleReal(), but returns more detailed success/failure status
* Deletes the article with database consistency, writes logs, purges caches
*
@@ -2312,7 +2079,8 @@ class WikiPage extends Page {
$title->touchLinks();
$title->purgeSquid();
- $title->deleteTitleProtection();
+
+ //n.b. omitting the deleteTitleRestriction() here
}
/**
@@ -2627,57 +2395,6 @@ class WikiPage extends Page {
}
/**
- * Updates cascading protections
- *
- * @param $parserOutput ParserOutput object for the current version
- */
- public function doCascadeProtectionUpdates( ParserOutput $parserOutput ) {
- if ( wfReadOnly() || !$this->mTitle->areRestrictionsCascading() ) {
- return;
- }
-
- // templatelinks table may have become out of sync,
- // especially if using variable-based transclusions.
- // For paranoia, check if things have changed and if
- // so apply updates to the database. This will ensure
- // that cascaded protections apply as soon as the changes
- // are visible.
-
- # Get templates from templatelinks
- $id = $this->mTitle->getArticleID();
-
- $tlTemplates = array();
-
- $dbr = wfGetDB( DB_SLAVE );
- $res = $dbr->select( array( 'templatelinks' ),
- array( 'tl_namespace', 'tl_title' ),
- array( 'tl_from' => $id ),
- __METHOD__
- );
-
- foreach ( $res as $row ) {
- $tlTemplates["{$row->tl_namespace}:{$row->tl_title}"] = true;
- }
-
- # Get templates from parser output.
- $poTemplates = array();
- foreach ( $parserOutput->getTemplates() as $ns => $templates ) {
- foreach ( $templates as $dbk => $id ) {
- $poTemplates["$ns:$dbk"] = true;
- }
- }
-
- # Get the diff
- $templates_diff = array_diff_key( $poTemplates, $tlTemplates );
-
- if ( count( $templates_diff ) > 0 ) {
- # Whee, link updates time.
- $u = new LinksUpdate( $this->mTitle, $parserOutput, false );
- $u->doUpdate();
- }
- }
-
- /**
* Return a list of templates used by this article.
* Uses the templatelinks table
*
@@ -2753,27 +2470,6 @@ class WikiPage extends Page {
}
/**
- * Update the article's restriction field, and leave a log entry.
- *
- * @deprecated since 1.19
- * @param $limit Array: set of restriction keys
- * @param $reason String
- * @param &$cascade Integer. Set to false if cascading protection isn't allowed.
- * @param $expiry Array: per restriction type expiration
- * @param $user User The user updating the restrictions
- * @return bool true on success
- */
- public function updateRestrictions(
- $limit = array(), $reason = '', &$cascade = 0, $expiry = array(), User $user = null
- ) {
- global $wgUser;
-
- $user = is_null( $user ) ? $wgUser : $user;
-
- return $this->doUpdateRestrictions( $limit, $expiry, $cascade, $reason, $user )->isOK();
- }
-
- /**
* @deprecated since 1.18
*/
public function quickEdit( $text, $comment = '', $minor = 0 ) {
@@ -2931,9 +2627,7 @@ class PoolWorkArticleView extends PoolCounterWork {
$wgUseFileCache = false;
}
- if ( $isCurrent ) {
- $this->page->doCascadeProtectionUpdates( $this->parserOutput );
- }
+ wfRunHooks( 'UpdateRestrictions', array( $this->page->getTitle() ) );
return true;
}
diff --git a/includes/actions/ProtectAction.php b/includes/actions/ProtectAction.php
deleted file mode 100644
index f053ede779bf..000000000000
--- a/includes/actions/ProtectAction.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/**
- * action=protect handler
- *
- * Copyright © 2012 Timo Tijhof
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * @file
- * @ingroup Actions
- * @author Timo Tijhof
- */
-
-class ProtectAction extends FormlessAction {
-
- public function getName() {
- return 'protect';
- }
-
- public function onView(){
- return null;
- }
-
- public function show(){
-
- $this->page->protect();
-
- }
-
-}
-
-class UnprotectAction extends ProtectAction {
-
- public function getName() {
- return 'unprotect';
- }
-
- public function show(){
-
- $this->page->unprotect();
-
- }
-
-}
diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php
index a586f688f1e5..f12b8922df4a 100644
--- a/includes/api/ApiBase.php
+++ b/includes/api/ApiBase.php
@@ -518,6 +518,9 @@ abstract class ApiBase extends ContextSource {
return false;
}
+ //TODO: The hooks can be run here, in getAllowedParams and friends.
+ // Then, inheriting classes call the parent's method implementation
+ // at the tail of the overriding function.
/**
* Returns an array of allowed parameters (parameter name) => (default
* value) or (parameter name) => (array with PARAM_* constants as keys)
@@ -1417,6 +1420,18 @@ abstract class ApiBase extends ContextSource {
}
/**
+ * Get final list of possible errors, after hooks have had a chance to tweak it as
+ * needed.
+ *
+ * @return array
+ */
+ public function getFinalPossibleErrors() {
+ $errs = $this->getPossibleErrors();
+ wfRunHooks( 'APIGetPossibleErrors', array( &$this, &$errs ) );
+ return $errs;
+ }
+
+ /**
* Parses a list of errors into a standardised format
* @param $errors array List of errors. Items can be in the for array( key, param1, param2, ... ) or array( 'code' => ..., 'info' => ... )
* @return array Parsed list of errors with items in the form array( 'code' => ..., 'info' => ... )
diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php
index fa95cfca3e0a..ea52de6e1500 100644
--- a/includes/api/ApiMain.php
+++ b/includes/api/ApiMain.php
@@ -67,7 +67,6 @@ class ApiMain extends ApiBase {
'rollback' => 'ApiRollback',
'delete' => 'ApiDelete',
'undelete' => 'ApiUndelete',
- 'protect' => 'ApiProtect',
'block' => 'ApiBlock',
'unblock' => 'ApiUnblock',
'move' => 'ApiMove',
diff --git a/includes/api/ApiParamInfo.php b/includes/api/ApiParamInfo.php
index f2263476270b..6c4a61444d49 100644
--- a/includes/api/ApiParamInfo.php
+++ b/includes/api/ApiParamInfo.php
@@ -252,7 +252,7 @@ class ApiParamInfo extends ApiBase {
$result->setIndexedTagName( $retval['parameters'], 'param' );
// Errors
- $retval['errors'] = $this->parseErrors( $obj->getPossibleErrors() );
+ $retval['errors'] = $this->parseErrors( $obj->getFinalPossibleErrors() );
$result->setIndexedTagName( $retval['errors'], 'error' );
return $retval;
diff --git a/includes/api/ApiProtect.php b/includes/api/ApiProtect.php
deleted file mode 100644
index fb225d86b6d2..000000000000
--- a/includes/api/ApiProtect.php
+++ /dev/null
@@ -1,225 +0,0 @@
-<?php
-/**
- *
- *
- * Created on Sep 1, 2007
- *
- * Copyright © 2007 Roan Kattouw <Firstname>.<Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * @ingroup API
- */
-class ApiProtect extends ApiBase {
-
- public function __construct( $main, $action ) {
- parent::__construct( $main, $action );
- }
-
- public function execute() {
- global $wgRestrictionLevels;
- $params = $this->extractRequestParams();
-
- $titleObj = Title::newFromText( $params['title'] );
- if ( !$titleObj ) {
- $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
- }
-
- $errors = $titleObj->getUserPermissionsErrors( 'protect', $this->getUser() );
- if ( $errors ) {
- // We don't care about multiple errors, just report one of them
- $this->dieUsageMsg( reset( $errors ) );
- }
-
- $expiry = (array)$params['expiry'];
- if ( count( $expiry ) != count( $params['protections'] ) ) {
- if ( count( $expiry ) == 1 ) {
- $expiry = array_fill( 0, count( $params['protections'] ), $expiry[0] );
- } else {
- $this->dieUsageMsg( array( 'toofewexpiries', count( $expiry ), count( $params['protections'] ) ) );
- }
- }
-
- $restrictionTypes = $titleObj->getRestrictionTypes();
- $dbr = wfGetDB( DB_SLAVE );
-
- $protections = array();
- $expiryarray = array();
- $resultProtections = array();
- foreach ( $params['protections'] as $i => $prot ) {
- $p = explode( '=', $prot );
- $protections[$p[0]] = ( $p[1] == 'all' ? '' : $p[1] );
-
- if ( $titleObj->exists() && $p[0] == 'create' ) {
- $this->dieUsageMsg( 'create-titleexists' );
- }
- if ( !$titleObj->exists() && $p[0] != 'create' ) {
- $this->dieUsageMsg( 'missingtitle-createonly' );
- }
-
- if ( !in_array( $p[0], $restrictionTypes ) && $p[0] != 'create' ) {
- $this->dieUsageMsg( array( 'protect-invalidaction', $p[0] ) );
- }
- if ( !in_array( $p[1], $wgRestrictionLevels ) && $p[1] != 'all' ) {
- $this->dieUsageMsg( array( 'protect-invalidlevel', $p[1] ) );
- }
-
- if ( in_array( $expiry[$i], array( 'infinite', 'indefinite', 'never' ) ) ) {
- $expiryarray[$p[0]] = $dbr->getInfinity();
- } else {
- $exp = strtotime( $expiry[$i] );
- if ( $exp < 0 || !$exp ) {
- $this->dieUsageMsg( array( 'invalidexpiry', $expiry[$i] ) );
- }
-
- $exp = wfTimestamp( TS_MW, $exp );
- if ( $exp < wfTimestampNow() ) {
- $this->dieUsageMsg( array( 'pastexpiry', $expiry[$i] ) );
- }
- $expiryarray[$p[0]] = $exp;
- }
- $resultProtections[] = array( $p[0] => $protections[$p[0]],
- 'expiry' => ( $expiryarray[$p[0]] == $dbr->getInfinity() ?
- 'infinite' :
- wfTimestamp( TS_ISO_8601, $expiryarray[$p[0]] ) ) );
- }
-
- $cascade = $params['cascade'];
-
- $watch = $params['watch'] ? 'watch' : $params['watchlist'];
- $this->setWatch( $watch, $titleObj );
-
- $pageObj = WikiPage::factory( $titleObj );
- $status = $pageObj->doUpdateRestrictions( $protections, $expiryarray, $cascade, $params['reason'], $this->getUser() );
-
- if ( !$status->isOK() ) {
- $errors = $status->getErrorsArray();
- $this->dieUsageMsg( $errors[0] );
- }
- $res = array(
- 'title' => $titleObj->getPrefixedText(),
- 'reason' => $params['reason']
- );
- if ( $cascade ) {
- $res['cascade'] = '';
- }
- $res['protections'] = $resultProtections;
- $result = $this->getResult();
- $result->setIndexedTagName( $res['protections'], 'protection' );
- $result->addValue( null, $this->getModuleName(), $res );
- }
-
- public function mustBePosted() {
- return true;
- }
-
- public function isWriteMode() {
- return true;
- }
-
- public function getAllowedParams() {
- return array(
- 'title' => array(
- ApiBase::PARAM_TYPE => 'string',
- ApiBase::PARAM_REQUIRED => true
- ),
- 'token' => null,
- 'protections' => array(
- ApiBase::PARAM_ISMULTI => true,
- ApiBase::PARAM_REQUIRED => true,
- ),
- 'expiry' => array(
- ApiBase::PARAM_ISMULTI => true,
- ApiBase::PARAM_ALLOW_DUPLICATES => true,
- ApiBase::PARAM_DFLT => 'infinite',
- ),
- 'reason' => '',
- 'cascade' => false,
- 'watch' => array(
- ApiBase::PARAM_DFLT => false,
- ApiBase::PARAM_DEPRECATED => true,
- ),
- 'watchlist' => array(
- ApiBase::PARAM_DFLT => 'preferences',
- ApiBase::PARAM_TYPE => array(
- 'watch',
- 'unwatch',
- 'preferences',
- 'nochange'
- ),
- ),
- );
- }
-
- public function getParamDescription() {
- return array(
- 'title' => 'Title of the page you want to (un)protect',
- 'token' => 'A protect token previously retrieved through prop=info',
- 'protections' => 'Pipe-separated list of protection levels, formatted action=group (e.g. edit=sysop)',
- 'expiry' => array( 'Expiry timestamps. If only one timestamp is set, it\'ll be used for all protections.',
- 'Use \'infinite\', \'indefinite\' or \'never\', for a neverexpiring protection.' ),
- 'reason' => 'Reason for (un)protecting (optional)',
- 'cascade' => array( 'Enable cascading protection (i.e. protect pages included in this page)',
- 'Ignored if not all protection levels are \'sysop\' or \'protect\'' ),
- 'watch' => 'If set, add the page being (un)protected to your watchlist',
- 'watchlist' => 'Unconditionally add or remove the page from your watchlist, use preferences or do not change watch',
- );
- }
-
- public function getDescription() {
- return 'Change the protection level of a page';
- }
-
- public function getPossibleErrors() {
- return array_merge( parent::getPossibleErrors(), array(
- array( 'invalidtitle', 'title' ),
- array( 'toofewexpiries', 'noofexpiries', 'noofprotections' ),
- array( 'create-titleexists' ),
- array( 'missingtitle-createonly' ),
- array( 'protect-invalidaction', 'action' ),
- array( 'protect-invalidlevel', 'level' ),
- array( 'invalidexpiry', 'expiry' ),
- array( 'pastexpiry', 'expiry' ),
- ) );
- }
-
- public function needsToken() {
- return true;
- }
-
- public function getTokenSalt() {
- return '';
- }
-
- public function getExamples() {
- return array(
- 'api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=sysop|move=sysop&cascade=&expiry=20070901163000|never',
- 'api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=all|move=all&reason=Lifting%20restrictions'
- );
- }
-
- public function getHelpUrls() {
- return 'https://www.mediawiki.org/wiki/API:Protect';
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id$';
- }
-}
diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php
index cd54a7daf79b..4d977ba2f803 100644
--- a/includes/api/ApiQuery.php
+++ b/includes/api/ApiQuery.php
@@ -88,7 +88,6 @@ class ApiQuery extends ApiBase {
'exturlusage' => 'ApiQueryExtLinksUsage',
'users' => 'ApiQueryUsers',
'random' => 'ApiQueryRandom',
- 'protectedtitles' => 'ApiQueryProtectedTitles',
'querypage' => 'ApiQueryQueryPage',
);
diff --git a/includes/api/ApiQueryAllpages.php b/includes/api/ApiQueryAllpages.php
index e003ee9115f0..85ffa5f28a7f 100644
--- a/includes/api/ApiQueryAllpages.php
+++ b/includes/api/ApiQueryAllpages.php
@@ -105,43 +105,6 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
$forceNameTitleIndex = false;
}
- // Page protection filtering
- if ( count( $params['prtype'] ) || $params['prexpiry'] != 'all' ) {
- $this->addTables( 'page_restrictions' );
- $this->addWhere( 'page_id=pr_page' );
- $this->addWhere( 'pr_expiry>' . $db->addQuotes( $db->timestamp() ) );
-
- if ( count( $params['prtype'] ) ) {
- $this->addWhereFld( 'pr_type', $params['prtype'] );
-
- if ( isset( $params['prlevel'] ) ) {
- // Remove the empty string and '*' from the prlevel array
- $prlevel = array_diff( $params['prlevel'], array( '', '*' ) );
-
- if ( count( $prlevel ) ) {
- $this->addWhereFld( 'pr_level', $prlevel );
- }
- }
- if ( $params['prfiltercascade'] == 'cascading' ) {
- $this->addWhereFld( 'pr_cascade', 1 );
- } elseif ( $params['prfiltercascade'] == 'noncascading' ) {
- $this->addWhereFld( 'pr_cascade', 0 );
- }
-
- $this->addOption( 'DISTINCT' );
- }
- $forceNameTitleIndex = false;
-
- if ( $params['prexpiry'] == 'indefinite' ) {
- $this->addWhere( "pr_expiry = {$db->addQuotes( $db->getInfinity() )} OR pr_expiry IS NULL" );
- } elseif ( $params['prexpiry'] == 'definite' ) {
- $this->addWhere( "pr_expiry != {$db->addQuotes( $db->getInfinity() )}" );
- }
-
- } elseif ( isset( $params['prlevel'] ) ) {
- $this->dieUsage( 'prlevel may not be used without prtype', 'params' );
- }
-
if ( $params['filterlanglinks'] == 'withoutlanglinks' ) {
$this->addTables( 'langlinks' );
$this->addJoinConds( array( 'langlinks' => array( 'LEFT JOIN', 'page_id=ll_from' ) ) );
@@ -158,11 +121,14 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
}
if ( $forceNameTitleIndex ) {
- $this->addOption( 'USE INDEX', 'name_title' );
+ $this->addOption( 'USE INDEX', array( 'page' => 'name_title' ) );
}
$limit = $params['limit'];
$this->addOption( 'LIMIT', $limit + 1 );
+
+ wfRunHooks( 'APIQueryAllpages::RunAlter', array( $this, $db, $params ) );
+
$res = $this->select( __METHOD__ );
$count = 0;
@@ -198,8 +164,6 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
}
public function getAllowedParams() {
- global $wgRestrictionLevels;
-
return array(
'from' => null,
'to' => null,
@@ -222,22 +186,6 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
'maxsize' => array(
ApiBase::PARAM_TYPE => 'integer',
),
- 'prtype' => array(
- ApiBase::PARAM_TYPE => Title::getFilteredRestrictionTypes( true ),
- ApiBase::PARAM_ISMULTI => true
- ),
- 'prlevel' => array(
- ApiBase::PARAM_TYPE => $wgRestrictionLevels,
- ApiBase::PARAM_ISMULTI => true
- ),
- 'prfiltercascade' => array(
- ApiBase::PARAM_DFLT => 'all',
- ApiBase::PARAM_TYPE => array(
- 'cascading',
- 'noncascading',
- 'all'
- ),
- ),
'limit' => array(
ApiBase::PARAM_DFLT => 10,
ApiBase::PARAM_TYPE => 'limit',
@@ -260,14 +208,6 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
),
ApiBase::PARAM_DFLT => 'all'
),
- 'prexpiry' => array(
- ApiBase::PARAM_TYPE => array(
- 'indefinite',
- 'definite',
- 'all'
- ),
- ApiBase::PARAM_DFLT => 'all'
- ),
);
}
@@ -282,17 +222,8 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
'dir' => 'The direction in which to list',
'minsize' => 'Limit to pages with at least this many bytes',
'maxsize' => 'Limit to pages with at most this many bytes',
- 'prtype' => 'Limit to protected pages only',
- 'prlevel' => "The protection level (must be used with {$p}prtype= parameter)",
- 'prfiltercascade' => "Filter protections based on cascadingness (ignored when {$p}prtype isn't set)",
'filterlanglinks' => 'Filter based on whether a page has langlinks',
'limit' => 'How many total pages to return.',
- 'prexpiry' => array(
- 'Which protection expiry to filter the page on',
- ' indefinite - Get only pages with indefinite protection expiry',
- ' definite - Get only pages with a definite (specific) protection expiry',
- ' all - Get pages with any protections expiry'
- ),
);
}
@@ -303,7 +234,6 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
public function getPossibleErrors() {
return array_merge( parent::getPossibleErrors(), array(
array( 'code' => 'params', 'info' => 'Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator' ),
- array( 'code' => 'params', 'info' => 'prlevel may not be used without prtype' ),
) );
}
diff --git a/includes/api/ApiQueryBase.php b/includes/api/ApiQueryBase.php
index 4fe82de0cb73..705ec152468e 100644
--- a/includes/api/ApiQueryBase.php
+++ b/includes/api/ApiQueryBase.php
@@ -79,7 +79,7 @@ abstract class ApiQueryBase extends ApiBase {
* @param $alias mixed Table alias, or null for no alias. Cannot be
* used with multiple tables
*/
- protected function addTables( $tables, $alias = null ) {
+ function addTables( $tables, $alias = null ) {
if ( is_array( $tables ) ) {
if ( !is_null( $alias ) ) {
ApiBase::dieDebug( __METHOD__, 'Multiple table aliases not supported' );
@@ -147,7 +147,7 @@ abstract class ApiQueryBase extends ApiBase {
* to "foo=bar AND baz='3' AND bla='foo'"
* @param $value mixed String or array
*/
- protected function addWhere( $value ) {
+ function addWhere( $value ) {
if ( is_array( $value ) ) {
// Sanity check: don't insert empty arrays,
// Database::makeList() chokes on them
@@ -178,7 +178,7 @@ abstract class ApiQueryBase extends ApiBase {
* @param $field string Field name
* @param $value string Value; ignored if null or empty array;
*/
- protected function addWhereFld( $field, $value ) {
+ function addWhereFld( $field, $value ) {
// Use count() to its full documented capabilities to simultaneously
// test for null, empty array or empty countable object
if ( count( $value ) ) {
@@ -243,7 +243,7 @@ abstract class ApiQueryBase extends ApiBase {
* @param $name string Option name
* @param $value string Option value
*/
- protected function addOption( $name, $value = null ) {
+ function addOption( $name, $value = null ) {
if ( is_null( $value ) ) {
$this->options[] = $name;
} else {
diff --git a/includes/api/ApiQueryProtectedTitles.php b/includes/api/ApiQueryProtectedTitles.php
deleted file mode 100644
index 44cc1d3266e8..000000000000
--- a/includes/api/ApiQueryProtectedTitles.php
+++ /dev/null
@@ -1,234 +0,0 @@
-<?php
-/**
- *
- *
- * Created on Feb 13, 2009
- *
- * Copyright © 2009 Roan Kattouw <Firstname>.<Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Query module to enumerate all create-protected pages.
- *
- * @ingroup API
- */
-class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
-
- public function __construct( $query, $moduleName ) {
- parent::__construct( $query, $moduleName, 'pt' );
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator( $resultPageSet ) {
- $this->run( $resultPageSet );
- }
-
- /**
- * @param $resultPageSet ApiPageSet
- * @return void
- */
- private function run( $resultPageSet = null ) {
- $params = $this->extractRequestParams();
-
- $this->addTables( 'protected_titles' );
- $this->addFields( array( 'pt_namespace', 'pt_title', 'pt_timestamp' ) );
-
- $prop = array_flip( $params['prop'] );
- $this->addFieldsIf( 'pt_user', isset( $prop['user'] ) || isset( $prop['userid'] ) );
- $this->addFieldsIf( 'pt_reason', isset( $prop['comment'] ) || isset( $prop['parsedcomment'] ) );
- $this->addFieldsIf( 'pt_expiry', isset( $prop['expiry'] ) );
- $this->addFieldsIf( 'pt_create_perm', isset( $prop['level'] ) );
-
- $this->addTimestampWhereRange( 'pt_timestamp', $params['dir'], $params['start'], $params['end'] );
- $this->addWhereFld( 'pt_namespace', $params['namespace'] );
- $this->addWhereFld( 'pt_create_perm', $params['level'] );
-
- if ( isset( $prop['user'] ) ) {
- $this->addTables( 'user' );
- $this->addFields( 'user_name' );
- $this->addJoinConds( array( 'user' => array( 'LEFT JOIN',
- 'user_id=pt_user'
- ) ) );
- }
-
- $this->addOption( 'LIMIT', $params['limit'] + 1 );
- $res = $this->select( __METHOD__ );
-
- $count = 0;
- $result = $this->getResult();
-
- $titles = array();
-
- foreach ( $res as $row ) {
- if ( ++ $count > $params['limit'] ) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->pt_timestamp ) );
- break;
- }
-
- $title = Title::makeTitle( $row->pt_namespace, $row->pt_title );
- if ( is_null( $resultPageSet ) ) {
- $vals = array();
- ApiQueryBase::addTitleInfo( $vals, $title );
- if ( isset( $prop['timestamp'] ) ) {
- $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->pt_timestamp );
- }
-
- if ( isset( $prop['user'] ) && !is_null( $row->user_name ) ) {
- $vals['user'] = $row->user_name;
- }
-
- if ( isset( $prop['user'] ) ) {
- $vals['userid'] = $row->pt_user;
- }
-
- if ( isset( $prop['comment'] ) ) {
- $vals['comment'] = $row->pt_reason;
- }
-
- if ( isset( $prop['parsedcomment'] ) ) {
- $vals['parsedcomment'] = Linker::formatComment( $row->pt_reason, $title );
- }
-
- if ( isset( $prop['expiry'] ) ) {
- global $wgContLang;
- $vals['expiry'] = $wgContLang->formatExpiry( $row->pt_expiry, TS_ISO_8601 );
- }
-
- if ( isset( $prop['level'] ) ) {
- $vals['level'] = $row->pt_create_perm;
- }
-
- $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
- if ( !$fit ) {
- $this->setContinueEnumParameter( 'start',
- wfTimestamp( TS_ISO_8601, $row->pt_timestamp ) );
- break;
- }
- } else {
- $titles[] = $title;
- }
- }
-
- if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), $this->getModulePrefix() );
- } else {
- $resultPageSet->populateFromTitles( $titles );
- }
- }
-
- public function getCacheMode( $params ) {
- if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
- // formatComment() calls wfMsg() among other things
- return 'anon-public-user-private';
- } else {
- return 'public';
- }
- }
-
- public function getAllowedParams() {
- global $wgRestrictionLevels;
- return array(
- 'namespace' => array(
- ApiBase::PARAM_ISMULTI => true,
- ApiBase::PARAM_TYPE => 'namespace',
- ),
- 'level' => array(
- ApiBase::PARAM_ISMULTI => true,
- ApiBase::PARAM_TYPE => array_diff( $wgRestrictionLevels, array( '' ) )
- ),
- 'limit' => array (
- ApiBase::PARAM_DFLT => 10,
- ApiBase::PARAM_TYPE => 'limit',
- ApiBase::PARAM_MIN => 1,
- ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
- ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
- ),
- 'dir' => array(
- ApiBase::PARAM_DFLT => 'older',
- ApiBase::PARAM_TYPE => array(
- 'newer',
- 'older'
- )
- ),
- 'start' => array(
- ApiBase::PARAM_TYPE => 'timestamp'
- ),
- 'end' => array(
- ApiBase::PARAM_TYPE => 'timestamp'
- ),
- 'prop' => array(
- ApiBase::PARAM_ISMULTI => true,
- ApiBase::PARAM_DFLT => 'timestamp|level',
- ApiBase::PARAM_TYPE => array(
- 'timestamp',
- 'user',
- 'userid',
- 'comment',
- 'parsedcomment',
- 'expiry',
- 'level'
- )
- ),
- );
- }
-
- public function getParamDescription() {
- return array(
- 'namespace' => 'Only list titles in these namespaces',
- 'start' => 'Start listing at this protection timestamp',
- 'end' => 'Stop listing at this protection timestamp',
- 'dir' => $this->getDirectionDescription( $this->getModulePrefix() ),
- 'limit' => 'How many total pages to return',
- 'prop' => array(
- 'Which properties to get',
- ' timestamp - Adds the timestamp of when protection was added',
- ' user - Adds the user that added the protection',
- ' userid - Adds the user id that added the protection',
- ' comment - Adds the comment for the protection',
- ' parsedcomment - Adds the parsed comment for the protection',
- ' expiry - Adds the timestamp of when the protection will be lifted',
- ' level - Adds the protection level',
- ),
- 'level' => 'Only list titles with these protection levels',
- );
- }
-
- public function getDescription() {
- return 'List all titles protected from creation';
- }
-
- public function getExamples() {
- return array(
- 'api.php?action=query&list=protectedtitles',
- );
- }
-
- public function getHelpUrls() {
- return 'https://www.mediawiki.org/wiki/API:Protectedtitles';
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id$';
- }
-}
diff --git a/includes/logging/LogEventsList.php b/includes/logging/LogEventsList.php
index 437670d013b9..92bf8c7982f0 100644
--- a/includes/logging/LogEventsList.php
+++ b/includes/logging/LogEventsList.php
@@ -429,26 +429,6 @@ class LogEventsList {
'known'
) .
')';
- // Show change protection link
- } elseif( self::typeAction( $row, 'protect', array( 'modify', 'protect', 'unprotect' ) ) ) {
- $revert .= ' (' .
- Linker::link( $title,
- $this->message['hist'],
- array(),
- array(
- 'action' => 'history',
- 'offset' => $row->log_timestamp
- )
- );
- if( $wgUser->isAllowed( 'protect' ) ) {
- $revert .= $this->message['pipe-separator'] .
- Linker::link( $title,
- $this->message['protect_change'],
- array(),
- array( 'action' => 'protect' ),
- 'known' );
- }
- $revert .= ')';
// Show unmerge link
} elseif( self::typeAction( $row, 'merge', 'merge', 'mergehistory' ) ) {
$revert = '(' . Linker::link(
diff --git a/includes/parser/CoreParserFunctions.php b/includes/parser/CoreParserFunctions.php
index 0e5702b79def..9bf4e8fa658a 100644
--- a/includes/parser/CoreParserFunctions.php
+++ b/includes/parser/CoreParserFunctions.php
@@ -604,16 +604,6 @@ class CoreParserFunctions {
}
/**
- * Returns the requested protection level for the current page
- */
- static function protectionlevel( $parser, $type = '' ) {
- $restrictions = $parser->mTitle->getRestrictions( strtolower( $type ) );
- # Title::getRestrictions returns an array, its possible it may have
- # multiple values in the future
- return implode( $restrictions, ',' );
- }
-
- /**
* Gives language names.
* @param $parser Parser
* @param $code String Language code
diff --git a/includes/specials/SpecialMovepage.php b/includes/specials/SpecialMovepage.php
index 5536fbc9919d..2ca70cfb9787 100644
--- a/includes/specials/SpecialMovepage.php
+++ b/includes/specials/SpecialMovepage.php
@@ -227,21 +227,7 @@ class MovePageForm extends UnlistedSpecialPage {
$out->addHTML( "</div>\n" );
}
- if ( $this->oldTitle->isProtected( 'move' ) ) {
- # Is the title semi-protected?
- if ( $this->oldTitle->isSemiProtected( 'move' ) ) {
- $noticeMsg = 'semiprotectedpagemovewarning';
- $classes[] = 'mw-textarea-sprotected';
- } else {
- # Then it must be protected based on static groups (regular)
- $noticeMsg = 'protectedpagemovewarning';
- $classes[] = 'mw-textarea-protected';
- }
- $out->addHTML( "<div class='mw-warning-with-logexcerpt'>\n" );
- $out->addWikiMsg( $noticeMsg );
- LogEventsList::showLogExtract( $out, 'protect', $this->oldTitle, '', array( 'lim' => 1 ) );
- $out->addHTML( "</div>\n" );
- }
+ //XXX display protection logs
// Byte limit (not string length limit) for wpReason and wpNewTitleMain
// is enforced in the mediawiki.special.movePage module
diff --git a/includes/specials/SpecialProtectedpages.php b/includes/specials/SpecialProtectedpages.php
deleted file mode 100644
index eec974fe0f37..000000000000
--- a/includes/specials/SpecialProtectedpages.php
+++ /dev/null
@@ -1,358 +0,0 @@
-<?php
-/**
- * Implements Special:Protectedpages
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup SpecialPage
- */
-
-/**
- * A special page that lists protected pages
- *
- * @ingroup SpecialPage
- */
-class SpecialProtectedpages extends SpecialPage {
-
- protected $IdLevel = 'level';
- protected $IdType = 'type';
-
- public function __construct() {
- parent::__construct( 'Protectedpages' );
- }
-
- public function execute( $par ) {
- $this->setHeaders();
- $this->outputHeader();
-
- // Purge expired entries on one in every 10 queries
- if( !mt_rand( 0, 10 ) ) {
- Title::purgeExpiredRestrictions();
- }
-
- $request = $this->getRequest();
- $type = $request->getVal( $this->IdType );
- $level = $request->getVal( $this->IdLevel );
- $sizetype = $request->getVal( 'sizetype' );
- $size = $request->getIntOrNull( 'size' );
- $NS = $request->getIntOrNull( 'namespace' );
- $indefOnly = $request->getBool( 'indefonly' ) ? 1 : 0;
- $cascadeOnly = $request->getBool('cascadeonly') ? 1 : 0;
-
- $pager = new ProtectedPagesPager( $this, array(), $type, $level, $NS, $sizetype, $size, $indefOnly, $cascadeOnly );
-
- $this->getOutput()->addHTML( $this->showOptions( $NS, $type, $level, $sizetype, $size, $indefOnly, $cascadeOnly ) );
-
- if( $pager->getNumRows() ) {
- $s = $pager->getNavigationBar();
- $s .= "<ul>" .
- $pager->getBody() .
- "</ul>";
- $s .= $pager->getNavigationBar();
- } else {
- $s = '<p>' . wfMsgHtml( 'protectedpagesempty' ) . '</p>';
- }
- $this->getOutput()->addHTML( $s );
- }
-
- /**
- * Callback function to output a restriction
- * @param $row object Protected title
- * @return string Formatted <li> element
- */
- public function formatRow( $row ) {
- wfProfileIn( __METHOD__ );
-
- static $infinity = null;
-
- if( is_null( $infinity ) ){
- $infinity = wfGetDB( DB_SLAVE )->getInfinity();
- }
-
- $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
- $link = Linker::link( $title );
-
- $description_items = array ();
-
- $protType = wfMsgHtml( 'restriction-level-' . $row->pr_level );
-
- $description_items[] = $protType;
-
- if( $row->pr_cascade ) {
- $description_items[] = wfMsg( 'protect-summary-cascade' );
- }
-
- $stxt = '';
- $lang = $this->getLanguage();
-
- $expiry = $lang->formatExpiry( $row->pr_expiry, TS_MW );
- if( $expiry != $infinity ) {
-
- $expiry_description = wfMsg(
- 'protect-expiring-local',
- $lang->timeanddate( $expiry, true ),
- $lang->date( $expiry, true ),
- $lang->time( $expiry, true )
- );
-
- $description_items[] = htmlspecialchars($expiry_description);
- }
-
- if(!is_null($size = $row->page_len)) {
- $stxt = $lang->getDirMark() . ' ' . Linker::formatRevisionSize( $size );
- }
-
- # Show a link to the change protection form for allowed users otherwise a link to the protection log
- if( $this->getUser()->isAllowed( 'protect' ) ) {
- $changeProtection = ' (' . Linker::linkKnown(
- $title,
- wfMsgHtml( 'protect_change' ),
- array(),
- array( 'action' => 'unprotect' )
- ) . ')';
- } else {
- $ltitle = SpecialPage::getTitleFor( 'Log' );
- $changeProtection = ' (' . Linker::linkKnown(
- $ltitle,
- wfMsgHtml( 'protectlogpage' ),
- array(),
- array(
- 'type' => 'protect',
- 'page' => $title->getPrefixedText()
- )
- ) . ')';
- }
-
- wfProfileOut( __METHOD__ );
-
- return Html::rawElement(
- 'li',
- array(),
- $lang->specialList( $link . $stxt, $lang->commaList( $description_items ), false ) . $changeProtection ) . "\n";
- }
-
- /**
- * @param $namespace Integer
- * @param $type String: restriction type
- * @param $level String: restriction level
- * @param $sizetype String: "min" or "max"
- * @param $size Integer
- * @param $indefOnly Boolean: only indefinie protection
- * @param $cascadeOnly Boolean: only cascading protection
- * @return String: input form
- */
- protected function showOptions( $namespace, $type='edit', $level, $sizetype, $size, $indefOnly, $cascadeOnly ) {
- global $wgScript;
- $title = $this->getTitle();
- return Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) .
- Xml::openElement( 'fieldset' ) .
- Xml::element( 'legend', array(), wfMsg( 'protectedpages' ) ) .
- Html::hidden( 'title', $title->getPrefixedDBkey() ) . "\n" .
- $this->getNamespaceMenu( $namespace ) . "&#160;\n" .
- $this->getTypeMenu( $type ) . "&#160;\n" .
- $this->getLevelMenu( $level ) . "&#160;\n" .
- "<br /><span style='white-space: nowrap'>" .
- $this->getExpiryCheck( $indefOnly ) . "&#160;\n" .
- $this->getCascadeCheck( $cascadeOnly ) . "&#160;\n" .
- "</span><br /><span style='white-space: nowrap'>" .
- $this->getSizeLimit( $sizetype, $size ) . "&#160;\n" .
- "</span>" .
- "&#160;" . Xml::submitButton( wfMsg( 'allpagessubmit' ) ) . "\n" .
- Xml::closeElement( 'fieldset' ) .
- Xml::closeElement( 'form' );
- }
-
- /**
- * Prepare the namespace filter drop-down; standard namespace
- * selector, sans the MediaWiki namespace
- *
- * @param $namespace Mixed: pre-select namespace
- * @return String
- */
- protected function getNamespaceMenu( $namespace = null ) {
- return "<span style='white-space: nowrap'>" .
- Xml::label( wfMsg( 'namespace' ), 'namespace' ) . '&#160;'
- . Xml::namespaceSelector( $namespace, '' ) . "</span>";
- }
-
- /**
- * @return string Formatted HTML
- */
- protected function getExpiryCheck( $indefOnly ) {
- return
- Xml::checkLabel( wfMsg('protectedpages-indef'), 'indefonly', 'indefonly', $indefOnly ) . "\n";
- }
-
- /**
- * @return string Formatted HTML
- */
- protected function getCascadeCheck( $cascadeOnly ) {
- return
- Xml::checkLabel( wfMsg('protectedpages-cascade'), 'cascadeonly', 'cascadeonly', $cascadeOnly ) . "\n";
- }
-
- /**
- * @return string Formatted HTML
- */
- protected function getSizeLimit( $sizetype, $size ) {
- $max = $sizetype === 'max';
-
- return
- Xml::radioLabel( wfMsg('minimum-size'), 'sizetype', 'min', 'wpmin', !$max ) .
- '&#160;' .
- Xml::radioLabel( wfMsg('maximum-size'), 'sizetype', 'max', 'wpmax', $max ) .
- '&#160;' .
- Xml::input( 'size', 9, $size, array( 'id' => 'wpsize' ) ) .
- '&#160;' .
- Xml::label( wfMsg('pagesize'), 'wpsize' );
- }
-
- /**
- * Creates the input label of the restriction type
- * @param $pr_type string Protection type
- * @return string Formatted HTML
- */
- protected function getTypeMenu( $pr_type ) {
- $m = array(); // Temporary array
- $options = array();
-
- // First pass to load the log names
- foreach( Title::getFilteredRestrictionTypes( true ) as $type ) {
- $text = wfMsg("restriction-$type");
- $m[$text] = $type;
- }
-
- // Third pass generates sorted XHTML content
- foreach( $m as $text => $type ) {
- $selected = ($type == $pr_type );
- $options[] = Xml::option( $text, $type, $selected ) . "\n";
- }
-
- return "<span style='white-space: nowrap'>" .
- Xml::label( wfMsg('restriction-type') , $this->IdType ) . '&#160;' .
- Xml::tags( 'select',
- array( 'id' => $this->IdType, 'name' => $this->IdType ),
- implode( "\n", $options ) ) . "</span>";
- }
-
- /**
- * Creates the input label of the restriction level
- * @param $pr_level string Protection level
- * @return string Formatted HTML
- */
- protected function getLevelMenu( $pr_level ) {
- global $wgRestrictionLevels;
-
- $m = array( wfMsg('restriction-level-all') => 0 ); // Temporary array
- $options = array();
-
- // First pass to load the log names
- foreach( $wgRestrictionLevels as $type ) {
- // Messages used can be 'restriction-level-sysop' and 'restriction-level-autoconfirmed'
- if( $type !='' && $type !='*') {
- $text = wfMsg("restriction-level-$type");
- $m[$text] = $type;
- }
- }
-
- // Third pass generates sorted XHTML content
- foreach( $m as $text => $type ) {
- $selected = ($type == $pr_level );
- $options[] = Xml::option( $text, $type, $selected );
- }
-
- return "<span style='white-space: nowrap'>" .
- Xml::label( wfMsg( 'restriction-level' ) , $this->IdLevel ) . ' ' .
- Xml::tags( 'select',
- array( 'id' => $this->IdLevel, 'name' => $this->IdLevel ),
- implode( "\n", $options ) ) . "</span>";
- }
-}
-
-/**
- * @todo document
- * @ingroup Pager
- */
-class ProtectedPagesPager extends AlphabeticPager {
- public $mForm, $mConds;
- private $type, $level, $namespace, $sizetype, $size, $indefonly;
-
- function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype='', $size=0,
- $indefonly = false, $cascadeonly = false )
- {
- $this->mForm = $form;
- $this->mConds = $conds;
- $this->type = ( $type ) ? $type : 'edit';
- $this->level = $level;
- $this->namespace = $namespace;
- $this->sizetype = $sizetype;
- $this->size = intval($size);
- $this->indefonly = (bool)$indefonly;
- $this->cascadeonly = (bool)$cascadeonly;
- parent::__construct( $form->getContext() );
- }
-
- function getStartBody() {
- # Do a link batch query
- $lb = new LinkBatch;
- foreach ( $this->mResult as $row ) {
- $lb->add( $row->page_namespace, $row->page_title );
- }
- $lb->execute();
- return '';
- }
-
- function formatRow( $row ) {
- return $this->mForm->formatRow( $row );
- }
-
- function getQueryInfo() {
- $conds = $this->mConds;
- $conds[] = '(pr_expiry>' . $this->mDb->addQuotes( $this->mDb->timestamp() ) .
- 'OR pr_expiry IS NULL)';
- $conds[] = 'page_id=pr_page';
- $conds[] = 'pr_type=' . $this->mDb->addQuotes( $this->type );
-
- if( $this->sizetype=='min' ) {
- $conds[] = 'page_len>=' . $this->size;
- } elseif( $this->sizetype=='max' ) {
- $conds[] = 'page_len<=' . $this->size;
- }
-
- if( $this->indefonly ) {
- $db = wfGetDB( DB_SLAVE );
- $conds[] = "pr_expiry = {$db->addQuotes( $db->getInfinity() )} OR pr_expiry IS NULL";
- }
- if( $this->cascadeonly ) {
- $conds[] = "pr_cascade = '1'";
- }
-
- if( $this->level )
- $conds[] = 'pr_level=' . $this->mDb->addQuotes( $this->level );
- if( !is_null($this->namespace) )
- $conds[] = 'page_namespace=' . $this->mDb->addQuotes( $this->namespace );
- return array(
- 'tables' => array( 'page_restrictions', 'page' ),
- 'fields' => 'pr_id,page_namespace,page_title,page_len,pr_type,pr_level,pr_expiry,pr_cascade',
- 'conds' => $conds
- );
- }
-
- function getIndexField() {
- return 'pr_id';
- }
-}
diff --git a/includes/specials/SpecialProtectedtitles.php b/includes/specials/SpecialProtectedtitles.php
deleted file mode 100644
index 982feb661b14..000000000000
--- a/includes/specials/SpecialProtectedtitles.php
+++ /dev/null
@@ -1,243 +0,0 @@
-<?php
-/**
- * Implements Special:Protectedtitles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup SpecialPage
- */
-
-/**
- * A special page that list protected titles from creation
- *
- * @ingroup SpecialPage
- */
-class SpecialProtectedtitles extends SpecialPage {
-
- protected $IdLevel = 'level';
- protected $IdType = 'type';
-
- public function __construct() {
- parent::__construct( 'Protectedtitles' );
- }
-
- function execute( $par ) {
- $this->setHeaders();
- $this->outputHeader();
-
- // Purge expired entries on one in every 10 queries
- if ( !mt_rand( 0, 10 ) ) {
- Title::purgeExpiredRestrictions();
- }
-
- $request = $this->getRequest();
- $type = $request->getVal( $this->IdType );
- $level = $request->getVal( $this->IdLevel );
- $sizetype = $request->getVal( 'sizetype' );
- $size = $request->getIntOrNull( 'size' );
- $NS = $request->getIntOrNull( 'namespace' );
-
- $pager = new ProtectedTitlesPager( $this, array(), $type, $level, $NS, $sizetype, $size );
-
- $this->getOutput()->addHTML( $this->showOptions( $NS, $type, $level ) );
-
- if ( $pager->getNumRows() ) {
- $s = $pager->getNavigationBar();
- $s .= "<ul>" .
- $pager->getBody() .
- "</ul>";
- $s .= $pager->getNavigationBar();
- } else {
- $s = '<p>' . wfMsgHtml( 'protectedtitlesempty' ) . '</p>';
- }
- $this->getOutput()->addHTML( $s );
- }
-
- /**
- * Callback function to output a restriction
- *
- * @return string
- */
- function formatRow( $row ) {
- wfProfileIn( __METHOD__ );
-
- static $infinity = null;
-
- if( is_null( $infinity ) ){
- $infinity = wfGetDB( DB_SLAVE )->getInfinity();
- }
-
- $title = Title::makeTitleSafe( $row->pt_namespace, $row->pt_title );
- $link = Linker::link( $title );
-
- $description_items = array ();
-
- $protType = wfMsgHtml( 'restriction-level-' . $row->pt_create_perm );
-
- $description_items[] = $protType;
-
- $lang = $this->getLanguage();
- $expiry = strlen( $row->pt_expiry ) ? $lang->formatExpiry( $row->pt_expiry, TS_MW ) : $infinity;
- if( $expiry != $infinity ) {
- $expiry_description = wfMsg(
- 'protect-expiring-local',
- $lang->timeanddate( $expiry, true ),
- $lang->date( $expiry, true ),
- $lang->time( $expiry, true )
- );
-
- $description_items[] = htmlspecialchars($expiry_description);
- }
-
- wfProfileOut( __METHOD__ );
-
- return '<li>' . $lang->specialList( $link, implode( $description_items, ', ' ) ) . "</li>\n";
- }
-
- /**
- * @param $namespace Integer:
- * @param $type string
- * @param $level string
- * @private
- */
- function showOptions( $namespace, $type='edit', $level ) {
- global $wgScript;
- $action = htmlspecialchars( $wgScript );
- $title = $this->getTitle();
- $special = htmlspecialchars( $title->getPrefixedDBkey() );
- return "<form action=\"$action\" method=\"get\">\n" .
- '<fieldset>' .
- Xml::element( 'legend', array(), wfMsg( 'protectedtitles' ) ) .
- Html::hidden( 'title', $special ) . "&#160;\n" .
- $this->getNamespaceMenu( $namespace ) . "&#160;\n" .
- $this->getLevelMenu( $level ) . "&#160;\n" .
- "&#160;" . Xml::submitButton( wfMsg( 'allpagessubmit' ) ) . "\n" .
- "</fieldset></form>";
- }
-
- /**
- * Prepare the namespace filter drop-down; standard namespace
- * selector, sans the MediaWiki namespace
- *
- * @param $namespace Mixed: pre-select namespace
- * @return string
- */
- function getNamespaceMenu( $namespace = null ) {
- return Xml::label( wfMsg( 'namespace' ), 'namespace' )
- . '&#160;'
- . Xml::namespaceSelector( $namespace, '' );
- }
-
- /**
- * @return string Formatted HTML
- * @private
- */
- function getLevelMenu( $pr_level ) {
- global $wgRestrictionLevels;
-
- $m = array( wfMsg('restriction-level-all') => 0 ); // Temporary array
- $options = array();
-
- // First pass to load the log names
- foreach( $wgRestrictionLevels as $type ) {
- if ( $type !='' && $type !='*') {
- $text = wfMsg("restriction-level-$type");
- $m[$text] = $type;
- }
- }
- // Is there only one level (aside from "all")?
- if( count($m) <= 2 ) {
- return '';
- }
- // Third pass generates sorted XHTML content
- foreach( $m as $text => $type ) {
- $selected = ($type == $pr_level );
- $options[] = Xml::option( $text, $type, $selected );
- }
-
- return
- Xml::label( wfMsg('restriction-level') , $this->IdLevel ) . '&#160;' .
- Xml::tags( 'select',
- array( 'id' => $this->IdLevel, 'name' => $this->IdLevel ),
- implode( "\n", $options ) );
- }
-}
-
-/**
- * @todo document
- * @ingroup Pager
- */
-class ProtectedTitlesPager extends AlphabeticPager {
- public $mForm, $mConds;
-
- function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype='', $size=0 ) {
- $this->mForm = $form;
- $this->mConds = $conds;
- $this->level = $level;
- $this->namespace = $namespace;
- $this->size = intval($size);
- parent::__construct( $form->getContext() );
- }
-
- function getStartBody() {
- wfProfileIn( __METHOD__ );
- # Do a link batch query
- $this->mResult->seek( 0 );
- $lb = new LinkBatch;
-
- foreach ( $this->mResult as $row ) {
- $lb->add( $row->pt_namespace, $row->pt_title );
- }
-
- $lb->execute();
- wfProfileOut( __METHOD__ );
- return '';
- }
-
- /**
- * @return Title
- */
- function getTitle() {
- return SpecialPage::getTitleFor( 'Protectedtitles' );
- }
-
- function formatRow( $row ) {
- return $this->mForm->formatRow( $row );
- }
-
- /**
- * @return array
- */
- function getQueryInfo() {
- $conds = $this->mConds;
- $conds[] = 'pt_expiry>' . $this->mDb->addQuotes( $this->mDb->timestamp() );
- if( $this->level )
- $conds['pt_create_perm'] = $this->level;
- if( !is_null($this->namespace) )
- $conds[] = 'pt_namespace=' . $this->mDb->addQuotes( $this->namespace );
- return array(
- 'tables' => 'protected_titles',
- 'fields' => 'pt_namespace,pt_title,pt_create_perm,pt_expiry,pt_timestamp',
- 'conds' => $conds
- );
- }
-
- function getIndexField() {
- return 'pt_timestamp';
- }
-}
-
diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php
index 5a5811d0be2b..515b8fb51a10 100644
--- a/languages/messages/MessagesEn.php
+++ b/languages/messages/MessagesEn.php
@@ -346,7 +346,6 @@ $magicWords = array(
'noindex' => array( 1, '__NOINDEX__' ),
'numberingroup' => array( 1, 'NUMBERINGROUP', 'NUMINGROUP' ),
'staticredirect' => array( 1, '__STATICREDIRECT__' ),
- 'protectionlevel' => array( 1, 'PROTECTIONLEVEL' ),
'formatdate' => array( 0, 'formatdate', 'dateformat' ),
'url_path' => array( 0, 'PATH' ),
'url_wiki' => array( 0, 'WIKI' ),
@@ -426,8 +425,6 @@ $specialPageAliases = array(
'Popularpages' => array( 'PopularPages' ),
'Preferences' => array( 'Preferences' ),
'Prefixindex' => array( 'PrefixIndex' ) ,
- 'Protectedpages' => array( 'ProtectedPages' ),
- 'Protectedtitles' => array( 'ProtectedTitles' ),
'Randompage' => array( 'Random', 'RandomPage' ),
'Randomredirect' => array( 'RandomRedirect' ),
'Recentchanges' => array( 'RecentChanges' ),
@@ -781,9 +778,7 @@ XHTML id names.
'vector-action-addsection' => 'Add topic',
'vector-action-delete' => 'Delete',
'vector-action-move' => 'Move',
-'vector-action-protect' => 'Protect',
'vector-action-undelete' => 'Undelete',
-'vector-action-unprotect' => 'Change protection',
'vector-simplesearch-preference' => 'Enable enhanced search suggestions (Vector skin only)',
'vector-view-create' => 'Create',
'vector-view-edit' => 'Edit',
@@ -817,11 +812,6 @@ XHTML id names.
'deletethispage' => 'Delete this page',
'undelete_short' => 'Undelete {{PLURAL:$1|one edit|$1 edits}}',
'viewdeleted_short' => 'View {{PLURAL:$1|one deleted edit|$1 deleted edits}}',
-'protect' => 'Protect',
-'protect_change' => 'change',
-'protectthispage' => 'Protect this page',
-'unprotect' => 'Change protection',
-'unprotectthispage' => 'Change protection of this page',
'newpage' => 'New page',
'talkpage' => 'Discuss this page',
'talkpagelinktext' => 'Talk',
@@ -847,7 +837,6 @@ XHTML id names.
'talkpageheader' => '-', # do not translate or duplicate this message to other languages
'lastmodifiedat' => 'This page was last modified on $1, at $2.',
'viewcount' => 'This page has been accessed {{PLURAL:$1|once|$1 times}}.',
-'protectedpage' => 'Protected page',
'jumpto' => 'Jump to:',
'jumptonavigation' => 'navigation',
'jumptosearch' => 'search',
@@ -1012,22 +1001,12 @@ Query: $2',
'actionthrottled' => 'Action throttled',
'actionthrottledtext' => 'As an anti-spam measure, you are limited from performing this action too many times in a short space of time, and you have exceeded this limit.
Please try again in a few minutes.',
-'protectedpagetext' => 'This page has been protected to prevent editing.',
'viewsourcetext' => 'You can view and copy the source of this page:',
'viewyourtext' => "You can view and copy the source of '''your edits''' to this page:",
-'protectedinterface' => 'This page provides interface text for the software, and is protected to prevent abuse.',
'editinginterface' => "'''Warning:''' You are editing a page which is used to provide interface text for the software.
Changes to this page will affect the appearance of the user interface for other users.
For translations, please consider using [//translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net], the MediaWiki localisation project.",
'sqlhidden' => '(SQL query hidden)',
-'cascadeprotected' => 'This page has been protected from editing, because it is included in the following {{PLURAL:$1|page, which is|pages, which are}} protected with the "cascading" option turned on:
-$2',
-'namespaceprotected' => "You do not have permission to edit pages in the '''$1''' namespace.",
-'customcssprotected' => "You do not have permission to edit this CSS page, because it contains another user's personal settings.",
-'customjsprotected' => "You do not have permission to edit this JavaScript page, because it contains another user's personal settings.",
-'ns-specialprotected' => 'Special pages cannot be edited.',
-'titleprotected' => 'This title has been protected from creation by [[User:$1|$1]].
-The reason given is "\'\'$2\'\'".',
# Virus scanner
'virus-badscanner' => "Bad configuration: Unknown virus scanner: ''$1''",
@@ -1404,18 +1383,9 @@ It cannot be saved.",
You may wish to cut-n-paste the text into a text file and save it for later.
The administrator who locked it offered this explanation: $1",
-'protectedpagewarning' => "'''Warning: This page has been protected so that only users with administrator privileges can edit it.'''
-The latest log entry is provided below for reference:",
-'semiprotectedpagewarning' => "'''Note:''' This page has been protected so that only registered users can edit it.
-The latest log entry is provided below for reference:",
-'cascadeprotectedwarning' => "'''Warning:''' This page has been protected so that only users with administrator privileges can edit it, because it is included in the following cascade-protected {{PLURAL:$1|page|pages}}:",
-'titleprotectedwarning' => "'''Warning: This page has been protected so that [[Special:ListGroupRights|specific rights]] are needed to create it.'''
-The latest log entry is provided below for reference:",
'templatesused' => '{{PLURAL:$1|Template|Templates}} used on this page:',
'templatesusedpreview' => '{{PLURAL:$1|Template|Templates}} used in this preview:',
'templatesusedsection' => '{{PLURAL:$1|Template|Templates}} used in this section:',
-'template-protected' => '(protected)',
-'template-semiprotected' => '(semi-protected)',
'hiddencategories' => 'This page is a member of {{PLURAL:$1|1 hidden category|$1 hidden categories}}:',
'edittools' => '<!-- Text here will be shown below edit and upload forms. -->', # only translate this message to other languages if you have to change it
'edittools-upload' => '-', # only translate this message to other languages if you have to change it
@@ -1941,7 +1911,6 @@ Your e-mail address is not revealed when other users contact you.',
'right-reupload-shared' => 'Override files on the shared media repository locally',
'right-upload_by_url' => 'Upload files from a URL',
'right-purge' => 'Purge the site cache for a page without confirmation',
-'right-autoconfirmed' => 'Edit semi-protected pages',
'right-bot' => 'Be treated as an automated process',
'right-nominornewtalk' => 'Not have minor edits to discussion pages trigger the new messages prompt',
'right-apihighlimits' => 'Use higher limits in API queries',
@@ -1961,8 +1930,6 @@ Your e-mail address is not revealed when other users contact you.',
'right-ipblock-exempt' => 'Bypass IP blocks, auto-blocks and range blocks',
'right-proxyunbannable' => 'Bypass automatic blocks of proxies',
'right-unblockself' => 'Unblock themselves',
-'right-protect' => 'Change protection levels and edit protected pages',
-'right-editprotected' => 'Edit protected pages (without cascading protection)',
'right-editinterface' => 'Edit the user interface',
'right-editusercssjs' => "Edit other users' CSS and JavaScript files",
'right-editusercss' => "Edit other users' CSS files",
@@ -2015,7 +1982,6 @@ Your e-mail address is not revealed when other users contact you.',
'action-suppressrevision' => 'review and restore this hidden revision',
'action-suppressionlog' => 'view this private log',
'action-block' => 'block this user from editing',
-'action-protect' => 'change protection levels for this page',
'action-rollback' => 'quickly rollback the edits of the last user who edited a particular page',
'action-import' => 'import this page from another wiki',
'action-importupload' => 'import this page from a file upload',
@@ -2564,16 +2530,6 @@ It now redirects to [[$2]].',
'deadendpages' => 'Dead-end pages',
'deadendpages-summary' => '', # do not translate or duplicate this message to other languages
'deadendpagestext' => 'The following pages do not link to other pages in {{SITENAME}}.',
-'protectedpages' => 'Protected pages',
-'protectedpages-indef' => 'Indefinite protections only',
-'protectedpages-summary' => '', # do not translate or duplicate this message to other languages
-'protectedpages-cascade' => 'Cascading protections only',
-'protectedpagestext' => 'The following pages are protected from moving or editing',
-'protectedpagesempty' => 'No pages are currently protected with these parameters.',
-'protectedtitles' => 'Protected titles',
-'protectedtitles-summary' => '', # do not translate or duplicate this message to other languages
-'protectedtitlestext' => 'The following titles are protected from creation',
-'protectedtitlesempty' => 'No titles are currently protected with these parameters.',
'listusers' => 'User list',
'listusers-summary' => '', # do not translate or duplicate this message to other languages
'listusers-editsonly' => 'Show only users with edits',
@@ -2878,73 +2834,6 @@ changed back to last revision by $2.',
this action has been canceled as a precaution against session hijacking.
Go back to the previous page, reload that page and then try again.',
-# Protect
-'protectlogpage' => 'Protection log',
-'protectlogtext' => 'Below is a list of changes to page protections.
-See the [[Special:ProtectedPages|protected pages list]] for the list of currently operational page protections.',
-'protectedarticle' => 'protected "[[$1]]"',
-'modifiedarticleprotection' => 'changed protection level for "[[$1]]"',
-'unprotectedarticle' => 'removed protection from "[[$1]]"',
-'movedarticleprotection' => 'moved protection settings from "[[$2]]" to "[[$1]]"',
-'protect-title' => 'Change protection level for "$1"',
-'protect-title-notallowed' => 'View protection level of "$1"',
-'prot_1movedto2' => '[[$1]] moved to [[$2]]',
-'protect-badnamespace-title' => 'Non-protectable namespace',
-'protect-badnamespace-text' => 'Pages in this namespace cannot be protected.',
-'protect-legend' => 'Confirm protection',
-'protectcomment' => 'Reason:',
-'protectexpiry' => 'Expires:',
-'protect_expiry_invalid' => 'Expiry time is invalid.',
-'protect_expiry_old' => 'Expiry time is in the past.',
-'protect-unchain-permissions' => 'Unlock further protect options',
-'protect-text' => "Here you may view and change the protection level for the page '''$1'''.",
-'protect-locked-blocked' => "You cannot change protection levels while blocked.
-Here are the current settings for the page '''$1''':",
-'protect-locked-dblock' => "Protection levels cannot be changed due to an active database lock.
-Here are the current settings for the page '''$1''':",
-'protect-locked-access' => "Your account does not have permission to change page protection levels.
-Here are the current settings for the page '''$1''':",
-'protect-cascadeon' => "This page is currently protected because it is included in the following {{PLURAL:$1|page, which has|pages, which have}} cascading protection turned on.
-You can change this page's protection level, but it will not affect the cascading protection.",
-'protect-default' => 'Allow all users',
-'protect-fallback' => 'Require "$1" permission',
-'protect-level-autoconfirmed' => 'Block new and unregistered users',
-'protect-level-sysop' => 'Administrators only',
-'protect-summary-cascade' => 'cascading',
-'protect-expiring' => 'expires $1 (UTC)',
-'protect-expiring-local' => 'expires $1',
-'protect-expiry-indefinite' => 'indefinite',
-'protect-cascade' => 'Protect pages included in this page (cascading protection)',
-'protect-cantedit' => 'You cannot change the protection levels of this page, because you do not have permission to edit it.',
-'protect-othertime' => 'Other time:',
-'protect-othertime-op' => 'other time',
-'protect-existing-expiry' => 'Existing expiry time: $3, $2',
-'protect-otherreason' => 'Other/additional reason:',
-'protect-otherreason-op' => 'Other reason',
-'protect-dropdown' => '*Common protection reasons
-** Excessive vandalism
-** Excessive spamming
-** Counter-productive edit warring
-** High traffic page',
-'protect-edit-reasonlist' => 'Edit protection reasons',
-'protect-expiry-options' => '1 hour:1 hour,1 day:1 day,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite',
-'restriction-type' => 'Permission:',
-'restriction-level' => 'Restriction level:',
-'minimum-size' => 'Min size',
-'maximum-size' => 'Max size:',
-'pagesize' => '(bytes)',
-
-# Restrictions (nouns)
-'restriction-edit' => 'Edit',
-'restriction-move' => 'Move',
-'restriction-create' => 'Create',
-'restriction-upload' => 'Upload',
-
-# Restriction levels
-'restriction-level-sysop' => 'fully protected',
-'restriction-level-autoconfirmed' => 'semi protected',
-'restriction-level-all' => 'any level',
-
# Undelete
'undelete' => 'View deleted pages',
'undeletepage' => 'View and restore deleted pages',
@@ -3262,7 +3151,6 @@ In those cases, you will have to move or merge the page manually if desired.",
'movepage-moved-noredirect' => 'The creation of a redirect has been suppressed.',
'articleexists' => 'A page of that name already exists, or the name you have chosen is not valid.
Please choose another name.',
-'cantmove-titleprotected' => 'You cannot move a page to this location, because the new title has been protected from creation',
'talkexists' => "'''The page itself was moved successfully, but the talk page could not be moved because one already exists at the new title.
Please merge them manually.'''",
'movedto' => 'moved to',
@@ -3299,10 +3187,6 @@ cannot move a page over itself.',
'imageinvalidfilename' => 'The target filename is invalid',
'fix-double-redirects' => 'Update any redirects that point to the original title',
'move-leave-redirect' => 'Leave a redirect behind',
-'protectedpagemovewarning' => "'''Warning:''' This page has been protected so that only users with administrator privileges can move it.
-The latest log entry is provided below for reference:",
-'semiprotectedpagemovewarning' => "'''Note:''' This page has been protected so that only registered users can move it.
-The latest log entry is provided below for reference:",
'move-over-sharedrepo' => '== File exists ==
[[:$1]] exists on a shared repository. Moving a file to this title will override the shared file.',
'file-exists-sharedrepo' => 'The filename chosen is already in use on a shared repository.
@@ -3446,8 +3330,6 @@ Please try again.',
'accesskey-ca-addsection' => '+', # do not translate or duplicate this message to other languages
'accesskey-ca-viewsource' => 'e', # do not translate or duplicate this message to other languages
'accesskey-ca-history' => 'h', # do not translate or duplicate this message to other languages
-'accesskey-ca-protect' => '=', # do not translate or duplicate this message to other languages
-'accesskey-ca-unprotect' => '=', # do not translate or duplicate this message to other languages
'accesskey-ca-delete' => 'd', # do not translate or duplicate this message to other languages
'accesskey-ca-undelete' => 'd', # do not translate or duplicate this message to other languages
'accesskey-ca-move' => 'm', # do not translate or duplicate this message to other languages
@@ -3514,11 +3396,7 @@ Please try again.',
'tooltip-ca-talk' => 'Discussion about the content page',
'tooltip-ca-edit' => 'You can edit this page. Please use the preview button before saving',
'tooltip-ca-addsection' => 'Start a new section',
-'tooltip-ca-viewsource' => 'This page is protected.
-You can view its source',
'tooltip-ca-history' => 'Past revisions of this page',
-'tooltip-ca-protect' => 'Protect this page',
-'tooltip-ca-unprotect' => 'Change protection of this page',
'tooltip-ca-delete' => 'Delete this page',
'tooltip-ca-undelete' => 'Restore the edits done to this page before it was deleted',
'tooltip-ca-move' => 'Move this page',
diff --git a/maintenance/ibm_db2/foreignkeys.sql b/maintenance/ibm_db2/foreignkeys.sql
index 4f1450d9b629..95bc582509af 100644
--- a/maintenance/ibm_db2/foreignkeys.sql
+++ b/maintenance/ibm_db2/foreignkeys.sql
@@ -94,9 +94,5 @@ ALTER TABLE watchlist ADD CONSTRAINT WATCHLIST_USER_FK FOREIGN KEY (wl_user) REF
;
-- cannot contain null values
--- ALTER TABLE protected_titles ADD CONSTRAINT PROTECTED_TITLES_USER_FK FOREIGN KEY (pt_user) REFERENCES user(user_id) ON DELETE SET NULL
---;
-
--- cannot contain null values
-- ALTER TABLE logging ADD CONSTRAINT LOGGING_USER_FK FOREIGN KEY (log_user) REFERENCES user(user_id) ON DELETE SET NULL
---; \ No newline at end of file
+--;
diff --git a/maintenance/ibm_db2/tables.sql b/maintenance/ibm_db2/tables.sql
index 66fc6564d946..c057ebc86b02 100644
--- a/maintenance/ibm_db2/tables.sql
+++ b/maintenance/ibm_db2/tables.sql
@@ -689,21 +689,6 @@ CREATE UNIQUE INDEX pf_name_server
-CREATE TABLE protected_titles (
- pt_namespace INTEGER NOT NULL,
- pt_title VARCHAR(255) NOT NULL,
- pt_user BIGINT NOT NULL DEFAULT 0,
- -- REFERENCES user(user_id) ON DELETE SET NULL,
- pt_reason VARCHAR(1024),
- pt_timestamp TIMESTAMP(3) NOT NULL,
- pt_expiry TIMESTAMP(3),
- pt_create_perm VARCHAR(60) NOT NULL DEFAULT ''
-);
-CREATE UNIQUE INDEX protected_titles_unique
- ON protected_titles (pt_namespace, pt_title);
-
-
-
CREATE TABLE updatelog (
ul_key VARCHAR(255) NOT NULL
PRIMARY KEY
diff --git a/maintenance/importImages.php b/maintenance/importImages.php
index bd077ff959f1..01308816089e 100644
--- a/maintenance/importImages.php
+++ b/maintenance/importImages.php
@@ -46,15 +46,6 @@ if ( count( $args ) == 0 ) {
$dir = $args[0];
-# Check Protection
-if ( isset( $options['protect'] ) && isset( $options['unprotect'] ) ) {
- die( "Cannot specify both protect and unprotect. Only 1 is allowed.\n" );
-}
-
-if ( isset( $options['protect'] ) && $options['protect'] == 1 ) {
- die( "You must specify a protection option.\n" );
-}
-
# Prepare the list of allowed extensions
global $wgFileExtensions;
$extensions = isset( $options['extensions'] )
@@ -237,40 +228,12 @@ if ( $count > 0 ) {
# We're done!
echo( "done.\n" );
- $doProtect = false;
-
- global $wgRestrictionLevels;
-
- $protectLevel = isset( $options['protect'] ) ? $options['protect'] : null;
-
- if ( $protectLevel && in_array( $protectLevel, $wgRestrictionLevels ) ) {
- $doProtect = true;
- }
- if ( isset( $options['unprotect'] ) ) {
- $protectLevel = '';
- $doProtect = true;
- }
-
- if ( $doProtect ) {
- # Protect the file
- echo "\nWaiting for slaves...\n";
- // Wait for slaves.
- sleep( 2.0 ); # Why this sleep?
- wfWaitForSlaves();
-
- echo( "\nSetting image restrictions ... " );
-
- $cascade = false;
- $restrictions = array();
- foreach( $title->getRestrictionTypes() as $type ) {
- $restrictions[$type] = $protectLevel;
- }
-
- $page = WikiPage::factory( $title );
- $status = $page->doUpdateRestrictions( $restrictions, array(), $cascade, '', $user );
- echo( ( $status->isOK() ? 'done' : 'failed' ) . "\n" );
- }
-
+ wfRunHooks( 'UpdateRestrictions', array(
+ 'file' => $image,
+ 'protect' => $options['protect'],
+ 'unprotect' => $options['unprotect'],
+ 'echo' => true,
+ ) );
} else {
echo( "failed. (at recordUpload stage)\n" );
$svar = 'failed';
@@ -330,8 +293,6 @@ Options:
but the extension <ext>. If a global comment is also given, it is appended.
--license=<code> Use an optional license template
--dry Dry run, don't import anything
---protect=<protect> Specify the protect value (autoconfirmed,sysop)
---unprotect Unprotects all uploaded images
--source-wiki-url if specified, take User and Comment data for each imported file from this URL.
For example, --source-wiki-url="http://en.wikipedia.org/"
diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc
index bee5a67ca22f..49d6bb2337a8 100644
--- a/maintenance/language/messages.inc
+++ b/maintenance/language/messages.inc
@@ -191,9 +191,7 @@ $wgMessageStructure = array(
'vector-action-addsection',
'vector-action-delete',
'vector-action-move',
- 'vector-action-protect',
'vector-action-undelete',
- 'vector-action-unprotect',
'vector-simplesearch-preference',
'vector-view-create',
'vector-view-edit',
@@ -228,11 +226,6 @@ $wgMessageStructure = array(
'deletethispage',
'undelete_short',
'viewdeleted_short',
- 'protect',
- 'protect_change',
- 'protectthispage',
- 'unprotect',
- 'unprotectthispage',
'newpage',
'talkpage',
'talkpagelinktext',
@@ -258,7 +251,6 @@ $wgMessageStructure = array(
'talkpageheader',
'lastmodifiedat',
'viewcount',
- 'protectedpage',
'jumpto',
'jumptonavigation',
'jumptosearch',
@@ -397,18 +389,10 @@ $wgMessageStructure = array(
'viewsource-title',
'actionthrottled',
'actionthrottledtext',
- 'protectedpagetext',
'viewsourcetext',
'viewyourtext',
- 'protectedinterface',
'editinginterface',
'sqlhidden',
- 'cascadeprotected',
- 'namespaceprotected',
- 'customcssprotected',
- 'customjsprotected',
- 'ns-specialprotected',
- 'titleprotected',
),
'virus' => array(
'virus-badscanner',
@@ -641,15 +625,9 @@ $wgMessageStructure = array(
'longpage-hint',
'longpageerror',
'readonlywarning',
- 'protectedpagewarning',
- 'semiprotectedpagewarning',
- 'cascadeprotectedwarning',
- 'titleprotectedwarning',
'templatesused',
'templatesusedpreview',
'templatesusedsection',
- 'template-protected',
- 'template-semiprotected',
'hiddencategories',
'edittools',
'edittools-upload',
@@ -1125,8 +1103,6 @@ $wgMessageStructure = array(
'right-ipblock-exempt',
'right-proxyunbannable',
'right-unblockself',
- 'right-protect',
- 'right-editprotected',
'right-editinterface',
'right-editusercssjs',
'right-editusercss',
@@ -1179,7 +1155,6 @@ $wgMessageStructure = array(
'action-suppressrevision',
'action-suppressionlog',
'action-block',
- 'action-protect',
'action-rollback',
'action-import',
'action-importupload',
@@ -1663,16 +1638,6 @@ $wgMessageStructure = array(
'deadendpages',
'deadendpages-summary',
'deadendpagestext',
- 'protectedpages',
- 'protectedpages-indef',
- 'protectedpages-summary',
- 'protectedpages-cascade',
- 'protectedpagestext',
- 'protectedpagesempty',
- 'protectedtitles',
- 'protectedtitles-summary',
- 'protectedtitlestext',
- 'protectedtitlesempty',
'listusers',
'listusers-summary',
'listusers-editsonly',
@@ -1925,64 +1890,6 @@ $wgMessageStructure = array(
'sessionfailure-title',
'sessionfailure',
),
- 'protect' => array(
- 'protectlogpage',
- 'protectlogtext',
- 'protectedarticle',
- 'modifiedarticleprotection',
- 'unprotectedarticle',
- 'movedarticleprotection',
- 'protect-title',
- 'protect-title-notallowed',
- 'prot_1movedto2',
- 'protect-badnamespace-title',
- 'protect-badnamespace-text',
- 'protect-legend',
- 'protectcomment',
- 'protectexpiry',
- 'protect_expiry_invalid',
- 'protect_expiry_old',
- 'protect-unchain-permissions',
- 'protect-text',
- 'protect-locked-blocked',
- 'protect-locked-dblock',
- 'protect-locked-access',
- 'protect-cascadeon',
- 'protect-default',
- 'protect-fallback',
- 'protect-level-autoconfirmed',
- 'protect-level-sysop',
- 'protect-summary-cascade',
- 'protect-expiring',
- 'protect-expiring-local',
- 'protect-expiry-indefinite',
- 'protect-cascade',
- 'protect-cantedit',
- 'protect-othertime',
- 'protect-othertime-op',
- 'protect-existing-expiry',
- 'protect-otherreason',
- 'protect-otherreason-op',
- 'protect-dropdown',
- 'protect-edit-reasonlist',
- 'protect-expiry-options',
- 'restriction-type',
- 'restriction-level',
- 'minimum-size',
- 'maximum-size',
- 'pagesize',
- ),
- 'restrictions' => array(
- 'restriction-edit',
- 'restriction-move',
- 'restriction-create',
- 'restriction-upload',
- ),
- 'restriction-levels' => array(
- 'restriction-level-sysop',
- 'restriction-level-autoconfirmed',
- 'restriction-level-all',
- ),
'undelete' => array(
'undelete',
'undeletepage',
@@ -2238,7 +2145,6 @@ $wgMessageStructure = array(
'movepage-moved-redirect',
'movepage-moved-noredirect',
'articleexists',
- 'cantmove-titleprotected',
'talkexists',
'movedto',
'movetalk',
@@ -2272,8 +2178,6 @@ $wgMessageStructure = array(
'imageinvalidfilename',
'fix-double-redirects',
'move-leave-redirect',
- 'protectedpagemovewarning',
- 'semiprotectedpagemovewarning',
'move-over-sharedrepo',
'file-exists-sharedrepo',
),
@@ -2401,8 +2305,6 @@ $wgMessageStructure = array(
'accesskey-ca-addsection',
'accesskey-ca-viewsource',
'accesskey-ca-history',
- 'accesskey-ca-protect',
- 'accesskey-ca-unprotect',
'accesskey-ca-delete',
'accesskey-ca-undelete',
'accesskey-ca-move',
@@ -2472,8 +2374,6 @@ $wgMessageStructure = array(
'tooltip-ca-addsection',
'tooltip-ca-viewsource',
'tooltip-ca-history',
- 'tooltip-ca-protect',
- 'tooltip-ca-unprotect',
'tooltip-ca-delete',
'tooltip-ca-undelete',
'tooltip-ca-move',
@@ -3738,9 +3638,6 @@ XHTML id names.",
'delete' => 'Delete',
'rollback' => 'Rollback',
'edittokens' => 'Edit tokens',
- 'protect' => 'Protect',
- 'restrictions' => 'Restrictions (nouns)',
- 'restriction-levels' => 'Restriction levels',
'undelete' => 'Undelete',
'nsform' => 'Namespace form on various pages',
'contributions' => 'Contributions',
diff --git a/maintenance/mssql/tables.sql b/maintenance/mssql/tables.sql
index 8c4d500876a3..f22e5de6b595 100644
--- a/maintenance/mssql/tables.sql
+++ b/maintenance/mssql/tables.sql
@@ -699,20 +699,6 @@ CREATE INDEX /*$wgDBprefix*/pr_pagelevel ON /*$wgDBprefix*/page_restrictions(pr_
CREATE INDEX /*$wgDBprefix*/pr_cascade ON /*$wgDBprefix*/page_restrictions(pr_cascade);
;
--- Protected titles - nonexistent pages that have been protected
-CREATE TABLE /*$wgDBprefix*/protected_titles (
- pt_namespace int NOT NULL,
- pt_title NVARCHAR(255) NOT NULL,
- pt_user int NOT NULL,
- pt_reason NVARCHAR(3555),
- pt_timestamp DATETIME NOT NULL,
- pt_expiry DATETIME NOT NULL default '',
- pt_create_perm NVARCHAR(60) NOT NULL,
- PRIMARY KEY (pt_namespace,pt_title),
-);
-CREATE INDEX /*$wgDBprefix*/pt_timestamp ON /*$wgDBprefix*/protected_titles(pt_timestamp);
-;
-
-- Name/value pairs indexed by page_id
CREATE TABLE /*$wgDBprefix*/page_props (
pp_page int NOT NULL,
diff --git a/maintenance/oracle/tables.sql b/maintenance/oracle/tables.sql
index 8c0ca30e3bf2..208e226a226d 100644
--- a/maintenance/oracle/tables.sql
+++ b/maintenance/oracle/tables.sql
@@ -571,17 +571,6 @@ CREATE INDEX &mw_prefix.page_restrictions_i01 ON &mw_prefix.page_restrictions (p
CREATE INDEX &mw_prefix.page_restrictions_i02 ON &mw_prefix.page_restrictions (pr_level);
CREATE INDEX &mw_prefix.page_restrictions_i03 ON &mw_prefix.page_restrictions (pr_cascade);
-CREATE TABLE &mw_prefix.protected_titles (
- pt_namespace NUMBER DEFAULT 0 NOT NULL,
- pt_title VARCHAR2(255) NOT NULL,
- pt_user NUMBER NOT NULL,
- pt_reason VARCHAR2(255),
- pt_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL,
- pt_expiry VARCHAR2(14) NOT NULL,
- pt_create_perm VARCHAR2(60) NOT NULL
-);
-CREATE UNIQUE INDEX &mw_prefix.protected_titles_u01 ON &mw_prefix.protected_titles (pt_namespace,pt_title);
-CREATE INDEX &mw_prefix.protected_titles_i01 ON &mw_prefix.protected_titles (pt_timestamp);
CREATE TABLE &mw_prefix.page_props (
pp_page NUMBER NOT NULL,
diff --git a/maintenance/postgres/tables.sql b/maintenance/postgres/tables.sql
index 6890df918f55..2a8f3799d5b9 100644
--- a/maintenance/postgres/tables.sql
+++ b/maintenance/postgres/tables.sql
@@ -584,17 +584,6 @@ CREATE TABLE profiling (
);
CREATE UNIQUE INDEX pf_name_server ON profiling (pf_name, pf_server);
-CREATE TABLE protected_titles (
- pt_namespace SMALLINT NOT NULL,
- pt_title TEXT NOT NULL,
- pt_user INTEGER NULL REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
- pt_reason TEXT NULL,
- pt_timestamp TIMESTAMPTZ NOT NULL,
- pt_expiry TIMESTAMPTZ NULL,
- pt_create_perm TEXT NOT NULL DEFAULT ''
-);
-CREATE UNIQUE INDEX protected_titles_unique ON protected_titles(pt_namespace, pt_title);
-
CREATE TABLE updatelog (
ul_key TEXT NOT NULL PRIMARY KEY,
diff --git a/maintenance/protect.php b/maintenance/protect.php
deleted file mode 100644
index 56958ea77ec1..000000000000
--- a/maintenance/protect.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-/**
- * Protect or unprotect an article.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @ingroup Maintenance
- */
-
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
-
-class Protect extends Maintenance {
- public function __construct() {
- parent::__construct();
- $this->mDescription = "Protect or unprotect an article from the command line.";
- $this->addOption( 'unprotect', 'Removes protection' );
- $this->addOption( 'semiprotect', 'Adds semi-protection' );
- $this->addOption( 'cascade', 'Add cascading protection' );
- $this->addOption( 'user', 'Username to protect with', false, true, 'u' );
- $this->addOption( 'reason', 'Reason for un/protection', false, true, 'r' );
- $this->addArg( 'title', 'Title to protect', true );
- }
-
- public function execute() {
- global $wgUser;
-
- $userName = $this->getOption( 'u', 'Maintenance script' );
- $reason = $this->getOption( 'r', '' );
-
- $cascade = $this->hasOption( 'cascade' );
-
- $protection = "sysop";
- if ( $this->hasOption( 'semiprotect' ) ) {
- $protection = "autoconfirmed";
- } elseif ( $this->hasOption( 'unprotect' ) ) {
- $protection = "";
- }
-
- $user = User::newFromName( $userName );
- if ( !$user ) {
- $this->error( "Invalid username", true );
- }
-
- $restrictions = array( 'edit' => $protection, 'move' => $protection );
-
- $t = Title::newFromText( $this->getArg() );
- if ( !$t ) {
- $this->error( "Invalid title", true );
- }
-
- $restrictions = array();
- foreach( $t->getRestrictionTypes() as $type ) {
- $restrictions[$type] = $protection;
- }
-
- # un/protect the article
- $this->output( "Updating protection status... " );
-
- $page = WikiPage::factory( $t );
- $status = $page->doUpdateRestrictions( $restrictions, array(), $cascade, $reason, $user );
-
- if ( $status->isOK() ) {
- $this->output( "done\n" );
- } else {
- $this->output( "failed\n" );
- }
- }
-}
-
-$maintClass = "Protect";
-require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/maintenance/tables.sql b/maintenance/tables.sql
index db89c37e67dc..105071141f4d 100644
--- a/maintenance/tables.sql
+++ b/maintenance/tables.sql
@@ -1353,21 +1353,6 @@ CREATE INDEX /*i*/pr_level ON /*_*/page_restrictions (pr_level);
CREATE INDEX /*i*/pr_cascade ON /*_*/page_restrictions (pr_cascade);
--- Protected titles - nonexistent pages that have been protected
-CREATE TABLE /*_*/protected_titles (
- pt_namespace int NOT NULL,
- pt_title varchar(255) binary NOT NULL,
- pt_user int unsigned NOT NULL,
- pt_reason tinyblob,
- pt_timestamp binary(14) NOT NULL,
- pt_expiry varbinary(14) NOT NULL default '',
- pt_create_perm varbinary(60) NOT NULL
-) /*$wgDBTableOptions*/;
-
-CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title);
-CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
-
-
-- Name/value pairs indexed by page_id
CREATE TABLE /*_*/page_props (
pp_page int NOT NULL,
diff --git a/maintenance/updateRestrictions.php b/maintenance/updateRestrictions.php
deleted file mode 100644
index ffbdb2baaac8..000000000000
--- a/maintenance/updateRestrictions.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-/**
- * Makes the required database updates for Special:ProtectedPages
- * to show all protected pages, even ones before the page restrictions
- * schema change. All remaining page_restriction column values are moved
- * to the new table.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Maintenance
- */
-
-require_once( dirname( __FILE__ ) . '/Maintenance.php' );
-
-class UpdateRestrictions extends Maintenance {
- public function __construct() {
- parent::__construct();
- $this->mDescription = "Updates page_restrictions table from old page_restriction column";
- $this->setBatchSize( 100 );
- }
-
- public function execute() {
- $db = wfGetDB( DB_MASTER );
- if ( !$db->tableExists( 'page_restrictions' ) ) {
- $this->error( "page_restrictions table does not exist", true );
- }
-
- $start = $db->selectField( 'page', 'MIN(page_id)', false, __METHOD__ );
- if ( !$start ) {
- $this->error( "Nothing to do.", true );
- }
- $end = $db->selectField( 'page', 'MAX(page_id)', false, __METHOD__ );
-
- # Do remaining chunk
- $end += $this->mBatchSize - 1;
- $blockStart = $start;
- $blockEnd = $start + $this->mBatchSize - 1;
- $encodedExpiry = 'infinity';
- while ( $blockEnd <= $end ) {
- $this->output( "...doing page_id from $blockStart to $blockEnd\n" );
- $cond = "page_id BETWEEN $blockStart AND $blockEnd AND page_restrictions !=''";
- $res = $db->select( 'page', array( 'page_id', 'page_namespace', 'page_restrictions' ), $cond, __METHOD__ );
- $batch = array();
- foreach ( $res as $row ) {
- $oldRestrictions = array();
- foreach ( explode( ':', trim( $row->page_restrictions ) ) as $restrict ) {
- $temp = explode( '=', trim( $restrict ) );
- // Make sure we are not settings restrictions to ""
- if ( count( $temp ) == 1 && $temp[0] ) {
- // old old format should be treated as edit/move restriction
- $oldRestrictions["edit"] = trim( $temp[0] );
- $oldRestrictions["move"] = trim( $temp[0] );
- } elseif ( $temp[1] ) {
- $oldRestrictions[$temp[0]] = trim( $temp[1] );
- }
- }
- # Clear invalid columns
- if ( $row->page_namespace == NS_MEDIAWIKI ) {
- $db->update( 'page', array( 'page_restrictions' => '' ),
- array( 'page_id' => $row->page_id ), __FUNCTION__ );
- $this->output( "...removed dead page_restrictions column for page {$row->page_id}\n" );
- }
- # Update restrictions table
- foreach ( $oldRestrictions as $action => $restrictions ) {
- $batch[] = array(
- 'pr_page' => $row->page_id,
- 'pr_type' => $action,
- 'pr_level' => $restrictions,
- 'pr_cascade' => 0,
- 'pr_expiry' => $encodedExpiry
- );
- }
- }
- # We use insert() and not replace() as Article.php replaces
- # page_restrictions with '' when protected in the restrictions table
- if ( count( $batch ) ) {
- $ok = $db->deadlockLoop( array( $db, 'insert' ), 'page_restrictions',
- $batch, __FUNCTION__, array( 'IGNORE' ) );
- if ( !$ok ) {
- throw new MWException( "Deadlock loop failed wtf :(" );
- }
- }
- $blockStart += $this->mBatchSize - 1;
- $blockEnd += $this->mBatchSize - 1;
- wfWaitForSlaves();
- }
- $this->output( "...removing dead rows from page_restrictions\n" );
- // Kill any broken rows from previous imports
- $db->delete( 'page_restrictions', array( 'pr_level' => '' ) );
- // Kill other invalid rows
- $db->deleteJoin( 'page_restrictions', 'page', 'pr_page', 'page_id', array( 'page_namespace' => NS_MEDIAWIKI ) );
- $this->output( "...Done!\n" );
- }
-}
-
-$maintClass = "UpdateRestrictions";
-require_once( RUN_MAINTENANCE_IF_MAIN );
diff --git a/resources/Resources.php b/resources/Resources.php
index 453f335bb129..fa97912dd6b9 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -868,16 +868,6 @@ return array(
'localBasePath' => $GLOBALS['wgStyleDirectory'],
'dependencies' => 'mediawiki.legacy.wikibits',
),
- 'mediawiki.legacy.protect' => array(
- 'scripts' => 'common/protect.js',
- 'remoteBasePath' => $GLOBALS['wgStylePath'],
- 'localBasePath' => $GLOBALS['wgStyleDirectory'],
- 'dependencies' => array(
- 'mediawiki.legacy.wikibits',
- 'jquery.byteLimit',
- ),
- 'position' => 'top',
- ),
'mediawiki.legacy.shared' => array(
'styles' => array( 'common/shared.css' => array( 'media' => 'screen' ) ),
'remoteBasePath' => $GLOBALS['wgStylePath'],
diff --git a/skins/CologneBlue.php b/skins/CologneBlue.php
index c5b3b11d38b8..0de384855b23 100644
--- a/skins/CologneBlue.php
+++ b/skins/CologneBlue.php
@@ -255,12 +255,6 @@ class CologneBlueTemplate extends LegacyTemplate {
$s .= $sep . $dtp;
}
}
- if ( $user->isAllowed( 'protect' ) ) {
- $ptp = $this->protectThisPage();
- if ( $ptp != '' ) {
- $s .= $sep . $ptp;
- }
- }
$s .= $sep;
$s .= $this->menuHead( 'qbpageoptions' );
diff --git a/skins/Standard.php b/skins/Standard.php
index bd0c41a5c036..84d14b0c52d2 100644
--- a/skins/Standard.php
+++ b/skins/Standard.php
@@ -228,8 +228,7 @@ class StandardTemplate extends LegacyTemplate {
$s .= $sep . $this->moveThisPage();
}
if ( $this->getSkin()->getUser()->isAllowed( 'delete' ) && $articleExists ) {
- $s .= $sep . $this->deleteThisPage() .
- $sep . $this->protectThisPage();
+ $s .= $sep . $this->deleteThisPage();
}
$s .= $sep . $this->talkLink();
if( $articleExists && $action != 'history' ) {
diff --git a/skins/common/protect.js b/skins/common/protect.js
deleted file mode 100644
index a23c0cbd8a27..000000000000
--- a/skins/common/protect.js
+++ /dev/null
@@ -1,357 +0,0 @@
-
-window.ProtectionForm = {
- 'existingMatch': false,
-
- /**
- * Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
- * on the protection form
- *
- * @param opts Object : parameters with members:
- * tableId Identifier of the table containing UI bits
- * labelText Text to use for the checkbox label
- * numTypes The number of protection types
- * existingMatch True if all the existing expiry times match
- */
- 'init': function( opts ) {
- if( !( document.createTextNode && document.getElementById && document.getElementsByTagName ) )
- return false;
-
- var box = document.getElementById( opts.tableId );
- if( !box )
- return false;
-
- var boxbody = box.getElementsByTagName('tbody')[0];
- var row = document.createElement( 'tr' );
- boxbody.insertBefore( row, boxbody.firstChild.nextSibling );
-
- this.existingMatch = opts.existingMatch;
-
- var cell = document.createElement( 'td' );
- row.appendChild( cell );
- // If there is only one protection type, there is nothing to chain
- if( opts.numTypes > 1 ) {
- var check = document.createElement( 'input' );
- check.id = 'mwProtectUnchained';
- check.type = 'checkbox';
- cell.appendChild( check );
- addClickHandler( check, function() { ProtectionForm.onChainClick(); } );
-
- cell.appendChild( document.createTextNode( ' ' ) );
- var label = document.createElement( 'label' );
- label.htmlFor = 'mwProtectUnchained';
- label.appendChild( document.createTextNode( opts.labelText ) );
- cell.appendChild( label );
-
- check.checked = !this.areAllTypesMatching();
- this.enableUnchainedInputs( check.checked );
- }
-
- $( '#mwProtect-reason' ).byteLimit( 180 );
-
- this.updateCascadeCheckbox();
-
- return true;
- },
-
- /**
- * Sets the disabled attribute on the cascade checkbox depending on the current selected levels
- */
- 'updateCascadeCheckbox': function() {
- // For non-existent titles, there is no cascade option
- if( !document.getElementById( 'mwProtect-cascade' ) ) {
- return;
- }
- var lists = this.getLevelSelectors();
- for( var i = 0; i < lists.length; i++ ) {
- if( lists[i].selectedIndex > -1 ) {
- var items = lists[i].getElementsByTagName( 'option' );
- var selected = items[ lists[i].selectedIndex ].value;
- if( !this.isCascadeableLevel(selected) ) {
- document.getElementById( 'mwProtect-cascade' ).checked = false;
- document.getElementById( 'mwProtect-cascade' ).disabled = true;
- return;
- }
- }
- }
- document.getElementById( 'mwProtect-cascade' ).disabled = false;
- },
-
- /**
- * Checks if a cerain protection level is cascadeable.
- * @param level {String}
- * @return {Boolean}
- */
- 'isCascadeableLevel': function( level ) {
- var cascadeLevels, len, i;
-
- cascadeLevels = mw.config.get( 'wgCascadeableLevels' );
- // cascadeLevels isn't defined on all pages
- if ( cascadeLevels ) {
- for ( i = 0, len = cascadeLevels.length; i < len; i += 1 ) {
- if ( cascadeLevels[i] === level ) {
- return true;
- }
- }
- }
- return false;
- },
-
- /**
- * When protection levels are locked together, update the rest
- * when one action's level changes
- *
- * @param source Element Level selector that changed
- */
- 'updateLevels': function(source) {
- if( !this.isUnchained() )
- this.setAllSelectors( source.selectedIndex );
- this.updateCascadeCheckbox();
- },
-
- /**
- * When protection levels are locked together, update the
- * expiries when one changes
- *
- * @param source Element expiry input that changed
- */
-
- 'updateExpiry': function(source) {
- if( !this.isUnchained() ) {
- var expiry = source.value;
- this.forEachExpiryInput(function(element) {
- element.value = expiry;
- });
- }
- var listId = source.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' );
- var list = document.getElementById( listId );
- if (list && list.value != 'othertime' ) {
- if ( this.isUnchained() ) {
- list.value = 'othertime';
- } else {
- this.forEachExpirySelector(function(element) {
- element.value = 'othertime';
- });
- }
- }
- },
-
- /**
- * When protection levels are locked together, update the
- * expiry lists when one changes and clear the custom inputs
- *
- * @param source Element expiry selector that changed
- */
- 'updateExpiryList': function(source) {
- if( !this.isUnchained() ) {
- var expiry = source.value;
- this.forEachExpirySelector(function(element) {
- element.value = expiry;
- });
- this.forEachExpiryInput(function(element) {
- element.value = '';
- });
- }
- },
-
- /**
- * Update chain status and enable/disable various bits of the UI
- * when the user changes the "unlock move permissions" checkbox
- */
- 'onChainClick': function() {
- if( this.isUnchained() ) {
- this.enableUnchainedInputs( true );
- } else {
- this.setAllSelectors( this.getMaxLevel() );
- this.enableUnchainedInputs( false );
- }
- this.updateCascadeCheckbox();
- },
-
- /**
- * Returns true if the named attribute in all objects in the given array are matching
- */
- 'matchAttribute' : function( objects, attrName ) {
- var value = null;
-
- // Check levels
- for ( var i = 0; i < objects.length; i++ ) {
- var element = objects[i];
- if ( value == null ) {
- value = element[attrName];
- } else {
- if ( value != element[attrName] ) {
- return false;
- }
- }
- }
- return true;
- },
-
- /**
- * Are all actions protected at the same level, with the same expiry time?
- *
- * @return boolean
- */
- 'areAllTypesMatching': function() {
- return this.existingMatch
- && this.matchAttribute( this.getLevelSelectors(), 'selectedIndex' )
- && this.matchAttribute( this.getExpirySelectors(), 'selectedIndex' )
- && this.matchAttribute( this.getExpiryInputs(), 'value' );
- },
-
- /**
- * Is protection chaining off?
- *
- * @return bool
- */
- 'isUnchained': function() {
- var element = document.getElementById( 'mwProtectUnchained' );
- return element
- ? element.checked
- : true; // No control, so we need to let the user set both levels
- },
-
- /**
- * Find the highest protection level in any selector
- */
- 'getMaxLevel': function() {
- var maxIndex = -1;
- this.forEachLevelSelector(function(element) {
- if (element.selectedIndex > maxIndex) {
- maxIndex = element.selectedIndex;
- }
- });
- return maxIndex;
- },
-
- /**
- * Protect all actions at the specified level
- *
- * @param index int Protection level
- */
- 'setAllSelectors': function(index) {
- this.forEachLevelSelector(function(element) {
- if (element.selectedIndex != index) {
- element.selectedIndex = index;
- }
- });
- },
-
- /**
- * Apply a callback to each protection selector
- *
- * @param func callable Callback function
- */
- 'forEachLevelSelector': function(func) {
- var selectors = this.getLevelSelectors();
- for (var i = 0; i < selectors.length; i++) {
- func(selectors[i]);
- }
- },
-
- /**
- * Get a list of all protection selectors on the page
- *
- * @return Array
- */
- 'getLevelSelectors': function() {
- var all = document.getElementsByTagName("select");
- var ours = [];
- for (var i = 0; i < all.length; i++) {
- var element = all[i];
- if (element.id.match(/^mwProtect-level-/)) {
- ours[ours.length] = element;
- }
- }
- return ours;
- },
-
- /**
- * Apply a callback to each expiry input
- *
- * @param func callable Callback function
- */
- 'forEachExpiryInput': function(func) {
- var inputs = this.getExpiryInputs();
- for (var i = 0; i < inputs.length; i++) {
- func(inputs[i]);
- }
- },
-
- /**
- * Get a list of all expiry inputs on the page
- *
- * @return Array
- */
- 'getExpiryInputs': function() {
- var all = document.getElementsByTagName("input");
- var ours = [];
- for (var i = 0; i < all.length; i++) {
- var element = all[i];
- if (element.name.match(/^mwProtect-expiry-/)) {
- ours[ours.length] = element;
- }
- }
- return ours;
- },
-
- /**
- * Apply a callback to each expiry selector list
- * @param func callable Callback function
- */
- 'forEachExpirySelector': function(func) {
- var inputs = this.getExpirySelectors();
- for (var i = 0; i < inputs.length; i++) {
- func(inputs[i]);
- }
- },
-
- /**
- * Get a list of all expiry selector lists on the page
- *
- * @return Array
- */
- 'getExpirySelectors': function() {
- var all = document.getElementsByTagName("select");
- var ours = [];
- for (var i = 0; i < all.length; i++) {
- var element = all[i];
- if (element.id.match(/^mwProtectExpirySelection-/)) {
- ours[ours.length] = element;
- }
- }
- return ours;
- },
-
- /**
- * Enable/disable protection selectors and expiry inputs
- *
- * @param val boolean Enable?
- */
- 'enableUnchainedInputs': function(val) {
- var first = true;
- this.forEachLevelSelector(function(element) {
- if (first) {
- first = false;
- } else {
- element.disabled = !val;
- }
- });
- first = true;
- this.forEachExpiryInput(function(element) {
- if (first) {
- first = false;
- } else {
- element.disabled = !val;
- }
- });
- first = true;
- this.forEachExpirySelector(function(element) {
- if (first) {
- first = false;
- } else {
- element.disabled = !val;
- }
- });
- }
-};
diff --git a/skins/common/shared.css b/skins/common/shared.css
index 824e36870b2a..87654b7cbf7d 100644
--- a/skins/common/shared.css
+++ b/skins/common/shared.css
@@ -313,9 +313,8 @@ input#wpSummary {
display: none;
}
-/* Convenience links to edit block, delete and protect reasons */
+/* Convenience links to edit block, delete reasons */
p.mw-ipb-conveniencelinks,
-p.mw-protect-editreasons,
p.mw-filedelete-editreasons,
p.mw-delete-editreasons,
p.mw-revdel-editreasons {
@@ -415,7 +414,6 @@ table.os-suggest-results {
/**
* Recreating deleted page warning
* Reupload file warning
- * Page protection warning
* incl. log entries for these warnings
*/
div.mw-warning-with-logexcerpt {