Add Namespace Restrictions to Special:BlockList
authorDavid Barratt <dbarratt@wikimedia.org>
Fri, 23 Nov 2018 05:08:27 +0000 (00:08 -0500)
committerUmherirrender <umherirrender_de.wp@web.de>
Mon, 28 Jan 2019 18:37:58 +0000 (18:37 +0000)
The editing restrictions will be split by type and add a heading for each type.
The namespace will be linked to Special:AllPages with the namespace set so the
user can see what pages the user is blocked from.

Bug: T204990
Change-Id: Idb1de20c1a780562b072ea350e5ba7dd1518d177

includes/specials/pagers/BlockListPager.php
languages/i18n/en.json
languages/i18n/qqq.json
tests/phpunit/includes/specials/pagers/BlockListPagerTest.php

index 205ffbf..8fc586b 100644 (file)
@@ -24,6 +24,8 @@
  */
 use MediaWiki\Block\BlockRestriction;
 use MediaWiki\Block\Restriction\Restriction;
+use MediaWiki\Block\Restriction\PageRestriction;
+use MediaWiki\Block\Restriction\NamespaceRestriction;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\Rdbms\IResultWrapper;
 
@@ -198,7 +200,7 @@ class BlockListPager extends TablePager {
                                }
 
                                if ( !$row->ipb_sitewide && $this->restrictions ) {
-                                       $list = $this->getRestrictionListHTML( $this->restrictions, $row );
+                                       $list = $this->getRestrictionListHTML( $row );
                                        if ( $list ) {
                                                $properties[] = htmlspecialchars( $msg['blocklist-editing'] ) . $list;
                                        }
@@ -246,41 +248,69 @@ class BlockListPager extends TablePager {
        /**
         * Get Restriction List HTML
         *
-        * @param Restriction[] $restrictions
         * @param stdClass $row
         *
         * @return string
         */
-       private static function getRestrictionListHTML(
-               array $restrictions,
-               stdClass $row
-       ) {
+       private function getRestrictionListHTML( stdClass $row ) {
                $items = [];
 
-               foreach ( $restrictions as $restriction ) {
+               foreach ( $this->restrictions as $restriction ) {
                        if ( $restriction->getBlockId() !== (int)$row->ipb_id ) {
                                continue;
                        }
 
-                       if ( $restriction->getType() !== 'page' ) {
-                               continue;
+                       switch ( $restriction->getType() ) {
+                               case PageRestriction::TYPE:
+                                       $items[$restriction->getType()][] = HTML::rawElement(
+                                               'li',
+                                               [],
+                                               Linker::link( $restriction->getTitle() )
+                                       );
+                                       break;
+                               case NamespaceRestriction::TYPE:
+                                       $text = $restriction->getValue() === NS_MAIN
+                                               ? $this->msg( 'blanknamespace' )
+                                               : $this->getLanguage()->getFormattedNsText(
+                                                       $restriction->getValue()
+                                               );
+                                       $items[$restriction->getType()][] = HTML::rawElement(
+                                               'li',
+                                               [],
+                                               Linker::link(
+                                                       SpecialPage::getTitleValueFor( 'Allpages' ),
+                                                       $text,
+                                                       [],
+                                                       [
+                                                               'namespace' => $restriction->getValue()
+                                                       ]
+                                               )
+                                       );
+                                       break;
                        }
-
-                       $items[] = Html::rawElement(
-                               'li',
-                               [],
-                               Linker::link( $restriction->getTitle() )
-                       );
                }
 
                if ( empty( $items ) ) {
                        return '';
                }
 
+               $sets = [];
+               foreach ( $items as $key => $value ) {
+                       $sets[] = Html::rawElement(
+                               'li',
+                               [],
+                               $this->msg( 'blocklist-editing-' . $key ) . Html::rawElement(
+                                       'ul',
+                                       [],
+                                       implode( '', $value )
+                               )
+                       );
+               }
+
                return Html::rawElement(
                        'ul',
                        [],
-                       implode( '', $items )
+                       implode( '', $sets )
                );
        }
 
index 86da5d9..e86c6fa 100644 (file)
        "blocklist-nousertalk": "cannot edit own talk page",
        "blocklist-editing": "editing",
        "blocklist-editing-sitewide": "editing (sitewide)",
+       "blocklist-editing-page": "pages",
+       "blocklist-editing-ns": "namespaces",
        "ipblocklist-empty": "The block list is empty.",
        "ipblocklist-no-results": "The requested IP address or username is not blocked.",
        "blocklink": "block",
index 58c2b97..2fc5086 100644 (file)
        "blocklist-nousertalk": "Used in [[Special:IPBlockList]] when \"Allow this user to edit own talk page while blocked\" option hasn't been flagged.\n\nSee also {{msg-mw|Block-log-flags-nousertalk}}.\n\nPart of the log entry of user block in [[Special:BlockList]].\n\n{{Related|Blocklist}}",
        "blocklist-editing": "Used in [[Special:IPBlockList]] when a block is not a sitewide block.",
        "blocklist-editing-sitewide": "Used in [[Special:IPBlockList]] when a block is a sitewide block.",
+       "blocklist-editing-page": "Used in [[Special:IPBlockList]] when a partial block has page restrictions.",
+       "blocklist-editing-ns": "Used in [[Special:IPBlockList]] when a partial block has namespace restrictions.",
        "ipblocklist-empty": "Used in [[Special:BlockList]], if the target is not specified.\n\nSee also:\n* {{msg-mw|Ipblocklist-no-results}}",
        "ipblocklist-no-results": "Used in [[Special:BlockList]], if the target is specified.\n\nSee also:\n* {{msg-mw|Ipblocklist-empty}}",
        "blocklink": "Display name for a link that, when selected, leads to a form where a user can be blocked. Used in page history and recent changes pages. Example: \"''UserName (Talk | contribs | '''block''')''\".\n\nUsed as link title in [[Special:Contributions]] and in [[Special:DeletedContributions]].\n\nSee also:\n* {{msg-mw|Sp-contributions-talk}}\n* {{msg-mw|Change-blocklink}}\n* {{msg-mw|Unblocklink}}\n* {{msg-mw|Sp-contributions-blocklog}}\n* {{msg-mw|Sp-contributions-uploads}}\n* {{msg-mw|Sp-contributions-logs}}\n* {{msg-mw|Sp-contributions-deleted}}\n* {{msg-mw|Sp-contributions-userrights}}\n{{Identical|Block}}",
index 80df1d0..570291c 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use MediaWiki\Block\Restriction\PageRestriction;
+use MediaWiki\Block\Restriction\NamespaceRestriction;
 use MediaWiki\MediaWikiServices;
 use Wikimedia\TestingAccessWrapper;
 
@@ -109,9 +110,13 @@ class BlockListPagerTest extends MediaWikiTestCase {
 
        /**
         * @covers ::formatValue
+        * @covers ::getRestrictionListHTML
         */
        public function testFormatValueRestrictions() {
-               $this->setMwGlobals( 'wgArticlePath', '/wiki/$1' );
+               $this->setMwGlobals( [
+                       'wgArticlePath' => '/wiki/$1',
+                       'wgScript' => '/w/index.php',
+               ] );
 
                $pager = new BlockListPager( new SpecialPage(),  [] );
 
@@ -134,7 +139,8 @@ class BlockListPagerTest extends MediaWikiTestCase {
                $pageId = $page['id'];
 
                $restrictions = [
-                       ( new PageRestriction( 0, $pageId ) )->setTitle( $title )
+                       ( new PageRestriction( 0, $pageId ) )->setTitle( $title ),
+                       new NamespaceRestriction( 0, NS_MAIN )
                ];
 
                $wrappedPager = TestingAccessWrapper::newFromObject( $pager );
@@ -146,11 +152,21 @@ class BlockListPagerTest extends MediaWikiTestCase {
                        // and must not depend on a localisation message.
                        // TODO: Mock the message or consider using qqx.
                        . wfMessage( 'blocklist-editing' )->text()
-                       . '<ul><li><a href="/wiki/Victor_Frankenstein" title="'
+                       . '<ul><li>'
+                       . wfMessage( 'blocklist-editing-page' )->text()
+                       . '<ul><li>'
+                       . '<a href="/wiki/Victor_Frankenstein" title="'
                        . $pageName
                        . '">'
                        . $pageName
-                       . '</a></li></ul></li></ul>',
+                       . '</a></li></ul></li><li>'
+                       . wfMessage( 'blocklist-editing-ns' )->text()
+                       . '<ul><li>'
+                       . '<a href="/w/index.php?title=Special:AllPages&amp;namespace=0" title="'
+                       . 'Special:AllPages'
+                       . '">'
+                       . wfMessage( 'blanknamespace' )->text()
+                       . '</a></li></ul></li></ul></li></ul>',
                        $formatted
                );
        }