Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 115 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
SpecialSpecialPages | |
0.00% |
0 / 114 |
|
0.00% |
0 / 4 |
702 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
getPageGroups | |
0.00% |
0 / 22 |
|
0.00% |
0 / 1 |
42 | |||
outputPageList | |
0.00% |
0 / 81 |
|
0.00% |
0 / 1 |
306 |
1 | <?php |
2 | /** |
3 | * Implements Special:Specialpages |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License along |
16 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
18 | * http://www.gnu.org/copyleft/gpl.html |
19 | * |
20 | * @file |
21 | * @ingroup SpecialPage |
22 | */ |
23 | |
24 | namespace MediaWiki\Specials; |
25 | |
26 | use MediaWiki\Html\Html; |
27 | use MediaWiki\Language\RawMessage; |
28 | use MediaWiki\Parser\Parser; |
29 | use MediaWiki\Parser\ParserOutput; |
30 | use MediaWiki\Parser\ParserOutputFlags; |
31 | use MediaWiki\SpecialPage\UnlistedSpecialPage; |
32 | use Wikimedia\Parsoid\Core\SectionMetadata; |
33 | use Wikimedia\Parsoid\Core\TOCData; |
34 | |
35 | /** |
36 | * A special page that lists special pages |
37 | * |
38 | * @ingroup SpecialPage |
39 | */ |
40 | class SpecialSpecialPages extends UnlistedSpecialPage { |
41 | |
42 | public function __construct() { |
43 | parent::__construct( 'Specialpages' ); |
44 | } |
45 | |
46 | public function execute( $par ) { |
47 | $out = $this->getOutput(); |
48 | $this->setHeaders(); |
49 | $this->outputHeader(); |
50 | $out->setPreventClickjacking( false ); |
51 | $out->addModuleStyles( 'mediawiki.special' ); |
52 | |
53 | $groups = $this->getPageGroups(); |
54 | |
55 | if ( $groups === false ) { |
56 | return; |
57 | } |
58 | |
59 | $this->addHelpLink( 'Help:Special pages' ); |
60 | $this->outputPageList( $groups ); |
61 | } |
62 | |
63 | private function getPageGroups() { |
64 | $pages = $this->getSpecialPageFactory()->getUsablePages( $this->getUser() ); |
65 | |
66 | if ( $pages === [] ) { |
67 | // Yeah, that was pointless. Thanks for coming. |
68 | return false; |
69 | } |
70 | |
71 | // Put them into a sortable array |
72 | $groups = []; |
73 | foreach ( $pages as $page ) { |
74 | $group = $page->getFinalGroupName(); |
75 | $desc = $page->getDescription(); |
76 | // T343849 |
77 | if ( is_string( $desc ) ) { |
78 | wfDeprecated( "string return from {$page->getName()}::getDescription()", '1.41' ); |
79 | $desc = ( new RawMessage( '$1' ) )->rawParams( $desc ); |
80 | } |
81 | $groups[$group][$desc->text()] = [ |
82 | $page->getPageTitle(), |
83 | $page->isRestricted(), |
84 | $page->isCached() |
85 | ]; |
86 | } |
87 | |
88 | // Sort |
89 | foreach ( $groups as $group => $sortedPages ) { |
90 | ksort( $groups[$group] ); |
91 | } |
92 | |
93 | // Always move "other" to end |
94 | if ( array_key_exists( 'other', $groups ) ) { |
95 | $other = $groups['other']; |
96 | unset( $groups['other'] ); |
97 | $groups['other'] = $other; |
98 | } |
99 | |
100 | return $groups; |
101 | } |
102 | |
103 | private function outputPageList( $groups ) { |
104 | $out = $this->getOutput(); |
105 | |
106 | // Legend |
107 | $includesRestrictedPages = false; |
108 | $includesCachedPages = false; |
109 | foreach ( $groups as $group => $sortedPages ) { |
110 | foreach ( $sortedPages as $desc => [ $title, $restricted, $cached ] ) { |
111 | if ( $cached ) { |
112 | $includesCachedPages = true; |
113 | } |
114 | if ( $restricted ) { |
115 | $includesRestrictedPages = true; |
116 | } |
117 | } |
118 | } |
119 | |
120 | $notes = []; |
121 | if ( $includesRestrictedPages ) { |
122 | $restricedMsg = $this->msg( 'specialpages-note-restricted' ); |
123 | if ( !$restricedMsg->isDisabled() ) { |
124 | $notes[] = $restricedMsg->parse(); |
125 | } |
126 | } |
127 | if ( $includesCachedPages ) { |
128 | $cachedMsg = $this->msg( 'specialpages-note-cached' ); |
129 | if ( !$cachedMsg->isDisabled() ) { |
130 | $notes[] = $cachedMsg->parse(); |
131 | } |
132 | } |
133 | if ( $notes !== [] ) { |
134 | $legendHeading = $this->msg( 'specialpages-note-top' )->parse(); |
135 | |
136 | $legend = Html::rawElement( |
137 | 'div', |
138 | [ 'class' => 'mw-changeslist-legend mw-specialpages-notes' ], |
139 | $legendHeading . implode( "\n", $notes ) |
140 | ); |
141 | |
142 | $out->addHTML( $legend ); |
143 | $out->addModuleStyles( 'mediawiki.special.changeslist.legend' ); |
144 | } |
145 | |
146 | // Format table of contents |
147 | $tocData = new TOCData(); |
148 | $tocLength = 0; |
149 | foreach ( $groups as $group => $sortedPages ) { |
150 | if ( !str_contains( $group, '/' ) ) { |
151 | ++$tocLength; |
152 | $tocData->addSection( new SectionMetadata( |
153 | 1, |
154 | 2, |
155 | $this->msg( "specialpages-group-$group" )->escaped(), |
156 | $this->getLanguage()->formatNum( $tocLength ), |
157 | (string)$tocLength, |
158 | null, |
159 | null, |
160 | "mw-specialpagesgroup-$group", |
161 | "mw-specialpagesgroup-$group" |
162 | ) ); |
163 | } |
164 | } |
165 | |
166 | $pout = new ParserOutput; |
167 | $pout->setTOCData( $tocData ); |
168 | $pout->setOutputFlag( ParserOutputFlags::SHOW_TOC ); |
169 | $pout->setRawText( Parser::TOC_PLACEHOLDER ); |
170 | $out->addParserOutput( $pout ); |
171 | |
172 | // Format contents |
173 | foreach ( $groups as $group => $sortedPages ) { |
174 | if ( str_contains( $group, '/' ) ) { |
175 | [ $group, $subGroup ] = explode( '/', $group, 2 ); |
176 | $out->addHTML( Html::element( |
177 | 'h3', |
178 | [ 'class' => "mw-specialpagessubgroup" ], |
179 | $this->msg( "specialpages-group-$group-$subGroup" )->text() |
180 | ) . "\n" ); |
181 | } else { |
182 | $out->addHTML( Html::element( |
183 | 'h2', |
184 | [ 'class' => "mw-specialpagesgroup", 'id' => "mw-specialpagesgroup-$group" ], |
185 | $this->msg( "specialpages-group-$group" )->text() |
186 | ) . "\n" ); |
187 | } |
188 | $out->addHTML( |
189 | Html::openElement( 'div', [ 'class' => 'mw-specialpages-list' ] ) |
190 | . '<ul>' |
191 | ); |
192 | foreach ( $sortedPages as $desc => [ $title, $restricted, $cached ] ) { |
193 | $pageClasses = []; |
194 | if ( $cached ) { |
195 | $pageClasses[] = 'mw-specialpagecached'; |
196 | } |
197 | if ( $restricted ) { |
198 | $pageClasses[] = 'mw-specialpagerestricted'; |
199 | } |
200 | |
201 | $link = $this->getLinkRenderer()->makeKnownLink( $title, $desc ); |
202 | $out->addHTML( Html::rawElement( |
203 | 'li', |
204 | [ 'class' => $pageClasses ], |
205 | $link |
206 | ) . "\n" ); |
207 | } |
208 | $out->addHTML( |
209 | Html::closeElement( 'ul' ) . |
210 | Html::closeElement( 'div' ) |
211 | ); |
212 | } |
213 | } |
214 | } |
215 | |
216 | /** |
217 | * Retain the old class name for backwards compatibility. |
218 | * @deprecated since 1.41 |
219 | */ |
220 | class_alias( SpecialSpecialPages::class, 'SpecialSpecialpages' ); |