MediaWiki master
SpecialSpecialPages.php
Go to the documentation of this file.
1<?php
24namespace MediaWiki\Specials;
25
32use Wikimedia\Parsoid\Core\SectionMetadata;
33use Wikimedia\Parsoid\Core\TOCData;
34
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
220class_alias( SpecialSpecialPages::class, 'SpecialSpecialpages' );
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
This class is a collection of static functions that serve two purposes:
Definition Html.php:56
Variant of the Message class.
ParserOutput is a rendering of a Content object or a message.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:156
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getUser()
Shortcut to get the User executing this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
getLanguage()
Shortcut to get user's language.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages By default the message key is the canonical name of...
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Shortcut to construct a special page which is unlisted by default.
A special page that lists special pages.
execute( $par)
Default execute method Checks user permissions.
element(SerializerNode $parent, SerializerNode $node, $contents)
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...