first commit
This commit is contained in:
278
class/class.Pager.php
Normal file
278
class/class.Pager.php
Normal file
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
use KupShop\KupShopBundle\Pager\PagerExtraItem;
|
||||
|
||||
class Pager implements ArrayAccess
|
||||
{
|
||||
public const INFINITE_PAGE_COUNT = 999999;
|
||||
|
||||
protected $pageSideCount = 1;
|
||||
protected $pageInsideCount = 3;
|
||||
|
||||
public $count;
|
||||
public $number;
|
||||
|
||||
public $total;
|
||||
public ?int $totalWithExtraItems = null;
|
||||
public $onPage;
|
||||
|
||||
protected $url;
|
||||
protected $params = [];
|
||||
|
||||
protected int $extraItemsOnFirstPage = 0;
|
||||
/** @var PagerExtraItem[] */
|
||||
protected array $extraItemsOnEachPage = [];
|
||||
|
||||
public function __construct($pageCount = null, $page = null, $objectCount = null)
|
||||
{
|
||||
if (!is_null($pageCount)) {
|
||||
$this->count = max(1, $pageCount);
|
||||
}
|
||||
|
||||
if (!is_null($page)) {
|
||||
$this->number = $page;
|
||||
}
|
||||
}
|
||||
|
||||
public function setUrl($url)
|
||||
{
|
||||
$parts = parse_url($url);
|
||||
|
||||
$this->url = $parts['path'];
|
||||
|
||||
if (!empty($parts['query'])) {
|
||||
parse_str($parts['query'], $this->params);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* set total number of pages
|
||||
* $total = total number of records
|
||||
* $this->count = total number of pages
|
||||
* */
|
||||
public function setTotal($total, $onPage = null)
|
||||
{
|
||||
// total uz muze mit nejakou hodnotu, napr. pocet banneru v ProductListu (total number of records = bannery + produkty)
|
||||
$this->total += $total;
|
||||
|
||||
if (is_null($this->count)) {
|
||||
$extraItems = array_sum($this->getExtraItems());
|
||||
$extraItems += $this->getExtraItemsOnNextPages(
|
||||
ceil(($this->total + $extraItems) / $this->getOnPage())
|
||||
);
|
||||
|
||||
$this->totalWithExtraItems = $this->total + $extraItems;
|
||||
$this->count = ceil($this->totalWithExtraItems / $this->getOnPage());
|
||||
}
|
||||
|
||||
if ($onPage) {
|
||||
$this->onPage = $onPage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $onPage
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
/*
|
||||
* set number of records on the page
|
||||
* */
|
||||
public function setOnPage($onPage)
|
||||
{
|
||||
$this->onPage = $onPage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $number
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPageNumber($number)
|
||||
{
|
||||
$this->number = max(1, $number);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $pageSideCount
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPageSide($pageSideCount)
|
||||
{
|
||||
$this->pageSideCount = $pageSideCount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $pageInsideCount
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPageInside($pageInsideCount)
|
||||
{
|
||||
$this->pageInsideCount = $pageInsideCount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUrl($values)
|
||||
{
|
||||
$params = array_merge($this->params, $values);
|
||||
|
||||
if (getVal('page', $params, 0) == 1) {
|
||||
unset($params['page']);
|
||||
}
|
||||
|
||||
$query = http_build_query($params);
|
||||
|
||||
return $query ? '?'.$query : '.';
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
if (method_exists($this, $name)) {
|
||||
return $this->$name();
|
||||
}
|
||||
}
|
||||
|
||||
public function first()
|
||||
{
|
||||
return $this->insidePagesFrom() > $this->pageSideCount;
|
||||
}
|
||||
|
||||
public function firstDots()
|
||||
{
|
||||
return $this->insidePagesFrom() > $this->pageSideCount + 1;
|
||||
}
|
||||
|
||||
public function last()
|
||||
{
|
||||
return $this->insidePagesTo() < ($this->count - $this->pageSideCount + 1);
|
||||
}
|
||||
|
||||
public function lastDots()
|
||||
{
|
||||
return $this->insidePagesTo() < $this->count - $this->pageSideCount;
|
||||
}
|
||||
|
||||
public function insidePagesFrom()
|
||||
{
|
||||
return max(1, $this->number - $this->pageInsideCount);
|
||||
}
|
||||
|
||||
public function insidePagesTo()
|
||||
{
|
||||
return min($this->count, $this->number + $this->pageInsideCount);
|
||||
}
|
||||
|
||||
public function to()
|
||||
{
|
||||
return min($this->number * $this->getOnPage() - 1, $this->total ?: self::INFINITE_PAGE_COUNT);
|
||||
}
|
||||
|
||||
public function from()
|
||||
{
|
||||
return ($this->number - 1) * $this->getOnPage();
|
||||
}
|
||||
|
||||
public function isInfinite(): bool
|
||||
{
|
||||
return $this->count === self::INFINITE_PAGE_COUNT;
|
||||
}
|
||||
|
||||
public function getSpec()
|
||||
{
|
||||
return function (Query\QueryBuilder $qb) {
|
||||
[$extraItemsOnThisPage, $extraItemsOnPreviousPages] = $this->getExtraItems();
|
||||
|
||||
$onPage = $this->getOnPage() - $extraItemsOnThisPage;
|
||||
$from = max(0, $this->from() - $extraItemsOnPreviousPages);
|
||||
|
||||
$qb->setMaxResults($onPage)
|
||||
->setFirstResult($from);
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
public function addExtraItems(PagerExtraItem $onEachPage): self
|
||||
{
|
||||
$this->extraItemsOnEachPage[] = $onEachPage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extra items for the current and previous pages.
|
||||
*
|
||||
* @return array{onThisPage: int, onPreviousPages: int}
|
||||
*/
|
||||
public function getExtraItems(): array
|
||||
{
|
||||
$extraItemsOnPreviousPages = 0;
|
||||
$extraItemsOnThisPage = 0;
|
||||
|
||||
foreach ($this->extraItemsOnEachPage as $extraItem) {
|
||||
$extraItemsOnPreviousPages += min($extraItem->countOnPage * ($this->number - 1), $extraItem->getMax());
|
||||
$extraItemsOnThisPage += min($extraItem->countOnPage, max($extraItem->getMax() - $extraItemsOnPreviousPages, 0));
|
||||
}
|
||||
|
||||
return [$extraItemsOnThisPage, $extraItemsOnPreviousPages];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extra items for the next pages when total pages count is already known.
|
||||
*/
|
||||
private function getExtraItemsOnNextPages(int $totalPages): int
|
||||
{
|
||||
$extraItemsOnNextPages = 0;
|
||||
|
||||
foreach ($this->extraItemsOnEachPage as $extraItem) {
|
||||
$extraItemsOnNextPages += min(($totalPages - $this->number) * $extraItem->countOnPage, max($extraItem->getMax() - ($extraItem->countOnPage * $this->number), 0));
|
||||
}
|
||||
|
||||
return $extraItemsOnNextPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ArrayAccess interface.
|
||||
*/
|
||||
public function offsetSet($offset, $value): void
|
||||
{
|
||||
$this->{$offset} = $value;
|
||||
}
|
||||
|
||||
public function offsetExists($offset): bool
|
||||
{
|
||||
return isset($this->{$offset});
|
||||
}
|
||||
|
||||
public function offsetUnset($offset): void
|
||||
{
|
||||
unset($this->{$offset});
|
||||
}
|
||||
|
||||
public function offsetGet($offset): mixed
|
||||
{
|
||||
if (method_exists($this, $offset)) {
|
||||
return $this->$offset();
|
||||
}
|
||||
|
||||
return isset($this->{$offset}) ? $this->{$offset} : null;
|
||||
}
|
||||
|
||||
public function getOnPage()
|
||||
{
|
||||
if (empty($this->onPage)) {
|
||||
return 30;
|
||||
}
|
||||
|
||||
return $this->onPage;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user