TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Pagination;
|
||||
|
||||
abstract class AbstractPaginator implements PaginatorInterface
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $numberOfPages = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $keyOfFirstPaginatedItem = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $keyOfLastPaginatedItem = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $currentPageNumber = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $itemsPerPage = 10;
|
||||
|
||||
public function withItemsPerPage(int $itemsPerPage): PaginatorInterface
|
||||
{
|
||||
if ($itemsPerPage === $this->itemsPerPage) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->setItemsPerPage($itemsPerPage);
|
||||
$new->updateInternalState();
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function withCurrentPageNumber(int $currentPageNumber): PaginatorInterface
|
||||
{
|
||||
if ($currentPageNumber === $this->currentPageNumber) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$new = clone $this;
|
||||
$new->setCurrentPageNumber($currentPageNumber);
|
||||
$new->updateInternalState();
|
||||
|
||||
return $new;
|
||||
}
|
||||
|
||||
public function getNumberOfPages(): int
|
||||
{
|
||||
return $this->numberOfPages;
|
||||
}
|
||||
|
||||
public function getCurrentPageNumber(): int
|
||||
{
|
||||
return $this->currentPageNumber;
|
||||
}
|
||||
|
||||
public function getKeyOfFirstPaginatedItem(): int
|
||||
{
|
||||
return $this->keyOfFirstPaginatedItem;
|
||||
}
|
||||
|
||||
public function getKeyOfLastPaginatedItem(): int
|
||||
{
|
||||
return $this->keyOfLastPaginatedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must update the paginated items, i.e. the subset of all items, limited and defined by
|
||||
* the given amount of items per page and offset
|
||||
*/
|
||||
abstract protected function updatePaginatedItems(int $itemsPerPage, int $offset): void;
|
||||
|
||||
/**
|
||||
* Must return the total amount of all unpaginated items
|
||||
*/
|
||||
abstract protected function getTotalAmountOfItems(): int;
|
||||
|
||||
/**
|
||||
* Must return the amount of paginated items on the current page
|
||||
*/
|
||||
abstract protected function getAmountOfItemsOnCurrentPage(): int;
|
||||
|
||||
/**
|
||||
* States whether there are items on the current page
|
||||
*/
|
||||
protected function hasItemsOnCurrentPage(): bool
|
||||
{
|
||||
return $this->getAmountOfItemsOnCurrentPage() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is the heart of the pagination. It updates all internal params and then calls the
|
||||
* {@see updatePaginatedItems} method which must update the set of paginated items.
|
||||
*/
|
||||
protected function updateInternalState(): void
|
||||
{
|
||||
$offset = (int)($this->itemsPerPage * ($this->currentPageNumber - 1));
|
||||
$totalAmountOfItems = $this->getTotalAmountOfItems();
|
||||
|
||||
/*
|
||||
* If the total amount of items is zero, then the number of pages is mathematically zero as
|
||||
* well. As that looks strange in the frontend, the number of pages is forced to be at least
|
||||
* one.
|
||||
*/
|
||||
$this->numberOfPages = max(1, (int)ceil($totalAmountOfItems / $this->itemsPerPage));
|
||||
|
||||
/*
|
||||
* To prevent empty results in case the given current page number exceeds the maximum number
|
||||
* of pages, we set the current page number to the last page and update the internal state
|
||||
* with this value again. Such situation should in the first place be prevented by not allowing
|
||||
* those values to be passed, e.g. by using the "max" attribute in the view. However there are
|
||||
* valid cases. For example when a user deletes a record while the pagination is already visible
|
||||
* to another user with, until then, a valid "max" value. Passing invalid values unintentionally
|
||||
* should therefore just silently be resolved.
|
||||
*/
|
||||
if ($this->currentPageNumber > $this->numberOfPages) {
|
||||
$this->currentPageNumber = $this->numberOfPages;
|
||||
$this->updateInternalState();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->updatePaginatedItems($this->itemsPerPage, $offset);
|
||||
|
||||
if (!$this->hasItemsOnCurrentPage()) {
|
||||
$this->keyOfFirstPaginatedItem = 0;
|
||||
$this->keyOfLastPaginatedItem = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
$indexOfLastPaginatedItem = min($offset + $this->itemsPerPage, $totalAmountOfItems);
|
||||
|
||||
$this->keyOfFirstPaginatedItem = $offset;
|
||||
$this->keyOfLastPaginatedItem = $indexOfLastPaginatedItem - 1;
|
||||
}
|
||||
|
||||
protected function setItemsPerPage(int $itemsPerPage): void
|
||||
{
|
||||
if ($itemsPerPage < 1) {
|
||||
throw new \InvalidArgumentException(
|
||||
'Argument $itemsPerPage must be greater than 0',
|
||||
1573061766
|
||||
);
|
||||
}
|
||||
|
||||
$this->itemsPerPage = $itemsPerPage;
|
||||
}
|
||||
|
||||
protected function setCurrentPageNumber(int $currentPageNumber): void
|
||||
{
|
||||
if ($currentPageNumber < 1) {
|
||||
throw new \InvalidArgumentException(
|
||||
'Argument $currentPageNumber must be greater than 0',
|
||||
1573047338
|
||||
);
|
||||
}
|
||||
|
||||
$this->currentPageNumber = $currentPageNumber;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Pagination;
|
||||
|
||||
final class ArrayPaginator extends AbstractPaginator
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $items;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $paginatedItems = [];
|
||||
|
||||
public function __construct(
|
||||
array $items,
|
||||
int $currentPageNumber = 1,
|
||||
int $itemsPerPage = 10
|
||||
) {
|
||||
$this->items = $items;
|
||||
$this->setCurrentPageNumber($currentPageNumber);
|
||||
$this->setItemsPerPage($itemsPerPage);
|
||||
|
||||
$this->updateInternalState();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable|array
|
||||
*/
|
||||
public function getPaginatedItems(): iterable
|
||||
{
|
||||
return $this->paginatedItems;
|
||||
}
|
||||
|
||||
protected function updatePaginatedItems(int $itemsPerPage, int $offset): void
|
||||
{
|
||||
$this->paginatedItems = array_slice($this->items, $offset, $itemsPerPage);
|
||||
}
|
||||
|
||||
protected function getTotalAmountOfItems(): int
|
||||
{
|
||||
return count($this->items);
|
||||
}
|
||||
|
||||
protected function getAmountOfItemsOnCurrentPage(): int
|
||||
{
|
||||
return count($this->paginatedItems);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Pagination;
|
||||
|
||||
/**
|
||||
* An interface that defines methods needed to implement a pagination
|
||||
*
|
||||
* A pagination is an object that takes a paginator and calculates variables
|
||||
* to render a pagination for the paginated objects in the given paginator
|
||||
*/
|
||||
interface PaginationInterface
|
||||
{
|
||||
public function __construct(PaginatorInterface $paginator);
|
||||
|
||||
/**
|
||||
* Must return the previous page number
|
||||
*
|
||||
* Is allowed to return null to indicate that there is no
|
||||
* previous page, e.g. when being on the first page
|
||||
*/
|
||||
public function getPreviousPageNumber(): ?int;
|
||||
|
||||
/**
|
||||
* Must return the next page number
|
||||
*
|
||||
* Is allowed to return null to indicate that there is no
|
||||
* next page, e.g. when being on the last page
|
||||
*/
|
||||
public function getNextPageNumber(): ?int;
|
||||
|
||||
/**
|
||||
* Must return the first page number, usually this will return 1
|
||||
*/
|
||||
public function getFirstPageNumber(): int;
|
||||
|
||||
/**
|
||||
* Must return the last page number, usually this will return the total amount of pages
|
||||
*/
|
||||
public function getLastPageNumber(): int;
|
||||
|
||||
/**
|
||||
* Must return the human-readable index of the first paginated item
|
||||
*
|
||||
* Example: given a set of 10 total items, 5 items per page and the current page being 2,
|
||||
* the start record number is 6:
|
||||
*
|
||||
* Page 1: Records 1-5
|
||||
* Page 2: Records 6-10
|
||||
*/
|
||||
public function getStartRecordNumber(): int;
|
||||
|
||||
/**
|
||||
* Must return the human-readable index of the last paginated item
|
||||
*
|
||||
* Example: given a set of 10 total items, 5 items per page and the current page being 2,
|
||||
* the end record number is 10.
|
||||
*
|
||||
* Page 1: Records 1-5
|
||||
* Page 2: Records 6-10
|
||||
*/
|
||||
public function getEndRecordNumber(): int;
|
||||
|
||||
/**
|
||||
* Must return a list of all page numbers.
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function getAllPageNumbers(): array;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Pagination;
|
||||
|
||||
/**
|
||||
* An interface that defines methods needed to implement a paginator, i.e. an object that handles
|
||||
* a set of items and returns a sub set of items, given by a configuration.
|
||||
*/
|
||||
interface PaginatorInterface
|
||||
{
|
||||
/**
|
||||
* Sets the amount of paginated items per page
|
||||
*
|
||||
* Must return a new instance of the Paginator with an updated internal state
|
||||
*/
|
||||
public function withItemsPerPage(int $itemsPerPage): PaginatorInterface;
|
||||
|
||||
/**
|
||||
* Sets the current page to calculate paginated items for
|
||||
*
|
||||
* Must return a new instance of the Paginator with an updated internal state
|
||||
*/
|
||||
public function withCurrentPageNumber(int $currentPageNumber): PaginatorInterface;
|
||||
|
||||
/**
|
||||
* Returns an iterable, sub set of the original set of items
|
||||
*/
|
||||
public function getPaginatedItems(): iterable;
|
||||
|
||||
/**
|
||||
* Returns the total number of pages, given the total number of non paginated items and the
|
||||
* items per page configuration
|
||||
*/
|
||||
public function getNumberOfPages(): int;
|
||||
|
||||
/**
|
||||
* Returns the current page number
|
||||
*/
|
||||
public function getCurrentPageNumber(): int;
|
||||
|
||||
/**
|
||||
* Returns the key of the first paginated item
|
||||
*
|
||||
* This is useful to display the exact range of
|
||||
* items that are available via getPaginatedItems
|
||||
*/
|
||||
public function getKeyOfFirstPaginatedItem(): int;
|
||||
|
||||
/**
|
||||
* Returns the key of the last paginated item
|
||||
*
|
||||
* This is useful to display the exact range of
|
||||
* items that are available via getPaginatedItems
|
||||
*/
|
||||
public function getKeyOfLastPaginatedItem(): int;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Pagination;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
|
||||
/**
|
||||
* Provides a paginator implementation to be used with {@see QueryBuilder} as
|
||||
* data source.
|
||||
*
|
||||
* **Be aware** that this comes with a couple of things to be considered:
|
||||
*
|
||||
* * QueryBuilder is used in a generic way by this Paginator and does not take care of proper language overlay
|
||||
* handling and cannot do that in a easy way and applying overlays on the result set can lead to weired item
|
||||
* count jumps on pages in case some of them are removed. For example 5 items on page 1, 6 on page two albeit
|
||||
* 10 items per page has been requested.
|
||||
*
|
||||
* * The paginator is completely in charge handling the pagination (offset/limit) and **does** not take
|
||||
* existing constraints of the passed QueryBuilder into account to match the expectation shared across
|
||||
* pagination handling throughout different frameworks and other Paginator implementation of TYPO3.
|
||||
*/
|
||||
final class QueryBuilderPaginator extends AbstractPaginator
|
||||
{
|
||||
private array $paginatedItems = [];
|
||||
private ?int $totalItems = null;
|
||||
|
||||
public function __construct(
|
||||
private readonly QueryBuilder $queryBuilder,
|
||||
int $currentPageNumber = 1,
|
||||
int $itemsPerPage = 10,
|
||||
) {
|
||||
$this->setCurrentPageNumber($currentPageNumber);
|
||||
$this->setItemsPerPage($itemsPerPage);
|
||||
|
||||
$this->updateInternalState();
|
||||
}
|
||||
|
||||
public function getPaginatedItems(): iterable
|
||||
{
|
||||
return $this->paginatedItems;
|
||||
}
|
||||
|
||||
protected function updatePaginatedItems(int $itemsPerPage, int $offset): void
|
||||
{
|
||||
$paginatedQueryBuilder = clone $this->queryBuilder;
|
||||
$this->paginatedItems = $paginatedQueryBuilder
|
||||
->setMaxResults($itemsPerPage)
|
||||
->setFirstResult($offset)
|
||||
->executeQuery()
|
||||
->fetchAllAssociative();
|
||||
}
|
||||
|
||||
protected function getTotalAmountOfItems(): int
|
||||
{
|
||||
return $this->getTotalItems();
|
||||
}
|
||||
|
||||
protected function getAmountOfItemsOnCurrentPage(): int
|
||||
{
|
||||
return count($this->paginatedItems);
|
||||
}
|
||||
|
||||
private function getTotalItems(): int
|
||||
{
|
||||
if ($this->totalItems === null) {
|
||||
$clonedQueryBuilder = clone $this->queryBuilder;
|
||||
// Remove obsolete query parts. There is no need to enforce any ordering improving
|
||||
// the performance and pagination constraints (LIMIT and OFFSET) are removed because
|
||||
// otherwise we would not get the total items count.
|
||||
$clonedQueryBuilder
|
||||
->resetOrderBy()
|
||||
->setMaxResults(null)
|
||||
->setFirstResult(0);
|
||||
|
||||
$this->totalItems = (int)$clonedQueryBuilder->getConnection()->createQueryBuilder()
|
||||
// @todo Upstream doctrine/dbal with() is not adopted in the decoration pattern and the reason to use
|
||||
// typo3 internal implementation for the common table expression here. Replace it when upstream
|
||||
// with() support has been integrated into the decoration chain.
|
||||
->typo3_with('cte_count', $clonedQueryBuilder)
|
||||
->count('*')
|
||||
->from('cte_count')
|
||||
->setParameters($clonedQueryBuilder->getParameters(), $clonedQueryBuilder->getParameterTypes())
|
||||
->executeQuery()
|
||||
->fetchOne();
|
||||
}
|
||||
return $this->totalItems;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Pagination;
|
||||
|
||||
final class SimplePagination implements PaginationInterface
|
||||
{
|
||||
private PaginatorInterface $paginator;
|
||||
|
||||
public function __construct(PaginatorInterface $paginator)
|
||||
{
|
||||
$this->paginator = $paginator;
|
||||
}
|
||||
|
||||
public function getPreviousPageNumber(): ?int
|
||||
{
|
||||
$previousPage = $this->paginator->getCurrentPageNumber() - 1;
|
||||
|
||||
if ($previousPage > $this->paginator->getNumberOfPages()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $previousPage >= $this->getFirstPageNumber()
|
||||
? $previousPage
|
||||
: null
|
||||
;
|
||||
}
|
||||
|
||||
public function getNextPageNumber(): ?int
|
||||
{
|
||||
$nextPage = $this->paginator->getCurrentPageNumber() + 1;
|
||||
|
||||
return $nextPage <= $this->paginator->getNumberOfPages()
|
||||
? $nextPage
|
||||
: null
|
||||
;
|
||||
}
|
||||
|
||||
public function getFirstPageNumber(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getLastPageNumber(): int
|
||||
{
|
||||
return $this->paginator->getNumberOfPages();
|
||||
}
|
||||
|
||||
public function getStartRecordNumber(): int
|
||||
{
|
||||
if ($this->paginator->getCurrentPageNumber() > $this->paginator->getNumberOfPages()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->paginator->getKeyOfFirstPaginatedItem() + 1;
|
||||
}
|
||||
|
||||
public function getEndRecordNumber(): int
|
||||
{
|
||||
if ($this->paginator->getCurrentPageNumber() > $this->paginator->getNumberOfPages()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->paginator->getKeyOfLastPaginatedItem() + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
public function getAllPageNumbers(): array
|
||||
{
|
||||
return range($this->getFirstPageNumber(), $this->getLastPageNumber());
|
||||
}
|
||||
|
||||
public function getPaginator(): PaginatorInterface
|
||||
{
|
||||
return $this->paginator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Core\Pagination;
|
||||
|
||||
final class SlidingWindowPagination implements PaginationInterface
|
||||
{
|
||||
private int $displayRangeStart = 0;
|
||||
private int $displayRangeEnd = 0;
|
||||
private bool $hasLessPages = false;
|
||||
private bool $hasMorePages = false;
|
||||
private int $maximumNumberOfLinks = 0;
|
||||
private PaginatorInterface $paginator;
|
||||
|
||||
public function __construct(PaginatorInterface $paginator, int $maximumNumberOfLinks = 0)
|
||||
{
|
||||
$this->paginator = $paginator;
|
||||
|
||||
if ($maximumNumberOfLinks > 0) {
|
||||
$this->maximumNumberOfLinks = $maximumNumberOfLinks;
|
||||
}
|
||||
|
||||
$this->calculateDisplayRange();
|
||||
}
|
||||
|
||||
public function getPreviousPageNumber(): ?int
|
||||
{
|
||||
$previousPage = $this->paginator->getCurrentPageNumber() - 1;
|
||||
|
||||
if ($previousPage > $this->paginator->getNumberOfPages()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $previousPage >= $this->getFirstPageNumber() ? $previousPage : null;
|
||||
}
|
||||
|
||||
public function getNextPageNumber(): ?int
|
||||
{
|
||||
$nextPage = $this->paginator->getCurrentPageNumber() + 1;
|
||||
|
||||
return $nextPage <= $this->paginator->getNumberOfPages() ? $nextPage : null;
|
||||
}
|
||||
|
||||
public function getFirstPageNumber(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getLastPageNumber(): int
|
||||
{
|
||||
return $this->paginator->getNumberOfPages();
|
||||
}
|
||||
|
||||
public function getStartRecordNumber(): int
|
||||
{
|
||||
if ($this->paginator->getCurrentPageNumber() > $this->paginator->getNumberOfPages()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->paginator->getKeyOfFirstPaginatedItem() + 1;
|
||||
}
|
||||
|
||||
public function getEndRecordNumber(): int
|
||||
{
|
||||
if ($this->paginator->getCurrentPageNumber() > $this->paginator->getNumberOfPages()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->paginator->getKeyOfLastPaginatedItem() + 1;
|
||||
}
|
||||
|
||||
public function getAllPageNumbers(): array
|
||||
{
|
||||
return range($this->displayRangeStart, $this->displayRangeEnd);
|
||||
}
|
||||
|
||||
public function getDisplayRangeStart(): int
|
||||
{
|
||||
return $this->displayRangeStart;
|
||||
}
|
||||
|
||||
public function getDisplayRangeEnd(): int
|
||||
{
|
||||
return $this->displayRangeEnd;
|
||||
}
|
||||
|
||||
public function getHasLessPages(): bool
|
||||
{
|
||||
return $this->hasLessPages;
|
||||
}
|
||||
|
||||
public function getHasMorePages(): bool
|
||||
{
|
||||
return $this->hasMorePages;
|
||||
}
|
||||
|
||||
public function getMaximumNumberOfLinks(): int
|
||||
{
|
||||
return $this->maximumNumberOfLinks;
|
||||
}
|
||||
|
||||
public function getPaginator(): PaginatorInterface
|
||||
{
|
||||
return $this->paginator;
|
||||
}
|
||||
|
||||
private function calculateDisplayRange(): void
|
||||
{
|
||||
$maximumNumberOfLinks = $this->maximumNumberOfLinks;
|
||||
$numberOfPages = $this->paginator->getNumberOfPages();
|
||||
|
||||
if ($maximumNumberOfLinks > $numberOfPages) {
|
||||
$maximumNumberOfLinks = $numberOfPages;
|
||||
}
|
||||
|
||||
$currentPage = $this->paginator->getCurrentPageNumber();
|
||||
$delta = floor($maximumNumberOfLinks / 2);
|
||||
|
||||
$this->displayRangeStart = (int)($currentPage - $delta);
|
||||
$this->displayRangeEnd = (int)($currentPage + $delta - ($maximumNumberOfLinks % 2 === 0 ? 1 : 0));
|
||||
|
||||
if ($this->displayRangeStart < 1) {
|
||||
$this->displayRangeEnd -= $this->displayRangeStart - 1;
|
||||
}
|
||||
|
||||
if ($this->displayRangeEnd > $numberOfPages) {
|
||||
$this->displayRangeStart -= $this->displayRangeEnd - $numberOfPages;
|
||||
}
|
||||
|
||||
$this->displayRangeStart = (int)max($this->displayRangeStart, 1);
|
||||
$this->displayRangeEnd = (int)min($this->displayRangeEnd, $numberOfPages);
|
||||
$this->hasLessPages = $this->displayRangeStart > 2;
|
||||
$this->hasMorePages = $this->displayRangeEnd + 1 < $this->paginator->getNumberOfPages();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user