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 
246  public function getDatabase() {
247  return $this->mDb;
248  }
249 
257  public function doQuery() {
258  $defaultOrder = ( $this->mDefaultDirection === self::DIR_ASCENDING )
259  ? self::QUERY_ASCENDING
260  : self::QUERY_DESCENDING;
261  $order = $this->mIsBackwards ? self::oppositeOrder( $defaultOrder ) : $defaultOrder;
262 
263  # Plus an extra row so that we can tell the "next" link should be shown
264  $queryLimit = $this->mLimit + 1;
265 
266  if ( $this->mOffset == '' ) {
267  $isFirst = true;
268  } else {
269  // If there's an offset, we may or may not be at the first entry.
270  // The only way to tell is to run the query in the opposite
271  // direction see if we get a row.
272  $oldIncludeOffset = $this->mIncludeOffset;
273  $this->mIncludeOffset = !$this->mIncludeOffset;
274  $oppositeOrder = self::oppositeOrder( $order );
275  $isFirst = !$this->reallyDoQuery( $this->mOffset, 1, $oppositeOrder )->numRows();
276  $this->mIncludeOffset = $oldIncludeOffset;
277  }
278 
279  $this->mResult = $this->reallyDoQuery(
280  $this->mOffset,
281  $queryLimit,
282  $order
283  );
284 
285  $this->extractResultInfo( $isFirst, $queryLimit, $this->mResult );
286  $this->mQueryDone = true;
287 
288  $this->preprocessResults( $this->mResult );
289  $this->mResult->rewind(); // Paranoia
290  }
291 
296  final protected static function oppositeOrder( $order ) {
297  return ( $order === self::QUERY_ASCENDING )
300  }
301 
305  public function getResult() {
306  return $this->mResult;
307  }
308 
314  public function setOffset( $offset ) {
315  $this->mOffset = $offset;
316  }
317 
327  public function setLimit( $limit ) {
328  $limit = (int)$limit;
329  // WebRequest::getLimitOffsetForUser() puts a cap of 5000, so do same here.
330  if ( $limit > 5000 ) {
331  $limit = 5000;
332  }
333  if ( $limit > 0 ) {
334  $this->mLimit = $limit;
335  }
336  }
337 
343  public function getLimit() {
344  return $this->mLimit;
345  }
346 
354  public function setIncludeOffset( $include ) {
355  $this->mIncludeOffset = $include;
356  }
357 
369  protected function extractResultInfo( $isFirst, $limit, IResultWrapper $res ) {
370  $numRows = $res->numRows();
371 
372  $firstIndex = [];
373  $lastIndex = [];
374  $this->mPastTheEndIndex = [];
375  $this->mPastTheEndRow = null;
376 
377  if ( $numRows ) {
378  $indexColumns = array_map( static function ( $v ) {
379  // Remove any table prefix from index field
380  $parts = explode( '.', $v );
381  return end( $parts );
382  }, (array)$this->mIndexField );
383 
384  $row = $res->fetchRow();
385  foreach ( $indexColumns as $indexColumn ) {
386  $firstIndex[] = $row[$indexColumn];
387  }
388 
389  # Discard the extra result row if there is one
390  if ( $numRows > $this->mLimit && $numRows > 1 ) {
391  $res->seek( $numRows - 1 );
392  $this->mPastTheEndRow = $res->fetchObject();
393  foreach ( $indexColumns as $indexColumn ) {
394  $this->mPastTheEndIndex[] = $this->mPastTheEndRow->$indexColumn;
395  }
396  $res->seek( $numRows - 2 );
397  $row = $res->fetchRow();
398  foreach ( $indexColumns as $indexColumn ) {
399  $lastIndex[] = $row[$indexColumn];
400  }
401  } else {
402  $this->mPastTheEndRow = null;
403  $res->seek( $numRows - 1 );
404  $row = $res->fetchRow();
405  foreach ( $indexColumns as $indexColumn ) {
406  $lastIndex[] = $row[$indexColumn];
407  }
408  }
409  }
410 
411  if ( $this->mIsBackwards ) {
412  $this->mIsFirst = ( $numRows < $limit );
413  $this->mIsLast = $isFirst;
414  $this->mLastShown = $firstIndex;
415  $this->mFirstShown = $lastIndex;
416  } else {
417  $this->mIsFirst = $isFirst;
418  $this->mIsLast = ( $numRows < $limit );
419  $this->mLastShown = $lastIndex;
420  $this->mFirstShown = $firstIndex;
421  }
422  }
423 
431  protected function getSqlComment() {
432  return static::class;
433  }
434 
447  public function reallyDoQuery( $offset, $limit, $order ) {
448  list( $tables, $fields, $conds, $fname, $options, $join_conds ) =
449  $this->buildQueryInfo( $offset, $limit, $order );
450 
451  return $this->mDb->select( $tables, $fields, $conds, $fname, $options, $join_conds );
452  }
453 
466  protected function buildQueryInfo( $offset, $limit, $order ) {
467  $fname = __METHOD__ . ' (' . $this->getSqlComment() . ')';
468  $info = $this->getQueryInfo();
469  $tables = $info['tables'];
470  $fields = $info['fields'];
471  $conds = $info['conds'] ?? [];
472  $options = $info['options'] ?? [];
473  $join_conds = $info['join_conds'] ?? [];
474  $indexColumns = (array)$this->mIndexField;
475  $sortColumns = array_merge( $indexColumns, $this->mExtraSortFields );
476 
477  if ( $order === self::QUERY_ASCENDING ) {
478  $options['ORDER BY'] = $sortColumns;
479  $operator = $this->mIncludeOffset ? '>=' : '>';
480  } else {
481  $orderBy = [];
482  foreach ( $sortColumns as $col ) {
483  $orderBy[] = $col . ' DESC';
484  }
485  $options['ORDER BY'] = $orderBy;
486  $operator = $this->mIncludeOffset ? '<=' : '<';
487  }
488  if ( $offset != '' ) {
489  $offsets = explode( '|', $offset, /* Limit to max of indices */ count( $indexColumns ) );
490 
491  $conds[] = $this->buildOffsetConds(
492  $offsets,
493  $indexColumns,
494  $operator
495  );
496  }
497  $options['LIMIT'] = intval( $limit );
498  return [ $tables, $fields, $conds, $fname, $options, $join_conds ];
499  }
500 
537  private function buildOffsetConds( $offsets, $columns, $operator ) {
538  $innerConds = [];
539  // $offsets and $columns are the same length
540  for ( $i = 1; $i <= count( $offsets ); $i++ ) {
541  $innerConds[] = $this->buildOffsetInnerConds(
542  array_slice( $offsets, 0, $i ),
543  array_slice( $columns, 0, $i ),
544  $operator
545  );
546  }
547  return $this->mDb->makeList( $innerConds, IDatabase::LIST_OR );
548  }
549 
559  private function buildOffsetInnerConds( $offsets, $columns, $operator ) {
560  $conds = [];
561  while ( count( $offsets ) > 1 ) {
562  $conds[] = $columns[0] . '=' . $this->mDb->addQuotes( $offsets[0] );
563  array_shift( $columns );
564  array_shift( $offsets );
565  }
566  $conds[] = $columns[0] . $operator . $this->mDb->addQuotes( $offsets[0] );
567  return $this->mDb->makeList( $conds, IDatabase::LIST_AND );
568  }
569 
577  protected function preprocessResults( $result ) {
578  }
579 
588  public function getBody() {
589  if ( !$this->mQueryDone ) {
590  $this->doQuery();
591  }
592 
593  if ( $this->mResult->numRows() ) {
594  # Do any special query batches before display
595  $this->doBatchLookups();
596  }
597 
598  # Don't use any extra rows returned by the query
599  $numRows = min( $this->mResult->numRows(), $this->mLimit );
600 
601  $s = $this->getStartBody();
602  if ( $numRows ) {
603  if ( $this->mIsBackwards ) {
604  for ( $i = $numRows - 1; $i >= 0; $i-- ) {
605  $this->mResult->seek( $i );
606  $row = $this->mResult->fetchObject();
607  $s .= $this->formatRow( $row );
608  }
609  } else {
610  $this->mResult->seek( 0 );
611  for ( $i = 0; $i < $numRows; $i++ ) {
612  $row = $this->mResult->fetchObject();
613  $s .= $this->formatRow( $row );
614  }
615  }
616  } else {
617  $s .= $this->getEmptyBody();
618  }
619  $s .= $this->getEndBody();
620  return $s;
621  }
622 
634  protected function makeLink( $text, array $query = null, $type = null ) {
635  if ( $query === null ) {
636  return $text;
637  }
638 
639  $attrs = [];
640  if ( in_array( $type, [ 'prev', 'next' ] ) ) {
641  $attrs['rel'] = $type;
642  }
643 
644  if ( in_array( $type, [ 'asc', 'desc' ] ) ) {
645  $attrs['title'] = $this->msg( $type == 'asc' ? 'sort-ascending' : 'sort-descending' )->text();
646  }
647 
648  if ( $type ) {
649  $attrs['class'] = "mw-{$type}link";
650  }
651 
652  return $this->getLinkRenderer()->makeKnownLink(
653  $this->getTitle(),
654  new HtmlArmor( $text ),
655  $attrs,
656  $query + $this->getDefaultQuery()
657  );
658  }
659 
669  protected function doBatchLookups() {
670  }
671 
678  protected function getStartBody() {
679  return '';
680  }
681 
689  protected function getEndBody() {
690  return '';
691  }
692 
701  protected function getEmptyBody() {
702  return '';
703  }
704 
714  public function getDefaultQuery() {
715  if ( !isset( $this->mDefaultQuery ) ) {
716  $this->mDefaultQuery = $this->getRequest()->getQueryValues();
717  unset( $this->mDefaultQuery['title'] );
718  unset( $this->mDefaultQuery['dir'] );
719  unset( $this->mDefaultQuery['offset'] );
720  unset( $this->mDefaultQuery['limit'] );
721  unset( $this->mDefaultQuery['order'] );
722  unset( $this->mDefaultQuery['month'] );
723  unset( $this->mDefaultQuery['year'] );
724  }
725  return $this->mDefaultQuery;
726  }
727 
733  public function getNumRows() {
734  if ( !$this->mQueryDone ) {
735  $this->doQuery();
736  }
737  return $this->mResult->numRows();
738  }
739 
747  public function getPagingQueries() {
748  if ( !$this->mQueryDone ) {
749  $this->doQuery();
750  }
751 
752  # Don't announce the limit everywhere if it's the default
753  $urlLimit = $this->mLimit == $this->mDefaultLimit ? null : $this->mLimit;
754 
755  if ( $this->mIsFirst ) {
756  $prev = false;
757  $first = false;
758  } else {
759  $prev = [
760  'dir' => 'prev',
761  'offset' => implode( '|', (array)$this->mFirstShown ),
762  'limit' => $urlLimit
763  ];
764  $first = [ 'limit' => $urlLimit ];
765  }
766  if ( $this->mIsLast ) {
767  $next = false;
768  $last = false;
769  } else {
770  $next = [ 'offset' => implode( '|', (array)$this->mLastShown ), 'limit' => $urlLimit ];
771  $last = [ 'dir' => 'prev', 'limit' => $urlLimit ];
772  }
773 
774  return [
775  'prev' => $prev,
776  'next' => $next,
777  'first' => $first,
778  'last' => $last
779  ];
780  }
781 
788  protected function isNavigationBarShown() {
789  if ( !$this->mQueryDone ) {
790  $this->doQuery();
791  }
792  // Hide navigation by default if there is nothing to page
793  return !( $this->mIsFirst && $this->mIsLast );
794  }
795 
806  protected function getPagingLinks( $linkTexts, $disabledTexts = [] ) {
807  $queries = $this->getPagingQueries();
808  $links = [];
809 
810  foreach ( $queries as $type => $query ) {
811  if ( $query !== false ) {
812  $links[$type] = $this->makeLink(
813  $linkTexts[$type],
814  $query,
815  $type
816  );
817  } elseif ( isset( $disabledTexts[$type] ) ) {
818  $links[$type] = $disabledTexts[$type];
819  } else {
820  $links[$type] = $linkTexts[$type];
821  }
822  }
823 
824  return $links;
825  }
826 
827  protected function getLimitLinks() {
828  $links = [];
829  if ( $this->mIsBackwards ) {
830  $offset = implode( '|', (array)$this->mPastTheEndIndex );
831  } else {
832  $offset = $this->mOffset;
833  }
834  foreach ( $this->mLimitsShown as $limit ) {
835  $links[] = $this->makeLink(
836  $this->getLanguage()->formatNum( $limit ),
837  [ 'offset' => $offset, 'limit' => $limit ],
838  'num'
839  );
840  }
841  return $links;
842  }
843 
851  abstract public function formatRow( $row );
852 
864  abstract public function getQueryInfo();
865 
902  abstract public function getIndexField();
903 
927  protected function getExtraSortFields() {
928  return [];
929  }
930 
952  protected function getDefaultDirections() {
953  return self::DIR_ASCENDING;
954  }
955 
966  protected function buildPrevNextNavigation(
967  Title $title,
968  $offset,
969  $limit,
970  array $query = [],
971  $atend = false
972  ) {
973  $prevNext = new PrevNextNavigationRenderer( $this );
974 
975  return $prevNext->buildPrevNextNavigation( $title, $offset, $limit, $query, $atend );
976  }
977 
982  protected function getLinkRenderer() {
983  if ( $this->linkRenderer === null ) {
984  $this->linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
985  }
986  return $this->linkRenderer;
987  }
988 }
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:678
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:577
IndexPager\getDefaultQuery
getDefaultQuery()
Get an array of query parameters that should be put into self-links.
Definition: IndexPager.php:714
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:193
IndexPager\QUERY_ASCENDING
const QUERY_ASCENDING
Backwards-compatible constant for reallyDoQuery() (do not change)
Definition: IndexPager.php:83
IndexPager\getResult
getResult()
Definition: IndexPager.php:305
IndexPager\$mFirstShown
array $mFirstShown
Definition: IndexPager.php:145
MediaWiki\Linker\LinkRenderer
Class that generates HTML links 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:927
LIST_AND
const LIST_AND
Definition: Defines.php:43
IndexPager\getDatabase
getDatabase()
Get the Database object in use.
Definition: IndexPager.php:246
IndexPager\getPagingQueries
getPagingQueries()
Get a URL query array for the prev, next, first and last links.
Definition: IndexPager.php:747
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:634
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:966
$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:827
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:669
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:701
IndexPager\reallyDoQuery
reallyDoQuery( $offset, $limit, $order)
Do a query with specified parameters, rather than using the object context.
Definition: IndexPager.php:447
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:466
IndexPager\setLimit
setLimit( $limit)
Set the limit from an other source than the request.
Definition: IndexPager.php:327
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2203
IndexPager\$mIsLast
bool $mIsLast
Definition: IndexPager.php:140
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:369
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:354
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:296
IndexPager\getDefaultDirections
getDefaultDirections()
Return the default sorting direction: DIR_ASCENDING or DIR_DESCENDING.
Definition: IndexPager.php:952
$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:314
IndexPager\$mResult
IResultWrapper $mResult
Result object for the query.
Definition: IndexPager.php:164
IndexPager\getLinkRenderer
getLinkRenderer()
Definition: IndexPager.php:982
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:559
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:689
IndexPager\getSqlComment
getSqlComment()
Get some text to go in brackets in the "function name" part of the SQL comment.
Definition: IndexPager.php:431
IndexPager\isNavigationBarShown
isNavigationBarShown()
Returns whether to show the "navigation bar" @stable to override.
Definition: IndexPager.php:788
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:537
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:343
IndexPager\$mLastShown
array $mLastShown
Definition: IndexPager.php:143
IndexPager\getBody
getBody()
Get the formatted result list.
Definition: IndexPager.php:588
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:733
IndexPager\getPagingLinks
getPagingLinks( $linkTexts, $disabledTexts=[])
Get paging links.
Definition: IndexPager.php:806
IndexPager\$mIsFirst
bool $mIsFirst
True if the current result set is the first one.
Definition: IndexPager.php:138
IndexPager\doQuery
doQuery()
Do the query, using information from the object context.
Definition: IndexPager.php:257
$type
$type
Definition: testCompression.php:52