To follow Message. This is approved as part of RFC T166010. Also namespace it but doing it properly with PSR-4 would require namespacing every class under language/ and that will take some time. Bug: T321882 Change-Id: I195cf4c67bd51410556c2dd1e33cc9c1033d5d18
370 lines
9.5 KiB
PHP
370 lines
9.5 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Navigation;
|
|
|
|
use Html;
|
|
use MediaWiki\Language\RawMessage;
|
|
use MediaWiki\Page\PageReference;
|
|
use Message;
|
|
use MessageLocalizer;
|
|
use RuntimeException;
|
|
use Title;
|
|
|
|
/**
|
|
* Build the navigation for a pager, with links to prev/next page, links to change limits, and
|
|
* optionally links to first/last page.
|
|
*
|
|
* @since 1.39
|
|
*/
|
|
class PagerNavigationBuilder {
|
|
/** @var MessageLocalizer */
|
|
private $messageLocalizer;
|
|
|
|
/** @var PageReference */
|
|
protected $page;
|
|
/** @var array<string,?string> */
|
|
protected $linkQuery = [];
|
|
|
|
/** @var array<string,?string>|null */
|
|
private $prevLinkQuery = null;
|
|
/** @var string */
|
|
private $prevMsg = 'prevn';
|
|
/** @var string|null */
|
|
private $prevTooltipMsg = null;
|
|
|
|
/** @var array<string,?string>|null */
|
|
private $nextLinkQuery = null;
|
|
/** @var string */
|
|
private $nextMsg = 'nextn';
|
|
/** @var string|null */
|
|
private $nextTooltipMsg = null;
|
|
|
|
/** @var array<string,?string>|null */
|
|
private $firstLinkQuery = null;
|
|
/** @var string|null */
|
|
private $firstMsg = null;
|
|
/** @var string|null */
|
|
private $firstTooltipMsg = null;
|
|
|
|
/** @var array<string,?string>|null */
|
|
private $lastLinkQuery = null;
|
|
/** @var string|null */
|
|
private $lastMsg = null;
|
|
/** @var string|null */
|
|
private $lastTooltipMsg = null;
|
|
|
|
/** @var int */
|
|
private $currentLimit = 50;
|
|
/** @var int[] */
|
|
private $limits = [ 20, 50, 100, 250, 500 ];
|
|
/** @var string */
|
|
private $limitLinkQueryParam = 'limit';
|
|
/** @var string|null */
|
|
private $limitTooltipMsg = null;
|
|
|
|
/** @var callable|null $callback Function to call instead of makeLink().
|
|
* See IndexPager::makeLink() for the expected signature.
|
|
*/
|
|
private $makeLinkCallback = null;
|
|
|
|
/**
|
|
* @param MessageLocalizer $messageLocalizer
|
|
*/
|
|
public function __construct( MessageLocalizer $messageLocalizer ) {
|
|
$this->messageLocalizer = $messageLocalizer;
|
|
}
|
|
|
|
/**
|
|
* @param PageReference $page
|
|
* @return $this
|
|
*/
|
|
public function setPage( PageReference $page ): PagerNavigationBuilder {
|
|
$this->page = $page;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array<string,?string> $linkQuery
|
|
* @return $this
|
|
*/
|
|
public function setLinkQuery( array $linkQuery ): PagerNavigationBuilder {
|
|
$this->linkQuery = $linkQuery;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array<string,?string>|null $prevLinkQuery
|
|
* @return $this
|
|
*/
|
|
public function setPrevLinkQuery( ?array $prevLinkQuery ): PagerNavigationBuilder {
|
|
$this->prevLinkQuery = $prevLinkQuery;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $prevMsg
|
|
* @return $this
|
|
*/
|
|
public function setPrevMsg( string $prevMsg ): PagerNavigationBuilder {
|
|
$this->prevMsg = $prevMsg;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string|null $prevTooltipMsg
|
|
* @return $this
|
|
*/
|
|
public function setPrevTooltipMsg( ?string $prevTooltipMsg ): PagerNavigationBuilder {
|
|
$this->prevTooltipMsg = $prevTooltipMsg;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array<string,?string>|null $nextLinkQuery
|
|
* @return $this
|
|
*/
|
|
public function setNextLinkQuery( ?array $nextLinkQuery ): PagerNavigationBuilder {
|
|
$this->nextLinkQuery = $nextLinkQuery;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $nextMsg
|
|
* @return $this
|
|
*/
|
|
public function setNextMsg( string $nextMsg ): PagerNavigationBuilder {
|
|
$this->nextMsg = $nextMsg;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string|null $nextTooltipMsg
|
|
* @return $this
|
|
*/
|
|
public function setNextTooltipMsg( ?string $nextTooltipMsg ): PagerNavigationBuilder {
|
|
$this->nextTooltipMsg = $nextTooltipMsg;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array<string,?string>|null $firstLinkQuery
|
|
* @return $this
|
|
*/
|
|
public function setFirstLinkQuery( ?array $firstLinkQuery ): PagerNavigationBuilder {
|
|
$this->firstLinkQuery = $firstLinkQuery;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string|null $firstMsg
|
|
* @return $this
|
|
*/
|
|
public function setFirstMsg( ?string $firstMsg ): PagerNavigationBuilder {
|
|
$this->firstMsg = $firstMsg;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string|null $firstTooltipMsg
|
|
* @return $this
|
|
*/
|
|
public function setFirstTooltipMsg( ?string $firstTooltipMsg ): PagerNavigationBuilder {
|
|
$this->firstTooltipMsg = $firstTooltipMsg;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param array<string,?string>|null $lastLinkQuery
|
|
* @return $this
|
|
*/
|
|
public function setLastLinkQuery( ?array $lastLinkQuery ): PagerNavigationBuilder {
|
|
$this->lastLinkQuery = $lastLinkQuery;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string|null $lastMsg
|
|
* @return $this
|
|
*/
|
|
public function setLastMsg( ?string $lastMsg ): PagerNavigationBuilder {
|
|
$this->lastMsg = $lastMsg;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string|null $lastTooltipMsg
|
|
* @return $this
|
|
*/
|
|
public function setLastTooltipMsg( ?string $lastTooltipMsg ): PagerNavigationBuilder {
|
|
$this->lastTooltipMsg = $lastTooltipMsg;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param int $currentLimit
|
|
* @return $this
|
|
*/
|
|
public function setCurrentLimit( int $currentLimit ): PagerNavigationBuilder {
|
|
$this->currentLimit = $currentLimit;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param int[] $limits
|
|
* @return $this
|
|
*/
|
|
public function setLimits( array $limits ): PagerNavigationBuilder {
|
|
$this->limits = $limits;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $limitLinkQueryParam
|
|
* @return $this
|
|
*/
|
|
public function setLimitLinkQueryParam( string $limitLinkQueryParam ): PagerNavigationBuilder {
|
|
$this->limitLinkQueryParam = $limitLinkQueryParam;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string|null $limitTooltipMsg
|
|
* @return $this
|
|
*/
|
|
public function setLimitTooltipMsg( ?string $limitTooltipMsg ): PagerNavigationBuilder {
|
|
$this->limitTooltipMsg = $limitTooltipMsg;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @deprecated since 1.39
|
|
* @param callable|null $callback Function to call instead of makeLink().
|
|
* See IndexPager::makeLink() for the expected signature.
|
|
* @return $this
|
|
*/
|
|
public function setMakeLinkCallback( ?callable $callback ): PagerNavigationBuilder {
|
|
$this->makeLinkCallback = $callback;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param mixed $key
|
|
* @param mixed ...$params
|
|
* @return Message
|
|
*/
|
|
private function msg( $key, ...$params ): Message {
|
|
return $this->messageLocalizer
|
|
->msg( $key, ...$params )
|
|
->page( $this->page );
|
|
}
|
|
|
|
/**
|
|
* @stable to override
|
|
* @param array|null $query
|
|
* @param string|null $class
|
|
* @param string $text
|
|
* @param string|null $tooltip
|
|
* @param string|null $rel
|
|
* @return string HTML
|
|
*/
|
|
protected function makeLink(
|
|
?array $query, ?string $class, string $text, ?string $tooltip, ?string $rel = null
|
|
): string {
|
|
if ( $this->makeLinkCallback ) {
|
|
$type = substr( $class, strlen( 'mw-' ), -strlen( 'link' ) );
|
|
return ( $this->makeLinkCallback )( $text, $query, $type );
|
|
}
|
|
|
|
if ( $query !== null ) {
|
|
$title = Title::castFromPageReference( $this->page );
|
|
return Html::element(
|
|
'a',
|
|
[
|
|
'href' => $title->getLocalURL( array_merge( $this->linkQuery, $query ) ),
|
|
'rel' => $rel,
|
|
'title' => $tooltip,
|
|
'class' => $class,
|
|
],
|
|
$text
|
|
);
|
|
} else {
|
|
return Html::element(
|
|
'span',
|
|
[
|
|
'class' => $class,
|
|
],
|
|
$text
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the navigation HTML.
|
|
* @return string HTML
|
|
*/
|
|
public function getHtml(): string {
|
|
if ( !isset( $this->page ) ) {
|
|
throw new RuntimeException( 'page must be set' );
|
|
}
|
|
if ( isset( $this->firstMsg ) !== isset( $this->lastMsg ) ) {
|
|
throw new RuntimeException( 'firstMsg and lastMsg must be both set or both unset' );
|
|
}
|
|
|
|
$prevText = $this->msg( $this->prevMsg )->numParams( $this->currentLimit )->text();
|
|
$prevTooltip = $this->prevTooltipMsg ?
|
|
$this->msg( $this->prevTooltipMsg )->numParams( $this->currentLimit )->text() :
|
|
null;
|
|
$prevLink = $this->makeLink( $this->prevLinkQuery, 'mw-prevlink', $prevText, $prevTooltip, 'prev' );
|
|
|
|
$nextText = $this->msg( $this->nextMsg )->numParams( $this->currentLimit )->text();
|
|
$nextTooltip = $this->nextTooltipMsg ?
|
|
$this->msg( $this->nextTooltipMsg )->numParams( $this->currentLimit )->text() :
|
|
null;
|
|
$nextLink = $this->makeLink( $this->nextLinkQuery, 'mw-nextlink', $nextText, $nextTooltip, 'next' );
|
|
|
|
if ( $this->firstMsg ) {
|
|
$firstText = $this->msg( $this->firstMsg )->text();
|
|
$firstTooltip = $this->firstTooltipMsg ?
|
|
$this->msg( $this->firstTooltipMsg )->text() :
|
|
null;
|
|
$firstLink = $this->makeLink( $this->firstLinkQuery, 'mw-firstlink', $firstText, $firstTooltip );
|
|
}
|
|
|
|
if ( $this->lastMsg ) {
|
|
$lastText = $this->msg( $this->lastMsg )->text();
|
|
$lastTooltip = $this->lastTooltipMsg ?
|
|
$this->msg( $this->lastTooltipMsg )->text() :
|
|
null;
|
|
$lastLink = $this->makeLink( $this->lastLinkQuery, 'mw-lastlink', $lastText, $lastTooltip );
|
|
}
|
|
|
|
$limitLinks = [];
|
|
foreach ( $this->limits as $limit ) {
|
|
$limitText = $this->msg( new RawMessage( '$1' ) )->numParams( $limit )->text();
|
|
$limitTooltip = $this->limitTooltipMsg ?
|
|
$this->msg( $this->limitTooltipMsg )->numParams( $limit )->text() :
|
|
null;
|
|
$limitQuery = $limit === $this->currentLimit ? null : [ $this->limitLinkQueryParam => $limit ];
|
|
$limitLinks[] = $this->makeLink( $limitQuery, 'mw-numlink', $limitText, $limitTooltip );
|
|
}
|
|
|
|
$html = '';
|
|
if ( isset( $firstLink ) && isset( $lastLink ) ) {
|
|
$html .= $this->msg( 'parentheses' )->params(
|
|
Message::listParam( [
|
|
Message::rawParam( $firstLink ),
|
|
Message::rawParam( $lastLink )
|
|
], 'pipe' )
|
|
)->escaped() . ' ';
|
|
}
|
|
$html .= $this->msg( 'viewprevnext' )->params(
|
|
Message::rawParam( $prevLink ),
|
|
Message::rawParam( $nextLink ),
|
|
Message::listParam( array_map( static function ( $limitLink ) {
|
|
return Message::rawParam( $limitLink );
|
|
}, $limitLinks ), 'pipe' )
|
|
)->escaped();
|
|
|
|
return Html::rawElement( 'div', [ 'class' => 'mw-pager-navigation-bar' ], $html );
|
|
}
|
|
}
|