Add namespace restrictions to block's log messages
[lhc/web/wiklou.git] / includes / specials / SpecialBlock.php
index c9ce2b0..bab3c8c 100644 (file)
@@ -23,6 +23,7 @@
 
 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
@@ -156,65 +157,68 @@ class SpecialBlock extends FormSpecialPage {
                        'type' => 'user',
                        'ipallowed' => true,
                        'iprange' => true,
-                       'label-message' => 'ipaddressorusername',
                        'id' => 'mw-bi-target',
                        'size' => '45',
                        'autofocus' => true,
                        'required' => true,
                        'validation-callback' => [ __CLASS__, 'validateTargetField' ],
+                       'section' => 'target',
+               ];
+
+               $a['Editing'] = [
+                       'type' => 'check',
+                       'label-message' => 'block-prevent-edit',
+                       'default' => true,
+                       'section' => 'actions',
+                       'disabled' => $enablePartialBlocks ? false : true,
                ];
 
                if ( $enablePartialBlocks ) {
                        $a['EditingRestriction'] = [
                                'type' => 'radio',
-                               'label' => $this->msg( 'ipb-type-label' )->text(),
+                               'cssclass' => 'mw-block-editing-restriction',
                                'options' => [
                                        $this->msg( 'ipb-sitewide' )->text() => 'sitewide',
                                        $this->msg( 'ipb-partial' )->text() => 'partial',
                                ],
+                               'section' => 'actions',
                        ];
                        $a['PageRestrictions'] = [
                                'type' => 'titlesmultiselect',
                                '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['Expiry'] = [
-                       'type' => 'expiry',
-                       'label-message' => 'ipbexpiry',
-                       'required' => true,
-                       'options' => $suggestedDurations,
-                       'default' => $this->msg( 'ipb-default-expiry' )->inContentLanguage()->text(),
-               ];
-
-               $a['Reason'] = [
-                       'type' => 'selectandother',
-                       // HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
-                       // (e.g. emojis) count for two each. This limit is overridden in JS to instead count
-                       // Unicode codepoints (or 255 UTF-8 bytes for old schema).
-                       'maxlength' => $oldCommentSchema ? 255 : CommentStore::COMMENT_CHARACTER_LIMIT,
-                       'maxlength-unit' => 'codepoints',
-                       'label-message' => 'ipbreason',
-                       'options-message' => 'ipbreason-dropdown',
-               ];
-
                $a['CreateAccount'] = [
                        'type' => 'check',
                        'label-message' => 'ipbcreateaccount',
                        'default' => true,
+                       'section' => 'actions',
                ];
 
                if ( self::canBlockEmail( $user ) ) {
                        $a['DisableEmail'] = [
                                'type' => 'check',
                                'label-message' => 'ipbemailban',
+                               'section' => 'actions',
                        ];
                }
 
@@ -223,13 +227,34 @@ class SpecialBlock extends FormSpecialPage {
                                'type' => 'check',
                                'label-message' => 'ipb-disableusertalk',
                                'default' => false,
+                               'section' => 'actions',
                        ];
                }
 
+               $a['Expiry'] = [
+                       'type' => 'expiry',
+                       'required' => true,
+                       'options' => $suggestedDurations,
+                       'default' => $this->msg( 'ipb-default-expiry' )->inContentLanguage()->text(),
+                       'section' => 'expiry',
+               ];
+
+               $a['Reason'] = [
+                       'type' => 'selectandother',
+                       // HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
+                       // (e.g. emojis) count for two each. This limit is overridden in JS to instead count
+                       // Unicode codepoints (or 255 UTF-8 bytes for old schema).
+                       'maxlength' => $oldCommentSchema ? 255 : CommentStore::COMMENT_CHARACTER_LIMIT,
+                       'maxlength-unit' => 'codepoints',
+                       'options-message' => 'ipbreason-dropdown',
+                       'section' => 'reason',
+               ];
+
                $a['AutoBlock'] = [
                        'type' => 'check',
                        'label-message' => 'ipbenableautoblock',
                        'default' => true,
+                       'section' => 'options',
                ];
 
                # Allow some users to hide name from block log, blocklist and listusers
@@ -238,6 +263,7 @@ class SpecialBlock extends FormSpecialPage {
                                'type' => 'check',
                                'label-message' => 'ipbhidename',
                                'cssclass' => 'mw-block-hideuser',
+                               'section' => 'options',
                        ];
                }
 
@@ -246,6 +272,7 @@ class SpecialBlock extends FormSpecialPage {
                        $a['Watch'] = [
                                'type' => 'check',
                                'label-message' => 'ipbwatchuser',
+                               'section' => 'options',
                        ];
                }
 
@@ -253,6 +280,7 @@ class SpecialBlock extends FormSpecialPage {
                        'type' => 'check',
                        'label-message' => 'ipb-hardblock',
                        'default' => false,
+                       'section' => 'options',
                ];
 
                # This is basically a copy of the Target field, but the user can't change it, so we
@@ -374,17 +402,31 @@ class SpecialBlock extends FormSpecialPage {
 
                        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 ) &&
+                                       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 );
                        }
                }
        }
@@ -394,7 +436,10 @@ class SpecialBlock extends FormSpecialPage {
         * @return string
         */
        protected function preText() {
-               $this->getOutput()->addModuleStyles( 'mediawiki.widgets.TagMultiselectWidget.styles' );
+               $this->getOutput()->addModuleStyles( [
+                       'mediawiki.widgets.TagMultiselectWidget.styles',
+                       'mediawiki.special',
+               ] );
                $this->getOutput()->addModules( [ 'mediawiki.special.block' ] );
 
                $blockCIDRLimit = $this->getConfig()->get( 'BlockCIDRLimit' );
@@ -815,10 +860,11 @@ class SpecialBlock extends FormSpecialPage {
                        return $reason;
                }
 
-               $restrictions = [];
+               $pageRestrictions = [];
+               $namespaceRestrictions = [];
                if ( $enablePartialBlocks ) {
-                       if ( !empty( $data['PageRestrictions'] ) ) {
-                               $restrictions = array_map( function ( $text ) {
+                       if ( $data['PageRestrictions'] !== '' ) {
+                               $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.
@@ -827,7 +873,13 @@ class SpecialBlock extends FormSpecialPage {
                                        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 );
                }
 
@@ -928,10 +980,14 @@ class SpecialBlock extends FormSpecialPage {
                $logParams['6::flags'] = self::blockLogFlags( $data, $type );
                $logParams['sitewide'] = $block->isSitewide();
 
-               if ( $enablePartialBlocks && !empty( $data['PageRestrictions'] ) ) {
-                       $logParams['7::restrictions'] = [
-                               'pages' => explode( "\n", $data['PageRestrictions'] ),
-                       ];
+               if ( $enablePartialBlocks && !$block->isSitewide() ) {
+                       if ( $data['PageRestrictions'] !== '' ) {
+                               $logParams['7::restrictions']['pages'] = explode( "\n", $data['PageRestrictions'] );
+                       }
+
+                       if ( $data['NamespaceRestrictions'] !== '' ) {
+                               $logParams['7::restrictions']['namespaces'] = explode( "\n", $data['NamespaceRestrictions'] );
+                       }
                }
 
                # Make log entry, if the name is hidden, put it in the suppression log
@@ -1138,6 +1194,13 @@ class SpecialBlock extends FormSpecialPage {
         * @return bool|array True for success, false for didn't-try, array of errors on failure
         */
        public function onSubmit( array $data, HTMLForm $form = null ) {
+               // If "Editing" checkbox is unchecked, the block must be a partial block affecting
+               // actions other than editing, and there must be no restrictions.
+               if ( isset( $data['Editing'] ) && $data['Editing'] === false ) {
+                       $data['EditingRestriction'] = 'partial';
+                       $data['PageRestrictions'] = '';
+                       $data['NamespaceRestrictions'] = '';
+               }
                return self::processForm( $data, $form->getContext() );
        }