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; } }