Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 103
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialNamespaceInfo
0.00% covered (danger)
0.00%
0 / 103
0.00% covered (danger)
0.00%
0 / 4
420
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 37
0.00% covered (danger)
0.00%
0 / 1
6
 makeNamespaceRow
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 1
272
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * @license GPL-2.0-or-later
5 * @file
6 * @ingroup SpecialPage
7 */
8
9namespace MediaWiki\Specials;
10
11use MediaWiki\Html\Html;
12use MediaWiki\SpecialPage\SpecialPage;
13use MediaWiki\Title\NamespaceInfo;
14
15/**
16 * Show information about the different namespaces
17 *
18 * @since 1.43
19 * @author DannyS712
20 * @ingroup SpecialPage
21 */
22class SpecialNamespaceInfo extends SpecialPage {
23
24    public function __construct(
25        private readonly NamespaceInfo $namespaceInfo
26    ) {
27        parent::__construct( 'NamespaceInfo' );
28    }
29
30    /**
31     * @param string|null $par
32     */
33    public function execute( $par ) {
34        $this->setHeaders();
35        $this->outputHeader();
36
37        $out = $this->getOutput();
38
39        $idHeading = Html::element(
40            'th',
41            [],
42            $this->msg( 'namespaceinfo-heading-id' )->text()
43        );
44        $canonicalHeading = Html::element(
45            'th',
46            [],
47            $this->msg( 'namespaceinfo-heading-canonical' )->text()
48        );
49        $localHeading = Html::element(
50            'th',
51            [],
52            $this->msg( 'namespaceinfo-heading-local' )->text()
53        );
54        $infoHeading = Html::element(
55            'th',
56            [],
57            $this->msg( 'namespaceinfo-heading-info' )->text()
58        );
59        $tableHeadingRow = Html::rawElement(
60            'tr',
61            [],
62            $idHeading . $canonicalHeading . $localHeading . $infoHeading
63        );
64
65        $tableBodyRows = '';
66        foreach ( $this->getContentLanguage()->getFormattedNamespaces() as $ns => $localName ) {
67            $tableBodyRows .= $this->makeNamespaceRow( $ns, $localName );
68        }
69
70        $table = Html::rawElement(
71            'table',
72            [ 'class' => 'wikitable' ],
73            $tableHeadingRow . $tableBodyRows
74        );
75
76        $out->addHtml( $table );
77    }
78
79    /**
80     * Get the HTML for a row for a specific namespace
81     *
82     * @param int $ns
83     * @param string $localName
84     * @return string
85     */
86    private function makeNamespaceRow( int $ns, string $localName ): string {
87        $canonicalName = $this->namespaceInfo->getCanonicalName( $ns );
88        if ( $canonicalName ) {
89            $canonicalName = strtr( $canonicalName, '_', ' ' );
90        } else {
91            $canonicalName = '';
92        }
93
94        // Special handling for main namespace
95        if ( $ns === NS_MAIN ) {
96            $localName = $this->msg( 'blanknamespace' )->escaped();
97            $canonicalName = $this->msg( 'blanknamespace' )->inLanguage( 'en' )->escaped();
98        }
99
100        $description = $this->msg( 'namespaceinfo-description-ns' . $ns );
101        if ( $description->isDisabled() ) {
102            // Custom namespace with no message
103
104            if ( $this->namespaceInfo->isTalk( $ns ) ) {
105                $subjectNs = $this->namespaceInfo->getSubject( $ns );
106                $subjectName = strtr(
107                    $this->namespaceInfo->getCanonicalName( $subjectNs ),
108                    '_',
109                    ' '
110                );
111                $description = $this->msg( 'namespaceinfo-description-custom-talk',
112                    $subjectName,
113                    $subjectNs
114                );
115            } else {
116                $description = $this->msg( 'namespaceinfo-description-custom', $localName );
117            }
118        }
119        $descriptionText = $description->parse();
120
121        $properties = [];
122        if ( $ns >= NS_MAIN ) {
123            // Don't talk about immovable namespaces for virtual NS_SPECIAL or NS_MEDIA
124            $namespaceProtection = $this->getConfig()->get( 'NamespaceProtection' );
125            if ( isset( $namespaceProtection[$ns] ) ) {
126                $rightsNeeded = $namespaceProtection[$ns];
127                if ( !is_array( $rightsNeeded ) ) {
128                    $rightsNeeded = [ $rightsNeeded ];
129                }
130                foreach ( $rightsNeeded as $right ) {
131                    $properties[] = $this->msg( 'namespaceinfo-namespace-protection-right', $right )
132                        ->parse();
133                }
134            }
135
136            if ( !$this->namespaceInfo->isMovable( $ns ) ) {
137                $properties[] = $this->msg( 'namespaceinfo-namespace-immovable' )->parse();
138            }
139            if ( $this->namespaceInfo->isContent( $ns ) ) {
140                $properties[] = $this->msg( 'namespaceinfo-namespace-iscontent' )->parse();
141            }
142            if ( $this->namespaceInfo->hasSubpages( $ns ) ) {
143                $properties[] = $this->msg( 'namespaceinfo-namespace-subpages' )->parse();
144            }
145            if ( $this->namespaceInfo->isNonincludable( $ns ) ) {
146                $properties[] = $this->msg( 'namespaceinfo-namespace-nonincludable' )->parse();
147            }
148            $contentModel = $this->namespaceInfo->getNamespaceContentModel( $ns );
149            if ( $contentModel !== null ) {
150                $properties[] = $this->msg( 'namespaceinfo-namespace-default-contentmodel' )
151                    ->params( $contentModel )
152                    ->parse();
153            }
154        }
155
156        // Convert to a string
157        $namespaceProperties = '';
158        if ( $properties !== [] ) {
159            $namespaceProperties = Html::openElement( 'ul' );
160            foreach ( $properties as $propertyText ) {
161                $namespaceProperties .= Html::rawElement(
162                    'li',
163                    [],
164                    $propertyText
165                );
166            }
167            $namespaceProperties .= Html::closeElement( 'ul' );
168        }
169
170        $idField = Html::rawElement( 'td', [], (string)$ns );
171        $canonicalField = Html::rawElement( 'td', [], $canonicalName );
172        $localField = Html::rawElement( 'td', [], $localName );
173        $infoField = Html::rawElement( 'td', [], $descriptionText . $namespaceProperties );
174
175        return Html::rawElement(
176            'tr',
177            [],
178            $idField . $canonicalField . $localField . $infoField
179        );
180    }
181
182    /**
183     * @return string
184     */
185    protected function getGroupName() {
186        return 'wiki';
187    }
188
189}