MediaWiki  master
SpecialPrefixindex.php
Go to the documentation of this file.
1 <?php
24 
31 
36  protected $stripPrefix = false;
37 
38  protected $hideRedirects = false;
39 
40  // Inherit $maxPerPage
41 
42  public function __construct() {
43  parent::__construct( 'Prefixindex' );
44  }
45 
50  public function execute( $par ) {
51  $this->setHeaders();
52  $this->outputHeader();
53 
54  $out = $this->getOutput();
55  $out->addModuleStyles( 'mediawiki.special' );
56 
57  # GET values
58  $request = $this->getRequest();
59  $from = $request->getVal( 'from', '' );
60  $prefix = $request->getVal( 'prefix', '' );
61  $ns = $request->getIntOrNull( 'namespace' );
62  $namespace = (int)$ns; // if no namespace given, use 0 (NS_MAIN).
63  $this->hideRedirects = $request->getBool( 'hideredirects', $this->hideRedirects );
64  $this->stripPrefix = $request->getBool( 'stripprefix', $this->stripPrefix );
65 
66  $namespaces = MediaWikiServices::getInstance()->getContentLanguage()->getNamespaces();
67  $out->setPageTitle(
68  ( $namespace > 0 && array_key_exists( $namespace, $namespaces ) )
69  ? $this->msg( 'prefixindex-namespace', str_replace( '_', ' ', $namespaces[$namespace] ) )
70  : $this->msg( 'prefixindex' )
71  );
72 
73  $showme = '';
74  if ( $par !== null ) {
75  $showme = $par;
76  } elseif ( $prefix != '' ) {
77  $showme = $prefix;
78  } elseif ( $from != '' && $ns === null ) {
79  // For back-compat with Special:Allpages
80  // Don't do this if namespace is passed, so paging works when doing NS views.
81  $showme = $from;
82  }
83 
84  // T29864: if transcluded, show all pages instead of the form.
85  if ( $this->including() || $showme != '' || $ns !== null ) {
86  $this->showPrefixChunk( $namespace, $showme, $from );
87  } else {
88  $out->addHTML( $this->namespacePrefixForm( $namespace, null ) );
89  }
90  }
91 
98  protected function namespacePrefixForm( $namespace = NS_MAIN, $from = '' ) {
99  $formDescriptor = [
100  'prefix' => [
101  'label-message' => 'allpagesprefix',
102  'name' => 'prefix',
103  'id' => 'nsfrom',
104  'type' => 'text',
105  'size' => '30',
106  'default' => str_replace( '_', ' ', $from ),
107  ],
108  'namespace' => [
109  'type' => 'namespaceselect',
110  'name' => 'namespace',
111  'id' => 'namespace',
112  'label-message' => 'namespace',
113  'all' => null,
114  'default' => $namespace,
115  ],
116  'hidedirects' => [
117  'class' => HTMLCheckField::class,
118  'name' => 'hideredirects',
119  'label-message' => 'allpages-hide-redirects',
120  ],
121  'stripprefix' => [
122  'class' => HTMLCheckField::class,
123  'name' => 'stripprefix',
124  'label-message' => 'prefixindex-strip',
125  ],
126  ];
127  $context = new DerivativeContext( $this->getContext() );
128  $context->setTitle( $this->getPageTitle() ); // Remove subpage
129  $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $context )
130  ->setMethod( 'get' )
131  ->setWrapperLegendMsg( 'prefixindex' )
132  ->setSubmitTextMsg( 'prefixindex-submit' );
133 
134  return $htmlForm->prepareForm()->getHTML( false );
135  }
136 
142  protected function showPrefixChunk( $namespace, $prefix, $from = null ) {
143  if ( $from === null ) {
144  $from = $prefix;
145  }
146 
147  $fromList = $this->getNamespaceKeyAndText( $namespace, $from );
148  $prefixList = $this->getNamespaceKeyAndText( $namespace, $prefix );
149  $namespaces = MediaWikiServices::getInstance()->getContentLanguage()->getNamespaces();
150  $res = null;
151  $n = 0;
152  $nextRow = null;
153 
154  if ( !$prefixList || !$fromList ) {
155  $out = $this->msg( 'allpagesbadtitle' )->parseAsBlock();
156  } elseif ( !array_key_exists( $namespace, $namespaces ) ) {
157  // Show errormessage and reset to NS_MAIN
158  $out = $this->msg( 'allpages-bad-ns', $namespace )->parse();
159  $namespace = NS_MAIN;
160  } else {
161  list( $namespace, $prefixKey, $prefix ) = $prefixList;
162  list( /* $fromNS */, $fromKey, ) = $fromList;
163 
164  # ## @todo FIXME: Should complain if $fromNs != $namespace
165 
166  $dbr = wfGetDB( DB_REPLICA );
167 
168  $conds = [
169  'page_namespace' => $namespace,
170  'page_title' . $dbr->buildLike( $prefixKey, $dbr->anyString() ),
171  'page_title >= ' . $dbr->addQuotes( $fromKey ),
172  ];
173 
174  if ( $this->hideRedirects ) {
175  $conds['page_is_redirect'] = 0;
176  }
177 
178  $res = $dbr->select( 'page',
179  array_merge(
180  [ 'page_namespace', 'page_title' ],
182  ),
183  $conds,
184  __METHOD__,
185  [
186  'ORDER BY' => 'page_title',
187  'LIMIT' => $this->maxPerPage + 1,
188  'USE INDEX' => 'name_title',
189  ]
190  );
191 
192  // @todo FIXME: Side link to previous
193 
194  if ( $res->numRows() > 0 ) {
195  $out = Html::openElement( 'ul', [ 'class' => 'mw-prefixindex-list' ] );
196  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
197 
198  $prefixLength = strlen( $prefix );
199  foreach ( $res as $row ) {
200  if ( $n >= $this->maxPerPage ) {
201  $nextRow = $row;
202  break;
203  }
204  $title = Title::newFromRow( $row );
205  // Make sure it gets into LinkCache
206  $linkCache->addGoodLinkObjFromRow( $title, $row );
207  $displayed = $title->getText();
208  // Try not to generate unclickable links
209  if ( $this->stripPrefix && $prefixLength !== strlen( $displayed ) ) {
210  $displayed = substr( $displayed, $prefixLength );
211  }
212  $link = ( $title->isRedirect() ? '<div class="allpagesredirect">' : '' ) .
213  $this->getLinkRenderer()->makeKnownLink(
214  $title,
215  $displayed
216  ) .
217  ( $title->isRedirect() ? '</div>' : '' );
218 
219  $out .= "<li>$link</li>\n";
220  $n++;
221 
222  }
223  $out .= Html::closeElement( 'ul' );
224 
225  if ( $res->numRows() > 2 ) {
226  // Only apply CSS column styles if there's more than 2 entries.
227  // Otherwise rendering is broken as "mw-prefixindex-body"'s CSS column count is 3.
228  $out = Html::rawElement( 'div', [ 'class' => 'mw-prefixindex-body' ], $out );
229  }
230  } else {
231  $out = '';
232  }
233  }
234 
235  $output = $this->getOutput();
236 
237  if ( $this->including() ) {
238  // We don't show the nav-links and the form when included into other
239  // pages so let's just finish here.
240  $output->addHTML( $out );
241  return;
242  }
243 
244  $topOut = $this->namespacePrefixForm( $namespace, $prefix );
245 
246  if ( $res && ( $n == $this->maxPerPage ) && $nextRow ) {
247  $query = [
248  'from' => $nextRow->page_title,
249  'prefix' => $prefix,
250  'hideredirects' => $this->hideRedirects,
251  'stripprefix' => $this->stripPrefix,
252  ];
253 
254  if ( $namespace || $prefix == '' ) {
255  // Keep the namespace even if it's 0 for empty prefixes.
256  // This tells us we're not just a holdover from old links.
257  $query['namespace'] = $namespace;
258  }
259 
260  $nextLink = $this->getLinkRenderer()->makeKnownLink(
261  $this->getPageTitle(),
262  $this->msg( 'nextpage', str_replace( '_', ' ', $nextRow->page_title ) )->text(),
263  [],
264  $query
265  );
266 
267  // Link shown at the top of the page below the form
268  $topOut .= Html::rawElement( 'div',
269  [ 'class' => 'mw-prefixindex-nav' ],
270  $nextLink
271  );
272 
273  // Link shown at the footer
274  $out .= "\n" . Html::element( 'hr' ) .
276  'div',
277  [ 'class' => 'mw-prefixindex-nav' ],
278  $nextLink
279  );
280 
281  }
282 
283  $output->addHTML( $topOut . $out );
284  }
285 
294  public function prefixSearchSubpages( $search, $limit, $offset ) {
295  return $this->prefixSearchString( $search, $limit, $offset );
296  }
297 
298  protected function getGroupName() {
299  return 'pages';
300  }
301 }
SpecialPage\getPageTitle
getPageTitle( $subpage=false)
Get a self-referential title object.
Definition: SpecialPage.php:697
SpecialPage\msg
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:828
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:744
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:160
SpecialPrefixindex\showPrefixChunk
showPrefixChunk( $namespace, $prefix, $from=null)
Definition: SpecialPrefixindex.php:142
SpecialPrefixindex\execute
execute( $par)
Entry point : initialise variables and call subfunctions.
Definition: SpecialPrefixindex.php:50
$res
$res
Definition: testCompression.php:57
LinkCache\getSelectFields
static getSelectFields()
Fields that LinkCache needs to select.
Definition: LinkCache.php:231
$dbr
$dbr
Definition: testCompression.php:54
NS_MAIN
const NS_MAIN
Definition: Defines.php:69
Html\closeElement
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:315
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:31
SpecialPage\prefixSearchString
prefixSearchString( $search, $limit, $offset)
Perform a regular substring search for prefixSearchSubpages.
Definition: SpecialPage.php:534
Title\newFromRow
static newFromRow( $row)
Make a Title object from a DB row.
Definition: Title.php:523
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2475
SpecialPrefixindex\$stripPrefix
$stripPrefix
Whether to remove the searched prefix from the displayed link.
Definition: SpecialPrefixindex.php:36
$title
$title
Definition: testCompression.php:38
SpecialPage\setHeaders
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!...
Definition: SpecialPage.php:571
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
SpecialPrefixindex\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: SpecialPrefixindex.php:298
SpecialPage\getContext
getContext()
Gets the context this SpecialPage is executed in.
Definition: SpecialPage.php:717
SpecialPrefixindex\namespacePrefixForm
namespacePrefixForm( $namespace=NS_MAIN, $from='')
HTML for the top form.
Definition: SpecialPrefixindex.php:98
SpecialAllPages\getNamespaceKeyAndText
getNamespaceKeyAndText( $ns, $text)
Definition: SpecialAllPages.php:353
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:734
SpecialPrefixindex\$hideRedirects
$hideRedirects
Definition: SpecialPrefixindex.php:38
SpecialPage\getLinkRenderer
getLinkRenderer()
Definition: SpecialPage.php:945
SpecialPrefixindex\__construct
__construct()
Definition: SpecialPrefixindex.php:42
SpecialAllPages
Implements Special:Allpages.
Definition: SpecialAllPages.php:30
Html\openElement
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:251
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
SpecialPrefixindex\prefixSearchSubpages
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
Definition: SpecialPrefixindex.php:294
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
SpecialPrefixindex
Implements Special:Prefixindex.
Definition: SpecialPrefixindex.php:30
HTMLForm\factory
static factory( $displayFormat,... $arguments)
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:315
SpecialPage\outputHeader
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
Definition: SpecialPage.php:662
SpecialPage\including
including( $x=null)
Whether the special page is being evaluated via transclusion.
Definition: SpecialPage.php:251