Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 116 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
SpecialSpecialPages | |
0.00% |
0 / 115 |
|
0.00% |
0 / 4 |
756 | |
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 / 23 |
|
0.00% |
0 / 1 |
56 | |||
outputPageList | |
0.00% |
0 / 81 |
|
0.00% |
0 / 1 |
306 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @file |
19 | */ |
20 | |
21 | namespace MediaWiki\Specials; |
22 | |
23 | use MediaWiki\Html\Html; |
24 | use MediaWiki\Language\RawMessage; |
25 | use MediaWiki\Parser\Parser; |
26 | use MediaWiki\Parser\ParserOutput; |
27 | use MediaWiki\Parser\ParserOutputFlags; |
28 | use MediaWiki\SpecialPage\UnlistedSpecialPage; |
29 | use Wikimedia\Parsoid\Core\SectionMetadata; |
30 | use Wikimedia\Parsoid\Core\TOCData; |
31 | |
32 | /** |
33 | * A special page that lists special pages |
34 | * |
35 | * @ingroup SpecialPage |
36 | */ |
37 | class SpecialSpecialPages extends UnlistedSpecialPage { |
38 | |
39 | public function __construct() { |
40 | parent::__construct( 'Specialpages' ); |
41 | } |
42 | |
43 | public function execute( $par ) { |
44 | $out = $this->getOutput(); |
45 | $this->setHeaders(); |
46 | $this->outputHeader(); |
47 | $out->getMetadata()->setPreventClickjacking( false ); |
48 | $out->addModuleStyles( 'mediawiki.special' ); |
49 | |
50 | $groups = $this->getPageGroups(); |
51 | |
52 | if ( $groups === false ) { |
53 | return; |
54 | } |
55 | |
56 | $this->addHelpLink( 'Help:Special pages' ); |
57 | $this->outputPageList( $groups ); |
58 | } |
59 | |
60 | private function getPageGroups() { |
61 | $pages = $this->getSpecialPageFactory()->getUsablePages( $this->getUser() ); |
62 | |
63 | if ( $pages === [] ) { |
64 | // Yeah, that was pointless. Thanks for coming. |
65 | return false; |
66 | } |
67 | |
68 | // Put them into a sortable array |
69 | $groups = []; |
70 | foreach ( $pages as $page ) { |
71 | $group = $page->getFinalGroupName(); |
72 | $desc = $page->getDescription(); |
73 | // T343849 |
74 | if ( is_string( $desc ) ) { |
75 | wfDeprecated( "string return from {$page->getName()}::getDescription()", '1.41' ); |
76 | $desc = ( new RawMessage( '$1' ) )->rawParams( $desc ); |
77 | } |
78 | // (T360723) Only show an entry if the message isn't blanked, to allow on-wiki unlisting |
79 | if ( !$desc->isDisabled() ) { |
80 | $groups[$group][$desc->text()] = [ |
81 | $page->getPageTitle(), |
82 | $page->isRestricted(), |
83 | $page->isCached() |
84 | ]; |
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' ); |