MediaWiki  master
SpecialPrefixindex.php
Go to the documentation of this file.
1 <?php
25 
32 
37  protected $stripPrefix = false;
38 
39  protected $hideRedirects = false;
40 
41  // Inherit $maxPerPage
42 
44  private $loadBalancer;
45 
47  private $linkCache;
48 
53  public function __construct(
56  ) {
57  parent::__construct( $loadBalancer );
58  $this->mName = 'Prefixindex';
59  $this->loadBalancer = $loadBalancer;
60  $this->linkCache = $linkCache;
61  }
62 
67  public function execute( $par ) {
68  $this->setHeaders();
69  $this->outputHeader();
70 
71  $out = $this->getOutput();
72  $out->addModuleStyles( 'mediawiki.special' );
73 
74  # GET values
75  $request = $this->getRequest();
76  $from = $request->getVal( 'from', '' );
77  $prefix = $request->getVal( 'prefix', '' );
78  $ns = $request->getIntOrNull( 'namespace' );
79  $namespace = (int)$ns; // if no namespace given, use 0 (NS_MAIN).
80  $this->hideRedirects = $request->getBool( 'hideredirects', $this->hideRedirects );
81  $this->stripPrefix = $request->getBool( 'stripprefix', $this->stripPrefix );
82 
83  $namespaces = $this->getContentLanguage()->getNamespaces();
84  $out->setPageTitle(
85  ( $namespace > 0 && array_key_exists( $namespace, $namespaces ) )
86  ? $this->msg( 'prefixindex-namespace', str_replace( '_', ' ', $namespaces[$namespace] ) )
87  : $this->msg( 'prefixindex' )
88  );
89 
90  $showme = '';
91  if ( $par !== null ) {
92  $showme = $par;
93  } elseif ( $prefix != '' ) {
94  $showme = $prefix;
95  } elseif ( $from != '' && $ns === null ) {
96  // For back-compat with Special:Allpages
97  // Don't do this if namespace is passed, so paging works when doing NS views.
98  $showme = $from;
99  }
100 
101  // T29864: if transcluded, show all pages instead of the form.
102  if ( $this->including() || $showme != '' || $ns !== null ) {
103  $this->showPrefixChunk( $namespace, $showme, $from );
104  } else {
105  $out->addHTML( $this->namespacePrefixForm( $namespace, null ) );
106  }
107  }
108 
115  protected function namespacePrefixForm( $namespace = NS_MAIN, $from = '' ) {
116  $formDescriptor = [
117  'prefix' => [
118  'label-message' => 'allpagesprefix',
119  'name' => 'prefix',
120  'id' => 'nsfrom',
121  'type' => 'text',
122  'size' => '30',
123  'default' => str_replace( '_', ' ', $from ),
124  ],
125  'namespace' => [
126  'type' => 'namespaceselect',
127  'name' => 'namespace',
128  'id' => 'namespace',
129  'label-message' => 'namespace',
130  'all' => null,
131  'default' => $namespace,
132  ],
133  'hidedirects' => [
134  'class' => HTMLCheckField::class,
135  'name' => 'hideredirects',
136  'label-message' => 'allpages-hide-redirects',
137  ],
138  'stripprefix' => [
139  'class' => HTMLCheckField::class,
140  'name' => 'stripprefix',
141  'label-message' => 'prefixindex-strip',
142  ],
143  ];
144  $context = new DerivativeContext( $this->getContext() );
145  $context->setTitle( $this->getPageTitle() ); // Remove subpage
146  $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $context )
147  ->setMethod( 'get' )
148  ->setWrapperLegendMsg( 'prefixindex' )
149  ->setSubmitTextMsg( 'prefixindex-submit' );
150 
151  return $htmlForm->prepareForm()->getHTML( false );
152  }
153 
159  protected function showPrefixChunk( $namespace, $prefix, $from = null ) {
160  if ( $from === null ) {
161  $from = $prefix;
162  }
163 
164  $fromList = $this->getNamespaceKeyAndText( $namespace, $from );
165  $prefixList = $this->getNamespaceKeyAndText( $namespace, $prefix );
166  $namespaces = $this->getContentLanguage()->getNamespaces();
167  $res = null;
168  $n = 0;
169  $nextRow = null;
170 
171  if ( !$prefixList || !$fromList ) {
172  $out = $this->msg( 'allpagesbadtitle' )->parseAsBlock();
173  } elseif ( !array_key_exists( $namespace, $namespaces ) ) {
174  // Show errormessage and reset to NS_MAIN
175  $out = $this->msg( 'allpages-bad-ns', $namespace )->parse();
176  $namespace = NS_MAIN;
177  } else {
178  list( $namespace, $prefixKey, $prefix ) = $prefixList;
179  list( /* $fromNS */, $fromKey, ) = $fromList;
180 
181  # ## @todo FIXME: Should complain if $fromNs != $namespace
182 
183  $dbr = $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA );
184 
185  $conds = [
186  'page_namespace' => $namespace,
187  'page_title' . $dbr->buildLike( $prefixKey, $dbr->anyString() ),
188  'page_title >= ' . $dbr->addQuotes( $fromKey ),
189  ];
190 
191  if ( $this->hideRedirects ) {
192  $conds['page_is_redirect'] = 0;
193  }
194 
195  $res = $dbr->select( 'page',
196  array_merge(
197  [ 'page_namespace', 'page_title' ],
199  ),
200  $conds,
201  __METHOD__,
202  [
203  'ORDER BY' => 'page_title',
204  'LIMIT' => $this->maxPerPage + 1,
205  'USE INDEX' => 'page_name_title',
206  ]
207  );
208 
209  // @todo FIXME: Side link to previous
210 
211  if ( $res->numRows() > 0 ) {
212  $out = Html::openElement( 'ul', [ 'class' => 'mw-prefixindex-list' ] );
213 
214  $prefixLength = strlen( $prefix );
215  foreach ( $res as $row ) {
216  if ( $n >= $this->maxPerPage ) {
217  $nextRow = $row;
218  break;
219  }
220  $title = Title::newFromRow( $row );
221  // Make sure it gets into LinkCache
222  $this->linkCache->addGoodLinkObjFromRow( $title, $row );
223  $displayed = $title->getText();
224  // Try not to generate unclickable links
225  if ( $this->stripPrefix && $prefixLength !== strlen( $displayed ) ) {
226  $displayed = substr( $displayed, $prefixLength );
227  }
228  $link = ( $title->isRedirect() ? '<div class="allpagesredirect">' : '' ) .
229  $this->getLinkRenderer()->makeKnownLink(
230  $title,
231  $displayed
232  ) .
233  ( $title->isRedirect() ? '</div>' : '' );
234 
235  $out .= "<li>$link</li>\n";
236  $n++;
237 
238  }
239  $out .= Html::closeElement( 'ul' );
240 
241  if ( $res->numRows() > 2 ) {
242  // Only apply CSS column styles if there's more than 2 entries.
243  // Otherwise rendering is broken as "mw-prefixindex-body"'s CSS column count is 3.
244  $out = Html::rawElement( 'div', [ 'class' => 'mw-prefixindex-body' ], $out );
245  }
246  } else {
247  $out = '';
248  }
249  }
250 
251  $output = $this->getOutput();
252 
253  if ( $this->including() ) {
254  // We don't show the nav-links and the form when included into other
255  // pages so let's just finish here.
256  $output->addHTML( $out );
257  return;
258  }
259 
260  $topOut = $this->namespacePrefixForm( $namespace, $prefix );
261 
262  if ( $res && ( $n == $this->maxPerPage ) && $nextRow ) {
263  $query = [
264  'from' => $nextRow->page_title,
265  'prefix' => $prefix,
266  'hideredirects' => $this->hideRedirects,
267  'stripprefix' => $this->stripPrefix,
268  ];
269 
270  if ( $namespace || $prefix == '' ) {
271  // Keep the namespace even if it's 0 for empty prefixes.
272  // This tells us we're not just a holdover from old links.
273  $query['namespace'] = $namespace;
274  }
275 
276  $nextLink = $this->getLinkRenderer()->makeKnownLink(
277  $this->getPageTitle(),
278  $this->msg( 'nextpage', str_replace( '_', ' ', $nextRow->page_title ) )->text(),
279  [],
280  $query
281  );
282 
283  // Link shown at the top of the page below the form
284  $topOut .= Html::rawElement( 'div',
285  [ 'class' => 'mw-prefixindex-nav' ],
286  $nextLink
287  );
288 
289  // Link shown at the footer
290  $out .= "\n" . Html::element( 'hr' ) .
292  'div',
293  [ 'class' => 'mw-prefixindex-nav' ],
294  $nextLink
295  );
296 
297  }
298 
299  $output->addHTML( $topOut . $out );
300  }
301 
302  protected function getGroupName() {
303  return 'pages';
304  }
305 }
SpecialPage\getPageTitle
getPageTitle( $subpage=false)
Get a self-referential title object.
Definition: SpecialPage.php:744
LinkCache
Cache for article titles (prefixed DB keys) and ids linked from one source.
Definition: LinkCache.php:40
SpecialPage\msg
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:912
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:790
SpecialPrefixindex\showPrefixChunk
showPrefixChunk( $namespace, $prefix, $from=null)
Definition: SpecialPrefixindex.php:159
SpecialPrefixindex\execute
execute( $par)
Entry point : initialise variables and call subfunctions.
Definition: SpecialPrefixindex.php:67
$res
$res
Definition: testCompression.php:57
LinkCache\getSelectFields
static getSelectFields()
Fields that LinkCache needs to select.
Definition: LinkCache.php:382
NS_MAIN
const NS_MAIN
Definition: Defines.php:64
$dbr
$dbr
Definition: testCompression.php:54
Html\closeElement
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:316
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:32
Title\newFromRow
static newFromRow( $row)
Make a Title object from a DB row.
Definition: Title.php:580
SpecialPrefixindex\$stripPrefix
$stripPrefix
Whether to remove the searched prefix from the displayed link.
Definition: SpecialPrefixindex.php:37
$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:618
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:302
SpecialPage\getContext
getContext()
Gets the context this SpecialPage is executed in.
Definition: SpecialPage.php:764
SpecialPrefixindex\namespacePrefixForm
namespacePrefixForm( $namespace=NS_MAIN, $from='')
HTML for the top form.
Definition: SpecialPrefixindex.php:115
SpecialAllPages\getNamespaceKeyAndText
getNamespaceKeyAndText( $ns, $text)
Definition: SpecialAllPages.php:369
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:780
SpecialPrefixindex\$hideRedirects
$hideRedirects
Definition: SpecialPrefixindex.php:39
SpecialPage\getLinkRenderer
getLinkRenderer()
Definition: SpecialPage.php:1028
SpecialAllPages
Implements Special:Allpages.
Definition: SpecialAllPages.php:33
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:252
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:210
SpecialPage\getContentLanguage
getContentLanguage()
Shortcut to get content language.
Definition: SpecialPage.php:840
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:232
SpecialPrefixindex\__construct
__construct(ILoadBalancer $loadBalancer, LinkCache $linkCache)
Definition: SpecialPrefixindex.php:53
SpecialPrefixindex
Implements Special:Prefixindex.
Definition: SpecialPrefixindex.php:31
SpecialPrefixindex\$linkCache
LinkCache $linkCache
Definition: SpecialPrefixindex.php:47
HTMLForm\factory
static factory( $displayFormat,... $arguments)
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:326
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:709
SpecialPage\including
including( $x=null)
Whether the special page is being evaluated via transclusion.
Definition: SpecialPage.php:266
Wikimedia\Rdbms\ILoadBalancer
Database cluster connection, tracking, load balancing, and transaction manager interface.
Definition: ILoadBalancer.php:81
SpecialPrefixindex\$loadBalancer
ILoadBalancer $loadBalancer
Definition: SpecialPrefixindex.php:44