<?php
namespace Knp\Bundle\PaginatorBundle\Pagination;
use Knp\Component\Pager\Pagination\AbstractPagination;
/**
* @template TKey
* @template TValue
*
* @template-extends AbstractPagination<TKey, TValue>
*
* @template-implements SlidingPaginationInterface<TKey, TValue>
*/
final class SlidingPagination extends AbstractPagination implements SlidingPaginationInterface
{
private ?string $route = null;
/** @var array<string, mixed> */
private array $params;
private int $pageRange = 5;
private ?int $pageLimit = null;
private ?string $template = null;
private ?string $sortableTemplate = null;
private ?string $filtrationTemplate = null;
/**
* @param array<string, mixed> $params
*/
public function __construct(array $params)
{
$this->params = $params;
}
public function setUsedRoute(?string $route): void
{
$this->route = $route;
}
public function getRoute(): ?string
{
return $this->route;
}
public function setSortableTemplate(string $template): void
{
$this->sortableTemplate = $template;
}
public function getSortableTemplate(): ?string
{
return $this->sortableTemplate;
}
public function setFiltrationTemplate(string $template): void
{
$this->filtrationTemplate = $template;
}
public function getFiltrationTemplate(): ?string
{
return $this->filtrationTemplate;
}
public function setParam(string $name, mixed $value): void
{
$this->params[$name] = $value;
}
public function getParams(): array
{
return $this->params;
}
public function setTemplate(string $template): void
{
$this->template = $template;
}
public function getTemplate(): ?string
{
return $this->template;
}
public function setPageRange(int $range): void
{
$this->pageRange = \abs($range);
}
public function setPageLimit(?int $limit): void
{
$this->pageLimit = $limit;
}
/**
* Get url query with all parameters.
*
* @param array<string, mixed> $additionalQueryParams
*
* @return array<string, mixed> - list of query parameters
*/
public function getQuery(array $additionalQueryParams = []): array
{
return \array_merge($this->params, $additionalQueryParams);
}
/**
* @param string[]|string|null $key
* @param array<string, mixed> $params
*/
public function isSorted($key = null, array $params = []): bool
{
$params = \array_merge($this->params, $params);
if (null === $key) {
return isset($params[$this->getPaginatorOption('sortFieldParameterName')]);
}
if (\is_array($key)) {
$key = \implode('+', $key);
}
return isset($params[$this->getPaginatorOption('sortFieldParameterName')]) && $params[$this->getPaginatorOption('sortFieldParameterName')] === $key;
}
public function getPage(): ?int
{
return $this->params[$this->getPaginatorOption('pageParameterName')] ?? null;
}
public function getSort(): ?string
{
return $this->params[$this->getPaginatorOption('sortFieldParameterName')] ?? null;
}
public function getDirection(): ?string
{
return $this->params[$this->getPaginatorOption('sortDirectionParameterName')] ?? null;
}
public function getPaginationData(): array
{
$pageCount = $this->getPageCount();
$current = $this->currentPageNumber;
if ($pageCount < $current) {
$this->currentPageNumber = $current = $pageCount;
}
if ($this->pageRange > $pageCount) {
$this->pageRange = $pageCount;
}
$delta = \ceil($this->pageRange / 2);
if ($current - $delta > $pageCount - $this->pageRange) {
$pages = \range($pageCount - $this->pageRange + 1, $pageCount);
} else {
if ($current - $delta < 0) {
$delta = $current;
}
$offset = $current - $delta;
$pages = \range($offset + 1, $offset + $this->pageRange);
}
$proximity = \floor($this->pageRange / 2);
$startPage = $current - $proximity;
$endPage = $current + $proximity;
if ($startPage < 1) {
$endPage = \min($endPage + (1 - $startPage), $pageCount);
$startPage = 1;
}
if ($endPage > $pageCount) {
$startPage = \max($startPage - ($endPage - $pageCount), 1);
$endPage = $pageCount;
}
$viewData = [
'last' => $pageCount,
'current' => $current,
'numItemsPerPage' => $this->numItemsPerPage,
'first' => 1,
'pageCount' => $pageCount,
'totalCount' => $this->totalCount,
'pageRange' => $this->pageRange,
'startPage' => $startPage,
'endPage' => $endPage,
];
if ($current > 1) {
$viewData['previous'] = $current - 1;
}
if ($current < $pageCount) {
$viewData['next'] = $current + 1;
}
$viewData['pagesInRange'] = $pages;
$viewData['firstPageInRange'] = \min($pages);
$viewData['lastPageInRange'] = \max($pages);
if (null !== $this->getItems()) {
$viewData['currentItemCount'] = $this->count();
$viewData['firstItemNumber'] = 0;
$viewData['lastItemNumber'] = 0;
if ($viewData['totalCount'] > 0) {
$viewData['firstItemNumber'] = (($current - 1) * $this->numItemsPerPage) + 1;
$viewData['lastItemNumber'] = $viewData['firstItemNumber'] + $viewData['currentItemCount'] - 1;
}
}
return $viewData;
}
public function getPageCount(): int
{
$count = (int) \ceil($this->totalCount / $this->numItemsPerPage);
if (null !== $this->pageLimit) {
return \min($count, $this->pageLimit);
}
return $count;
}
public function getPaginatorOptions(): ?array
{
return $this->paginatorOptions;
}
public function getCustomParameters(): ?array
{
return $this->customParameters;
}
}