$editingRestriction = 'sitewide';
$pageRestrictions = '';
+ $namespaceRestrictions = '';
if ( $this->getConfig()->get( 'EnablePartialBlocks' ) ) {
if ( $params['partial'] ) {
$editingRestriction = 'partial';
}
$pageRestrictions = implode( "\n", (array)$params['pagerestrictions'] );
+ $namespaceRestrictions = implode( "\n", (array)$params['namespacerestrictions'] );
}
if ( $params['userid'] !== null ) {
'Tags' => $params['tags'],
'EditingRestriction' => $editingRestriction,
'PageRestrictions' => $pageRestrictions,
+ 'NamespaceRestrictions' => $namespaceRestrictions,
];
$retval = SpecialBlock::processForm( $data, $this->getContext() );
if ( $this->getConfig()->get( 'EnablePartialBlocks' ) ) {
$res['partial'] = $params['partial'];
$res['pagerestrictions'] = $params['pagerestrictions'];
+ $res['namespacerestrictions'] = $params['namespacerestrictions'];
}
$this->getResult()->addValue( null, $this->getModuleName(), $res );
ApiBase::PARAM_ISMULTI_LIMIT1 => 10,
ApiBase::PARAM_ISMULTI_LIMIT2 => 10,
];
+ $params['namespacerestrictions'] = [
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_TYPE => 'namespace',
+ ];
}
return $params;
"apihelp-block-param-watchuser": "Watch the user's or IP address's user and talk pages.",
"apihelp-block-param-tags": "Change tags to apply to the entry in the block log.",
"apihelp-block-param-partial": "Block user from specific pages or namespaces rather than the entire site.",
- "apihelp-block-param-pagerestrictions": "List of titles to block the user from editing. Only applies when 'partial' is set to true.",
+ "apihelp-block-param-pagerestrictions": "List of titles to block the user from editing. Only applies when <var>partial</var> is set to true.",
+ "apihelp-block-param-namespacerestrictions": "List of namespace IDs to block the user from editing. Only applies when <var>partial</var> is set to true.",
"apihelp-block-example-ip-simple": "Block IP address <kbd>192.0.2.5</kbd> for three days with reason <kbd>First strike</kbd>.",
"apihelp-block-example-user-complex": "Block user <kbd>Vandal</kbd> indefinitely with reason <kbd>Vandalism</kbd>, and prevent new account creation and email sending.",
"apihelp-block-param-tags": "{{doc-apihelp-param|block|tags}}",
"apihelp-block-param-partial": "{{doc-apihelp-param|block|partial}}",
"apihelp-block-param-pagerestrictions": "{{doc-apihelp-param|block|pagerestrictions}}",
+ "apihelp-block-param-namespacerestrictions": "{{doc-apihelp-param|block|namespacerestrictions}}",
"apihelp-block-example-ip-simple": "{{doc-apihelp-example|block}}",
"apihelp-block-example-user-complex": "{{doc-apihelp-example|block}}",
"apihelp-changeauthenticationdata-summary": "{{doc-apihelp-summary|changeauthenticationdata}}",
use MediaWiki\Block\BlockRestriction;
use MediaWiki\Block\Restriction\PageRestriction;
+use MediaWiki\Block\Restriction\NamespaceRestriction;
/**
* A special page that allows users with 'block' right to block users from
'label' => $this->msg( 'ipb-pages-label' )->text(),
'exists' => true,
'max' => 10,
- 'cssclass' => 'mw-block-page-restrictions',
+ 'cssclass' => 'mw-block-restriction',
'showMissing' => false,
'input' => [
'autocomplete' => false
],
'section' => 'actions',
];
+ $a['NamespaceRestrictions'] = [
+ 'type' => 'namespacesmultiselect',
+ 'label' => $this->msg( 'ipb-namespaces-label' )->text(),
+ 'exists' => true,
+ 'cssclass' => 'mw-block-restriction',
+ 'input' => [
+ 'autocomplete' => false
+ ],
+ 'section' => 'actions',
+ ];
}
$a['CreateAccount'] = [
if ( $block instanceof Block ) {
$pageRestrictions = [];
+ $namespaceRestrictions = [];
foreach ( $block->getRestrictions() as $restriction ) {
- if ( $restriction->getType() !== 'page' ) {
- continue;
+ switch ( $restriction->getType() ) {
+ case PageRestriction::TYPE:
+ $pageRestrictions[] = $restriction->getTitle()->getPrefixedText();
+ break;
+ case NamespaceRestriction::TYPE:
+ $namespaceRestrictions[] = $restriction->getValue();
+ break;
}
-
- $pageRestrictions[] = $restriction->getTitle()->getPrefixedText();
}
- if ( !$block->isSitewide() && empty( $pageRestrictions ) ) {
+ if (
+ !$block->isSitewide() &&
+ empty( $pageRestrictions ) &&
+ empty( $namespaceRestrictions )
+ ) {
$fields['Editing']['default'] = false;
}
// Sort the restrictions so they are in alphabetical order.
sort( $pageRestrictions );
$fields['PageRestrictions']['default'] = implode( "\n", $pageRestrictions );
+ sort( $namespaceRestrictions );
+ $fields['NamespaceRestrictions']['default'] = implode( "\n", $namespaceRestrictions );
}
}
}
return $reason;
}
- $restrictions = [];
+ $pageRestrictions = [];
+ $namespaceRestrictions = [];
if ( $enablePartialBlocks ) {
if ( $data['PageRestrictions'] !== '' ) {
- $restrictions = array_map( function ( $text ) {
+ $pageRestrictions = array_map( function ( $text ) {
$title = Title::newFromText( $text );
// Use the link cache since the title has already been loaded when
// the field was validated.
return $restriction;
}, explode( "\n", $data['PageRestrictions'] ) );
}
+ if ( $data['NamespaceRestrictions'] !== '' ) {
+ $namespaceRestrictions = array_map( function ( $id ) {
+ return new NamespaceRestriction( 0, $id );
+ }, explode( "\n", $data['NamespaceRestrictions'] ) );
+ }
+ $restrictions = ( array_merge( $pageRestrictions, $namespaceRestrictions ) );
$block->setRestrictions( $restrictions );
}
if ( isset( $data['Editing'] ) && $data['Editing'] === false ) {
$data['EditingRestriction'] = 'partial';
$data['PageRestrictions'] = '';
+ $data['NamespaceRestrictions'] = '';
}
return self::processForm( $data, $form->getContext() );
}
"ipb-sitewide": "Sitewide",
"ipb-partial": "Partial",
"ipb-pages-label": "Pages",
+ "ipb-namespaces-label": "Namespaces",
"badipaddress": "Invalid IP address",
"blockipsuccesssub": "Block succeeded",
"blockipsuccesstext": "[[Special:Contributions/$1|$1]] has been blocked.<br />\nSee the [[Special:BlockList|block list]] to review blocks.",
"ipb-sitewide": "A type of block the user can select from on [[Special:Block]].",
"ipb-partial": "A type of block the user can select from on [[Special:Block]].",
"ipb-pages-label": "The label for an autocomplete text field to specify pages to block a user from editing on [[Special:Block]].",
+ "ipb-namespaces-label": "The label for an autocomplete text field to specify namespaces to block a user from editing on [[Special:Block]].",
"badipaddress": "An error message shown when one entered an invalid IP address in blocking page.",
"blockipsuccesssub": "Used as page title in [[Special:Block]].\n\nThis message is the subject for the following message:\n* {{msg-mw|Blockipsuccesstext}}",
"blockipsuccesstext": "Used in [[Special:Block]].\nThe title (subject) for this message is {{msg-mw|Blockipsuccesssub}}.\n\nParameters:\n* $1 - username, can be used for GENDER",
editingWidget = infuseIfExists( $( '#mw-input-wpEditing' ) ),
editingRestrictionWidget = infuseIfExists( $( '#mw-input-wpEditingRestriction' ) ),
preventTalkPageEdit = infuseIfExists( $( '#mw-input-wpDisableUTEdit' ) ),
- pageRestrictionsWidget = infuseIfExists( $( '#mw-input-wpPageRestrictions' ) );
+ pageRestrictionsWidget = infuseIfExists( $( '#mw-input-wpPageRestrictions' ) ),
+ namespaceRestrictionsWidget = infuseIfExists( $( '#mw-input-wpNamespaceRestrictions' ) );
function updateBlockOptions() {
var blocktarget = blockTargetWidget.getValue().trim(),
if ( watchUserField ) {
watchUserField.toggle( !isIpRange || isEmpty );
}
- if ( pageRestrictionsWidget ) {
+ if ( editingRestrictionWidget ) {
editingRestrictionWidget.setDisabled( !editingIsSelected );
+ }
+ if ( pageRestrictionsWidget ) {
pageRestrictionsWidget.setDisabled( !editingIsSelected || editingRestrictionValue === 'sitewide' );
}
- if ( preventTalkPageEdit ) {
- // TODO: (T210475) this option is disabled for partial blocks unless
- // a namespace restriction for User_talk namespace is in place.
- // This needs to be updated once Namespace restrictions is available
- preventTalkPageEdit.setDisabled( editingRestrictionValue === 'partial' && editingIsSelected );
+ if ( namespaceRestrictionsWidget ) {
+ namespaceRestrictionsWidget.setDisabled( !editingIsSelected || editingRestrictionValue === 'sitewide' );
+ }
+ if ( preventTalkPageEdit && namespaceRestrictionsWidget ) {
+ // This option is disabled for partial blocks unless a namespace restriction
+ // for the User_talk namespace is in place.
+ preventTalkPageEdit.setDisabled(
+ editingIsSelected &&
+ editingRestrictionValue === 'partial' &&
+ namespaceRestrictionsWidget.getValue().indexOf(
+ String( mw.config.get( 'wgNamespaceIds' ).user_talk )
+ ) === -1
+ );
}
}
// Bind functions so they're checked whenever stuff changes
blockTargetWidget.on( 'change', updateBlockOptions );
expiryWidget.on( 'change', updateBlockOptions );
+ if ( editingWidget ) {
+ editingWidget.on( 'change', updateBlockOptions );
+ }
if ( editingRestrictionWidget ) {
editingRestrictionWidget.on( 'change', updateBlockOptions );
}
- if ( editingWidget ) {
- editingWidget.on( 'change', updateBlockOptions );
+ if ( namespaceRestrictionsWidget ) {
+ namespaceRestrictionsWidget.on( 'change', updateBlockOptions );
}
// Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours)
margin-left: @ooui-spacing-radio-label;
}
- .mw-block-page-restrictions.oo-ui-fieldLayout {
+ .mw-block-restriction.oo-ui-fieldLayout {
margin-left: 2 * @ooui-spacing-radio-label;
.oo-ui-widget {
<?php
+use MediaWiki\Block\Restriction\PageRestriction;
+use MediaWiki\Block\Restriction\NamespaceRestriction;
+
/**
* @group API
* @group Database
$title = 'Foo';
$page = $this->getExistingTestPage( $title );
+ $namespace = NS_TALK;
$this->doBlock( [
'partial' => true,
'pagerestrictions' => $title,
+ 'namespacerestrictions' => $namespace,
] );
$block = Block::newFromTarget( $this->mUser->getName() );
$this->assertFalse( $block->isSitewide() );
- $this->assertCount( 1, $block->getRestrictions() );
+ $this->assertCount( 2, $block->getRestrictions() );
+ $this->assertInstanceOf( PageRestriction::class, $block->getRestrictions()[0] );
$this->assertEquals( $title, $block->getRestrictions()[0]->getTitle()->getText() );
+ $this->assertInstanceOf( NamespaceRestriction::class, $block->getRestrictions()[1] );
+ $this->assertEquals( $namespace, $block->getRestrictions()[1]->getValue() );
}
/**
* @expectedExceptionMessage Too many values supplied for parameter "pagerestrictions". The
* limit is 10.
*/
- public function testBlockingToManyRestrictions() {
+ public function testBlockingToManyPageRestrictions() {
$this->setMwGlobals( [
'wgEnablePartialBlocks' => true,
] );
use MediaWiki\Block\BlockRestriction;
use MediaWiki\Block\Restriction\PageRestriction;
+use MediaWiki\Block\Restriction\NamespaceRestriction;
use Wikimedia\TestingAccessWrapper;
/**
$this->assertArrayNotHasKey( 'EditingRestriction', $fields );
$this->assertArrayNotHasKey( 'PageRestrictions', $fields );
+ $this->assertArrayNotHasKey( 'NamespaceRestrictions', $fields );
}
/**
$this->assertArrayHasKey( 'EditingRestriction', $fields );
$this->assertArrayHasKey( 'PageRestrictions', $fields );
+ $this->assertArrayHasKey( 'NamespaceRestrictions', $fields );
}
/**
$block->setRestrictions( [
new PageRestriction( 0, $pageSaturn->getId() ),
new PageRestriction( 0, $pageMars->getId() ),
+ new NamespaceRestriction( 0, NS_TALK ),
] );
$block->insert();
/**
* @covers ::processForm()
*/
- public function testProcessFormRestictions() {
+ public function testProcessFormRestrictions() {
$this->setMwGlobals( [
'wgEnablePartialBlocks' => true,
] );
'Watch' => '0',
'EditingRestriction' => 'partial',
'PageRestrictions' => implode( "\n", $titles ),
+ 'NamespaceRestrictions' => '',
];
$result = $page->processForm( $data, $context );
'Watch' => '0',
'EditingRestriction' => 'partial',
'PageRestrictions' => implode( "\n", $titles ),
+ 'NamespaceRestrictions' => '',
];
$result = $page->processForm( $data, $context );