MediaWiki  master
IndexPager.php
Go to the documentation of this file.
1 <?php
24 use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
30 
74 abstract class IndexPager extends ContextSource implements Pager {
75  use ProtectedHookAccessorTrait;
76 
78  public const DIR_ASCENDING = false;
80  public const DIR_DESCENDING = true;
81 
83  public const QUERY_ASCENDING = true;
85  public const QUERY_DESCENDING = false;
86 
88  public $mRequest;
90  public $mLimitsShown = [ 20, 50, 100, 250, 500 ];
92  public $mDefaultLimit = 50;
94  public $mOffset;
96  public $mLimit;
98  public $mQueryDone = false;
100  public $mDb;
103 
110  protected $mIndexField;
116  protected $mExtraSortFields;
120  protected $mOrderType;
136 
138  public $mIsFirst;
140  public $mIsLast;
141 
143  protected $mLastShown;
145  protected $mFirstShown;
147  protected $mPastTheEndIndex;
149  protected $mDefaultQuery;
151  protected $mNavigationBar;
152 
157  protected $mIncludeOffset = false;
158 
164  public $mResult;
165 
167  private $linkRenderer;
168 
175  public function __construct( IContextSource $context = null, LinkRenderer $linkRenderer = null ) {
176  if ( $context ) {
177  $this->setContext( $context );
178  }
179 
180  $this->mRequest = $this->getRequest();
181 
182  # NB: the offset is quoted, not validated. It is treated as an
183  # arbitrary string to support the widest variety of index types. Be
184  # careful outputting it into HTML!
185  $this->mOffset = $this->mRequest->getText( 'offset' );
186 
187  # Use consistent behavior for the limit options
188  $this->mDefaultLimit = MediaWikiServices::getInstance()
189  ->getUserOptionsLookup()
190  ->getIntOption( $this->getUser(), 'rclimit' );
191  if ( !$this->mLimit ) {
192  // Don't override if a subclass calls $this->setLimit() in its constructor.
193  list( $this->mLimit, /* $offset */ ) = $this->mRequest
194  ->getLimitOffsetForUser( $this->getUser() );
195  }
196 
197  $this->mIsBackwards = ( $this->mRequest->getVal( 'dir' ) == 'prev' );
198  # Let the subclass set the DB here; otherwise use a replica DB for the current wiki
199  $this->mDb = $this->mDb ?: wfGetDB( DB_REPLICA );
200 
201  $index = $this->getIndexField(); // column to sort on
202  $extraSort = $this->getExtraSortFields(); // extra columns to sort on for query planning
203  $order = $this->mRequest->getVal( 'order' );
204 
205  if ( is_array( $index ) && isset( $index[$order] ) ) {
206  $this->mOrderType = $order;
207  $this->mIndexField = $index[$order];
208  $this->mExtraSortFields = isset( $extraSort[$order] )
209  ? (array)$extraSort[$order]
210  : [];
211  } elseif ( is_array( $index ) ) {
212  # First element is the default
213  $this->mIndexField = reset( $index );
214  $this->mOrderType = key( $index );
215  $this->mExtraSortFields = isset( $extraSort[$this->mOrderType] )
216  ? (array)$extraSort[$this->mOrderType]
217  : [];
218  } else {
219  # $index is not an array
220  $this->mOrderType = null;
221  $this->mIndexField = $index;
222  $isSortAssociative = array_values( $extraSort ) !== $extraSort;
223  if ( $isSortAssociative ) {
224  $this->mExtraSortFields = isset( $extraSort[$index] )
225  ? (array)$extraSort[$index]
226  : [];
227  } else {
228  $this->mExtraSortFields = (array)$extraSort;
229  }
230  }
231 
232  if ( !isset( $this->mDefaultDirection ) ) {
233  $dir = $this->getDefaultDirections();
234  $this->mDefaultDirection = is_array( $dir )
235  ? $dir[$this->mOrderType]
236  : $dir;
237  }
238  $this->linkRenderer = $linkRenderer;
239  }
240 
248  public function getDatabase() {
249  return $this->mDb;
250  }
251 
259  public function doQuery() {
260  $defaultOrder = ( $this->mDefaultDirection === self::DIR_ASCENDING )
261  ? self::QUERY_ASCENDING
262  : self::QUERY_DESCENDING;
263  $order = $this->mIsBackwards ? self::oppositeOrder( $defaultOrder ) : $defaultOrder;
264 
265  # Plus an extra row so that we can tell the "next" link should be shown
266  $queryLimit = $this->mLimit + 1;
267 
268  if ( $this->mOffset == '' ) {
269  $isFirst = true;
270  } else {
271  // If there's an offset, we may or may not be at the first entry.
272  // The only way to tell is to run the query in the opposite
273  // direction see if we get a row.
274  $oldIncludeOffset = $this->mIncludeOffset;
275  $this->mIncludeOffset = !$this->mIncludeOffset;
276  $oppositeOrder = self::oppositeOrder( $order );
277  $isFirst = !$this->reallyDoQuery( $this->mOffset, 1, $oppositeOrder )->numRows();
278  $this->mIncludeOffset = $oldIncludeOffset;
279  }
280 
281  $this->mResult = $this->reallyDoQuery(
282  $this->mOffset,
283  $queryLimit,
284  $order
285  );
286 
287  $this->extractResultInfo( $isFirst, $queryLimit, $this->mResult );
288  $this->mQueryDone = true;
289 
290  $this->preprocessResults( $this->mResult );
291  $this->mResult->rewind(); // Paranoia
292  }
293 
298  final protected static function oppositeOrder( $order ) {
299  return ( $order === self::QUERY_ASCENDING )
302  }
303 
307  public function getResult() {
308  return $this->mResult;
309  }
310 
314  public function getResultOffset() {
315  return $this->mResult->key();
316  }
317 
323  public function setOffset( $offset ) {
324  $this->mOffset = $offset;
325  }
326 
336  public function setLimit( $limit ) {
337  $limit = (int)$limit;
338  // WebRequest::getLimitOffsetForUser() puts a cap of 5000, so do same here.
339  if ( $limit > 5000 ) {
340  $limit = 5000;
341  }
342  if ( $limit > 0 ) {
343  $this->mLimit = $limit;
344  }
345  }
346 
352  public function getLimit() {
353  return $this->mLimit;
354  }
355 
363  public function setIncludeOffset( $include ) {
364  $this->mIncludeOffset = $include;
365  }
366 
378  protected function extractResultInfo( $isFirst, $limit, IResultWrapper $res ) {
379  $numRows = $res->numRows();
380 
381  $firstIndex = [];
382  $lastIndex = [];
383  $this->mPastTheEndIndex = [];
384  $this->mPastTheEndRow = null;
385 
386  if ( $numRows ) {
387  $indexColumns = array_map( static function ( $v ) {
388  // Remove any table prefix from index field
389  $parts = explode( '.', $v );
390  return end( $parts );
391  }, (array)$this->mIndexField );
392 
393  $row = $res->fetchRow();
394  foreach ( $indexColumns as $indexColumn ) {
395  $firstIndex[] = $row[$indexColumn];
396  }
397 
398  # Discard the extra result row if there is one
399  if ( $numRows > $this->mLimit && $numRows > 1 ) {
400  $res->seek( $numRows - 1 );
401  $this->mPastTheEndRow = $res->fetchObject();
402  foreach ( $indexColumns as $indexColumn ) {
403  $this->mPastTheEndIndex[] = $this->mPastTheEndRow->$indexColumn;
404  }
405  $res->seek( $numRows - 2 );
406  $row = $res->fetchRow();
407  foreach ( $indexColumns as $indexColumn ) {
408  $lastIndex[] = $row[$indexColumn];
409  }
410  } else {
411  $this->mPastTheEndRow = null;
412  $res->seek( $numRows - 1 );
413  $row = $res->fetchRow();
414  foreach ( $indexColumns as $indexColumn ) {
415  $lastIndex[] = $row[$indexColumn];
416  }
417  }
418  }
419 
420  if ( $this->mIsBackwards ) {
421  $this->mIsFirst = ( $numRows < $limit );
422  $this->mIsLast = $isFirst;
423  $this->mLastShown = $firstIndex;
424  $this->mFirstShown = $lastIndex;
425  } else {
426  $this->mIsFirst = $isFirst;
427  $this->mIsLast = ( $numRows < $limit );
428  $this->mLastShown = $lastIndex;
429  $this->mFirstShown = $firstIndex;
430  }
431  }
432 
440  protected function getSqlComment() {
441  return static::class;
442  }
443 
456  public function reallyDoQuery( $offset, $limit, $order ) {
457  list( $tables, $fields, $conds, $fname, $options, $join_conds ) =
458  $this->buildQueryInfo( $offset, $limit, $order );
459 
460  return $this->mDb->select( $tables, $fields, $conds, $fname, $options, $join_conds );
461  }
462 
475  protected function buildQueryInfo( $offset, $limit, $order ) {
476  $fname = __METHOD__ . ' (' . $this->getSqlComment() . ')';
477  $info = $this->getQueryInfo();
478  $tables = $info['tables'];
479  $fields = $info['fields'];
480  $conds = $info['conds'] ?? [];
481  $options = $info['options'] ?? [];
482  $join_conds = $info['join_conds'] ?? [];
483  $indexColumns = (array)$this->mIndexField;
484  $sortColumns = array_merge( $indexColumns, $this->mExtraSortFields );
485 
486  if ( $order === self::QUERY_ASCENDING ) {
487  $options['ORDER BY'] = $sortColumns;
488  $operator = $this->mIncludeOffset ? '>=' : '>';
489  } else {
490  $orderBy = [];
491  foreach ( $sortColumns as $col ) {
492  $orderBy[] = $col . ' DESC';
493  }
494  $options['ORDER BY'] = $orderBy;
495  $operator = $this->mIncludeOffset ? '<=' : '<';
496  }
497  if ( $offset != '' ) {
498  $offsets = explode( '|', $offset, /* Limit to max of indices */ count( $indexColumns ) );
499 
500  $conds[] = $this->buildOffsetConds(
501  $offsets,
502  $indexColumns,
503  $operator
504  );
505  }
506  $options['LIMIT'] = intval( $limit );
507  return [ $tables, $fields, $conds, $fname, $options, $join_conds ];
508  }
509 
546  private function buildOffsetConds( $offsets, $columns, $operator ) {
547  $innerConds = [];
548  // $offsets and $columns are the same length
549  for ( $i = 1; $i <= count( $offsets ); $i++ ) {
550  $innerConds[] = $this->buildOffsetInnerConds(
551  array_slice( $offsets, 0, $i ),
552  array_slice( $columns, 0, $i ),
553  $operator
554  );
555  }
556  return $this->mDb->makeList( $innerConds, IDatabase::LIST_OR );
557  }
558 
568  private function buildOffsetInnerConds( $offsets, $columns, $operator ) {
569  $conds = [];
570  while ( count( $offsets ) > 1 ) {
571  $conds[] = $columns[0] . '=' . $this->mDb->addQuotes( $offsets[0] );
572  array_shift( $columns );
573  array_shift( $offsets );
574  }
575  $conds[] = $columns[0] . $operator . $this->mDb->addQuotes( $offsets[0] );
576  return $this->mDb->makeList( $conds, IDatabase::LIST_AND );
577  }
578 
586  protected function preprocessResults( $result ) {
587  }
588 
597  public function getBody() {
598  $this->getOutput()->addModuleStyles( $this->getModuleStyles() );
599  if ( !$this->mQueryDone ) {
600  $this->doQuery();
601  }
602 
603  if ( $this->mResult->numRows() ) {
604  # Do any special query batches before display
605  $this->doBatchLookups();
606  }
607 
608  # Don't use any extra rows returned by the query
609  $numRows = min( $this->mResult->numRows(), $this->mLimit );
610 
611  $s = $this->getStartBody();
612  if ( $numRows ) {
613  if ( $this->mIsBackwards ) {
614  for ( $i = $numRows - 1; $i >= 0; $i-- ) {
615  $this->mResult->seek( $i );
616  $row = $this->mResult->fetchObject();
617  $s .= $this->formatRow( $row );
618  }
619  } else {
620  $this->mResult->seek( 0 );
621  for ( $i = 0; $i < $numRows; $i++ ) {
622  $row = $this->mResult->fetchObject();
623  $s .= $this->formatRow( $row );
624  }
625  }
626  } else {
627  $s .= $this->getEmptyBody();
628  }
629  $s .= $this->getEndBody();
630  return $s;
631  }
632 
640  public function getModuleStyles() {
641  return [ 'mediawiki.pager.styles' ];
642  }
643 
655  protected function makeLink( $text, array $query = null, $type = null ) {
656  if ( $query === null ) {
657  return $text;
658  }
659 
660  $attrs = [];
661  if ( in_array( $type, [ 'prev', 'next' ] ) ) {
662  $attrs['rel'] = $type;
663  }
664 
665  if ( in_array( $type, [ 'asc', 'desc' ] ) ) {
666  $attrs['title'] = $this->msg( $type == 'asc' ? 'sort-ascending' : 'sort-descending' )->text();
667  }
668 
669  if ( $type ) {
670  $attrs['class'] = "mw-{$type}link";
671  }
672 
673  return $this->getLinkRenderer()->makeKnownLink(
674  $this->getTitle(),
675  new HtmlArmor( $text ),
676  $attrs,
677  $query + $this->getDefaultQuery()
678  );
679  }
680 
690  protected function doBatchLookups() {
691  }
692 
699  protected function getStartBody() {
700  return '';
701  }
702 
710  protected function getEndBody() {
711  return '';
712  }
713 
722  protected function getEmptyBody() {
723  return '';
724  }
725 
735  public function getDefaultQuery() {
736  if ( !isset( $this->mDefaultQuery ) ) {
737  $this->mDefaultQuery = $this->getRequest()->getQueryValues();
738  unset( $this->mDefaultQuery['title'] );
739  unset( $this->mDefaultQuery['dir'] );
740  unset( $this->mDefaultQuery['offset'] );
741  unset( $this->mDefaultQuery['limit'] );
742  unset( $this->mDefaultQuery['order'] );
743  unset( $this->mDefaultQuery['month'] );
744  unset( $this->mDefaultQuery['year'] );
745  }
746  return $this->mDefaultQuery;
747  }
748 
754  public function getNumRows() {
755  if ( !$this->mQueryDone ) {
756  $this->doQuery();
757  }
758  return $this->mResult->numRows();
759  }
760 
768  public function getPagingQueries() {
769  if ( !$this->mQueryDone ) {
770  $this->doQuery();
771  }
772 
773  # Don't announce the limit everywhere if it's the default
774  $urlLimit = $this->mLimit == $this->mDefaultLimit ? null : $this->mLimit;
775 
776  if ( $this->mIsFirst ) {
777  $prev = false;
778  $first = false;
779  } else {
780  $prev = [
781  'dir' => 'prev',
782  'offset' => implode( '|', (array)$this->mFirstShown ),
783  'limit' => $urlLimit
784  ];
785  $first = [ 'limit' => $urlLimit ];
786  }
787  if ( $this->mIsLast ) {
788  $next = false;
789  $last = false;
790  } else {
791  $next = [ 'offset' => implode( '|', (array)$this->mLastShown ), 'limit' => $urlLimit ];
792  $last = [ 'dir' => 'prev', 'limit' => $urlLimit ];
793  }
794 
795  return [
796  'prev' => $prev,
797  'next' => $next,
798  'first' => $first,
799  'last' => $last
800  ];
801  }
802 
809  protected function isNavigationBarShown() {
810  if ( !$this->mQueryDone ) {
811  $this->doQuery();
812  }
813  // Hide navigation by default if there is nothing to page
814  return !( $this->mIsFirst && $this->mIsLast );
815  }
816 
827  protected function getPagingLinks( $linkTexts, $disabledTexts = [] ) {
828  $queries = $this->getPagingQueries();
829  $links = [];
830 
831  foreach ( $queries as $type => $query ) {
832  if ( $query !== false ) {
833  $links[$type] = $this->makeLink(
834  $linkTexts[$type],
835  $query,
836  $type
837  );
838  } elseif ( isset( $disabledTexts[$type] ) ) {
839  $links[$type] = $disabledTexts[$type];
840  } else {
841  $links[$type] = $linkTexts[$type];
842  }
843  }
844 
845  return $links;
846  }
847 
848  protected function getLimitLinks() {
849  $links = [];
850  if ( $this->mIsBackwards ) {
851  $offset = implode( '|', (array)$this->mPastTheEndIndex );
852  } else {
853  $offset = $this->mOffset;
854  }
855  foreach ( $this->mLimitsShown as $limit ) {
856  $links[] = $this->makeLink(
857  $this->getLanguage()->formatNum( $limit ),
858  [ 'offset' => $offset, 'limit' => $limit ],
859  'num'
860  );
861  }
862  return $links;
863  }
864 
872  abstract public function formatRow( $row );
873 
885  abstract public function getQueryInfo();
886 
923  abstract public function getIndexField();
924 
948  protected function getExtraSortFields() {
949  return [];
950  }
951 
973  protected function getDefaultDirections() {
974  return self::DIR_ASCENDING;
975  }
976 
987  protected function buildPrevNextNavigation(
988  Title $title,
989  $offset,
990  $limit,
991  array $query = [],
992  $atend = false
993  ) {
994  $prevNext = new PrevNextNavigationRenderer( $this );
995 
996  return $prevNext->buildPrevNextNavigation( $title, $offset, $limit, $query, $atend );
997  }
998 
1003  protected function getLinkRenderer() {
1004  if ( $this->linkRenderer === null ) {
1005  $this->linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
1006  }
1007  return $this->linkRenderer;
1008  }
1009 }
LIST_OR
const LIST_OR
Definition: Defines.php:46
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:39
IndexPager\$mLimit
int $mLimit
The maximum number of entries to show.
Definition: IndexPager.php:96
IndexPager\formatRow
formatRow( $row)
Returns an HTML string representing the result row $row.
HtmlArmor
Marks HTML that shouldn't be escaped.
Definition: HtmlArmor.php:30
IndexPager\getStartBody
getStartBody()
Hook into getBody(), allows text to be inserted at the start.
Definition: IndexPager.php:699
IndexPager\$mDefaultDirection
bool $mDefaultDirection
$mDefaultDirection gives the direction to use when sorting results: DIR_ASCENDING or DIR_DESCENDING.
Definition: IndexPager.php:133
IndexPager\$mPastTheEndIndex
array $mPastTheEndIndex
Definition: IndexPager.php:147
IndexPager\preprocessResults
preprocessResults( $result)
Pre-process results; useful for performing batch existence checks, etc.
Definition: IndexPager.php:586
IndexPager\getDefaultQuery
getDefaultQuery()
Get an array of query parameters that should be put into self-links.
Definition: IndexPager.php:735
IndexPager\$mIncludeOffset
bool $mIncludeOffset
Whether to include the offset in the query.
Definition: IndexPager.php:157
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:204
IndexPager\QUERY_ASCENDING
const QUERY_ASCENDING
Backwards-compatible constant for reallyDoQuery() (do not change)
Definition: IndexPager.php:83
IndexPager\getResult
getResult()
Definition: IndexPager.php:307
IndexPager\$mFirstShown
array $mFirstShown
Definition: IndexPager.php:145
MediaWiki\Linker\LinkRenderer
Class that generates HTML anchor link elements for pages.
Definition: LinkRenderer.php:43
IndexPager\$mLimitsShown
int[] $mLimitsShown
List of default entry limit options to be presented to clients.
Definition: IndexPager.php:90
IndexPager\getExtraSortFields
getExtraSortFields()
Returns the names of secondary columns to order by in addition to the column in getIndexField().
Definition: IndexPager.php:948
LIST_AND
const LIST_AND
Definition: Defines.php:43
IndexPager\getModuleStyles
getModuleStyles()
ResourceLoader modules that must be loaded to provide correct styling for this pager.
Definition: IndexPager.php:640
IndexPager\getDatabase
getDatabase()
Get the Database object in use.
Definition: IndexPager.php:248
IndexPager\getPagingQueries
getPagingQueries()
Get a URL query array for the prev, next, first and last links.
Definition: IndexPager.php:768
MediaWiki\Navigation\PrevNextNavigationRenderer
Helper class for generating prev/next links for paging.
Definition: PrevNextNavigationRenderer.php:33
IndexPager\$linkRenderer
LinkRenderer $linkRenderer
Definition: IndexPager.php:167
IndexPager\__construct
__construct(IContextSource $context=null, LinkRenderer $linkRenderer=null)
Definition: IndexPager.php:175
IndexPager\$mNavigationBar
string $mNavigationBar
Definition: IndexPager.php:151
IndexPager\makeLink
makeLink( $text, array $query=null, $type=null)
Make a self-link.
Definition: IndexPager.php:655
ContextSource\getRequest
getRequest()
Definition: ContextSource.php:81
IndexPager\buildPrevNextNavigation
buildPrevNextNavigation(Title $title, $offset, $limit, array $query=[], $atend=false)
Generate (prev x| next x) (20|50|100...) type links for paging.
Definition: IndexPager.php:987
$res
$res
Definition: testCompression.php:57
ContextSource\getUser
getUser()
Definition: ContextSource.php:136
ContextSource\getTitle
getTitle()
Definition: ContextSource.php:90
IndexPager\DIR_ASCENDING
const DIR_ASCENDING
Backwards-compatible constant for $mDefaultDirection field (do not change)
Definition: IndexPager.php:78
IndexPager\getLimitLinks
getLimitLinks()
Definition: IndexPager.php:848
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
IndexPager\doBatchLookups
doBatchLookups()
Called from getBody(), before getStartBody() is called and after doQuery() was called.
Definition: IndexPager.php:690
IndexPager\getIndexField
getIndexField()
Returns the name of the index field.
IndexPager\$mPastTheEndRow
stdClass bool null $mPastTheEndRow
Extra row fetched at the end to see if the end was reached.
Definition: IndexPager.php:102
ContextSource\getLanguage
getLanguage()
Definition: ContextSource.php:153
IndexPager\$mIndexField
string string[] $mIndexField
The index to actually be used for ordering.
Definition: IndexPager.php:110
Pager
Basic pager interface.
Definition: Pager.php:34
IndexPager\getEmptyBody
getEmptyBody()
Hook into getBody(), for the bit between the start and the end when there are no rows.
Definition: IndexPager.php:722
IndexPager\reallyDoQuery
reallyDoQuery( $offset, $limit, $order)
Do a query with specified parameters, rather than using the object context.
Definition: IndexPager.php:456
IndexPager\QUERY_DESCENDING
const QUERY_DESCENDING
Backwards-compatible constant for reallyDoQuery() (do not change)
Definition: IndexPager.php:85
IndexPager\$mQueryDone
bool $mQueryDone
Whether the listing query completed.
Definition: IndexPager.php:98
Wikimedia\Rdbms\IResultWrapper
Result wrapper for grabbing data queried from an IDatabase object.
Definition: IResultWrapper.php:26
IndexPager\buildQueryInfo
buildQueryInfo( $offset, $limit, $order)
Build variables to use by the database wrapper.
Definition: IndexPager.php:475
IndexPager\setLimit
setLimit( $limit)
Set the limit from an other source than the request.
Definition: IndexPager.php:336
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2186
IndexPager\$mIsLast
bool $mIsLast
Definition: IndexPager.php:140
ContextSource\getOutput
getOutput()
Definition: ContextSource.php:126
ContextSource
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
Definition: ContextSource.php:33
IndexPager\$mDb
IDatabase $mDb
Definition: IndexPager.php:100
$title
$title
Definition: testCompression.php:38
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
IndexPager\$mRequest
WebRequest $mRequest
Definition: IndexPager.php:88
IndexPager\extractResultInfo
extractResultInfo( $isFirst, $limit, IResultWrapper $res)
Extract some useful data from the result object for use by the navigation bar, put it into $this.
Definition: IndexPager.php:378
ContextSource\setContext
setContext(IContextSource $context)
Definition: ContextSource.php:63
IndexPager\setIncludeOffset
setIncludeOffset( $include)
Set whether a row matching exactly the offset should be also included in the result or not.
Definition: IndexPager.php:363
IndexPager\$mIsBackwards
bool $mIsBackwards
Definition: IndexPager.php:135
ContextSource\msg
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:197
IndexPager\oppositeOrder
static oppositeOrder( $order)
Definition: IndexPager.php:298
IndexPager\getDefaultDirections
getDefaultDirections()
Return the default sorting direction: DIR_ASCENDING or DIR_DESCENDING.
Definition: IndexPager.php:973
$s
foreach( $mmfl['setupFiles'] as $fileName) if( $queue) if(empty( $mmfl['quiet'])) $s
Definition: mergeMessageFileList.php:206
IndexPager\setOffset
setOffset( $offset)
Set the offset from an other source than the request.
Definition: IndexPager.php:323
IndexPager\$mResult
IResultWrapper $mResult
Result object for the query.
Definition: IndexPager.php:164
IndexPager\getLinkRenderer
getLinkRenderer()
Definition: IndexPager.php:1003
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:58
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:43
IndexPager\buildOffsetInnerConds
buildOffsetInnerConds( $offsets, $columns, $operator)
Build an inner part of an offset condition, consisting of inequalities joined by AND,...
Definition: IndexPager.php:568
IndexPager\DIR_DESCENDING
const DIR_DESCENDING
Backwards-compatible constant for $mDefaultDirection field (do not change)
Definition: IndexPager.php:80
IndexPager\getEndBody
getEndBody()
Hook into getBody() for the end of the list.
Definition: IndexPager.php:710
IndexPager\getSqlComment
getSqlComment()
Get some text to go in brackets in the "function name" part of the SQL comment.
Definition: IndexPager.php:440
IndexPager\isNavigationBarShown
isNavigationBarShown()
Returns whether to show the "navigation bar" @stable to override.
Definition: IndexPager.php:809
Title
Represents a title within MediaWiki.
Definition: Title.php:47
IndexPager\$mExtraSortFields
string[] $mExtraSortFields
An array of secondary columns to order by.
Definition: IndexPager.php:116
IndexPager\$mOrderType
string null $mOrderType
For pages that support multiple types of ordering, which one to use.
Definition: IndexPager.php:120
IndexPager\buildOffsetConds
buildOffsetConds( $offsets, $columns, $operator)
Build the conditions for the offset, given that we may be paginating on a single column or multiple c...
Definition: IndexPager.php:546
IndexPager
IndexPager is an efficient pager which uses a (roughly unique) index in the data set to implement pag...
Definition: IndexPager.php:74
IndexPager\getLimit
getLimit()
Get the current limit.
Definition: IndexPager.php:352
IndexPager\$mLastShown
array $mLastShown
Definition: IndexPager.php:143
IndexPager\getBody
getBody()
Get the formatted result list.
Definition: IndexPager.php:597
IndexPager\$mDefaultLimit
int $mDefaultLimit
The default entry limit choosen for clients.
Definition: IndexPager.php:92
IndexPager\$mOffset
mixed $mOffset
The starting point to enumerate entries.
Definition: IndexPager.php:94
IndexPager\getQueryInfo
getQueryInfo()
Provides all parameters needed for the main paged query.
IndexPager\$mDefaultQuery
array $mDefaultQuery
Definition: IndexPager.php:149
IndexPager\getNumRows
getNumRows()
Get the number of rows in the result set.
Definition: IndexPager.php:754
IndexPager\getPagingLinks
getPagingLinks( $linkTexts, $disabledTexts=[])
Get paging links.
Definition: IndexPager.php:827
IndexPager\$mIsFirst
bool $mIsFirst
True if the current result set is the first one.
Definition: IndexPager.php:138
IndexPager\getResultOffset
getResultOffset()
Definition: IndexPager.php:314
IndexPager\doQuery
doQuery()
Do the query, using information from the object context.
Definition: IndexPager.php:259
$type
$type
Definition: testCompression.php:52