MediaWiki master
SpecialSpecialPages.php
Go to the documentation of this file.
1<?php
7namespace MediaWiki\Specials;
8
12use OOUI\FieldLayout;
13use OOUI\SearchInputWidget;
14use Wikimedia\Parsoid\Core\SectionMetadata;
15use Wikimedia\Parsoid\Core\TOCData;
16
23
24 public function __construct() {
25 parent::__construct( 'Specialpages' );
26 }
27
29 public function execute( $par ) {
30 $out = $this->getOutput();
31 $this->setHeaders();
32 $this->outputHeader();
33 $out->getMetadata()->setPreventClickjacking( false );
34 $out->addModuleStyles( 'mediawiki.special' );
35
36 $groups = $this->getPageGroups();
37
38 if ( $groups === false ) {
39 return;
40 }
41
42 $this->addHelpLink( 'Help:Special pages' );
43 $this->outputPageList( $groups );
44 }
45
47 private function getPageGroups() {
48 $pages = $this->getSpecialPageFactory()->getUsablePages( $this->getUser(), $this->getContext() );
49
50 if ( $pages === [] ) {
51 // Yeah, that was pointless. Thanks for coming.
52 return false;
53 }
54
55 // Put them into a sortable array
56 $groups = [];
57 foreach ( $pages as $page ) {
58 $group = $page->getFinalGroupName();
59 $desc = $page->getDescription();
60 // (T360723) Only show an entry if the message isn't blanked, to allow on-wiki unlisting
61 if ( !$desc->isDisabled() ) {
62 $groups[$group][$desc->text()] = [
63 $page->getPageTitle(),
64 $page->isRestricted(),
65 $page->isCached()
66 ];
67 }
68 }
69
70 // Sort
71 foreach ( $groups as $group => $sortedPages ) {
72 ksort( $groups[$group] );
73 }
74
75 // Always move "other" to end
76 if ( array_key_exists( 'other', $groups ) ) {
77 $other = $groups['other'];
78 unset( $groups['other'] );
79 $groups['other'] = $other;
80 }
81
82 return $groups;
83 }
84
85 private function outputPageList( array $groups ) {
86 $out = $this->getOutput();
87 $aliases = $this->getSpecialPageFactory()->getAliasList();
88 $out->addModules( 'mediawiki.special.specialpages' );
89 $out->enableOOUI();
90
91 // Legend
92 $includesRestrictedPages = false;
93 $includesCachedPages = false;
94 foreach ( $groups as $group => $sortedPages ) {
95 foreach ( $sortedPages as $desc => [ $title, $restricted, $cached ] ) {
96 if ( $cached ) {
97 $includesCachedPages = true;
98 }
99 if ( $restricted ) {
100 $includesRestrictedPages = true;
101 }
102 }
103 }
104
105 $notes = [];
106 if ( $includesRestrictedPages ) {
107 $restricedMsg = $this->msg( 'specialpages-note-restricted' );
108 if ( !$restricedMsg->isDisabled() ) {
109 $notes[] = $restricedMsg->parse();
110 }
111 }
112 if ( $includesCachedPages ) {
113 $cachedMsg = $this->msg( 'specialpages-note-cached' );
114 if ( !$cachedMsg->isDisabled() ) {
115 $notes[] = $cachedMsg->parse();
116 }
117 }
118 if ( $notes !== [] ) {
119 $legendHeading = $this->msg( 'specialpages-note-top' )->parse();
120
121 $legend = Html::rawElement(
122 'div',
123 [ 'class' => [ 'mw-changeslist-legend', 'mw-specialpages-notes' ] ],
124 $legendHeading . implode( "\n", $notes )
125 );
126
127 $out->addHTML( $legend );
128 $out->addModuleStyles( 'mediawiki.special.changeslist.legend' );
129 }
130
131 $out->addHTML( ( new FieldLayout(
132 new SearchInputWidget( [
133 'placeholder' => $this->msg( 'specialpages-header-search' )->text(),
134 ] ),
135 [
136 'classes' => [ 'mw-special-pages-search' ],
137 'label' => $this->msg( 'specialpages-header-search' )->text(),
138 'invisibleLabel' => true,
139 'infusable' => true,
140 ]
141 ) )->toString() );
142
143 // Format table of contents
144 $tocData = new TOCData();
145 $tocLength = 0;
146 foreach ( $groups as $group => $sortedPages ) {
147 if ( !str_contains( $group, '/' ) ) {
148 ++$tocLength;
149 $tocData->addSection( new SectionMetadata(
150 1,
151 2,
152 $this->msg( "specialpages-group-$group" )->escaped(),
153 $this->getLanguage()->formatNum( $tocLength ),
154 (string)$tocLength,
155 null,
156 null,
157 "mw-specialpagesgroup-$group",
158 "mw-specialpagesgroup-$group"
159 ) );
160 }
161 }
162
163 $out->addTOCPlaceholder( $tocData );
164
165 // Format contents
166 $language = $this->getLanguage();
167 foreach ( $groups as $group => $sortedPages ) {
168 if ( str_contains( $group, '/' ) ) {
169 [ $group, $subGroup ] = explode( '/', $group, 2 );
170 $out->addHTML( Html::element(
171 'h3',
172 [ 'class' => "mw-specialpagessubgroup" ],
173 $this->msg( "specialpages-group-$group-$subGroup" )->text()
174 ) . "\n" );
175 } else {
176 $out->addHTML( Html::element(
177 'h2',
178 [ 'class' => "mw-specialpagesgroup", 'id' => "mw-specialpagesgroup-$group" ],
179 $this->msg( "specialpages-group-$group" )->text()
180 ) . "\n" );
181 }
182 $out->addHTML(
183 Html::openElement( 'div', [ 'class' => 'mw-specialpages-list' ] )
184 . '<ul>'
185 );
186 foreach ( $sortedPages as $desc => [ $title, $restricted, $cached ] ) {
187 $indexAttr = [ 'data-search-index-0' => $language->lc( $title->getText() ) ];
188 $c = 1;
189 foreach ( $aliases as $alias => $target ) {
191 if (
192 $target == $title->getText() &&
193 $language->lc( $alias ) !== $language->lc( $title->getText() )
194 ) {
195 $indexAttr['data-search-index-' . $c ] = $language->lc( $alias );
196 ++$c;
197 }
198 }
199 $pageClasses = [];
200 if ( $cached ) {
201 $pageClasses[] = 'mw-specialpagecached';
202 }
203 if ( $restricted ) {
204 $pageClasses[] = 'mw-specialpagerestricted';
205 }
206
207 $link = $this->getLinkRenderer()->makeKnownLink( $title, $desc );
208 $out->addHTML( Html::rawElement(
209 'li',
210 $indexAttr + [ 'class' => $pageClasses ],
211 $link
212 ) . "\n" );
213 }
214 $out->addHTML(
215 Html::closeElement( 'ul' ) .
216 Html::closeElement( 'div' )
217 );
218 }
219 }
220}
221
226class_alias( SpecialSpecialPages::class, 'SpecialSpecialpages' );
This class is a collection of static functions that serve two purposes:
Definition Html.php:43
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getUser()
Shortcut to get the User executing this instance.
getContext()
Gets the context this SpecialPage is executed in.
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.This must be overridden by subclasses; it will be made...
Represents a title within MediaWiki.
Definition Title.php:69
element(SerializerNode $parent, SerializerNode $node, $contents)