current === null) { // Parse current page from search parameters $this->current = array_key_exists($this->key, $_GET) ? $this->clamp((int) $_GET[$this->key]) : 0; } if ($this->size === null) { $this->size = self::DEFAULT_PAGE_SIZE; } } /** * Search parameter to use as key for page number */ public string $key = "p"; /** * Get current database offset * * @return int Database offset of first item on current page */ public int $offset { get => max(0, $this->current * $this->size); } /** * Get total amount of pages * * @return int Total number of pages */ public int $pages { get => ceil($this->total / $this->size); } /** * Returns true if a previous page exists * * @return bool Previous page exists */ public bool $previous { get => $this->current > 0; } /** * True if a next page exists * * @return bool Next page exists */ public bool $next { get => $this->current + 1 < $this->pages; } /** * Get pages witin ±range from current page * * @param ?int $range Desired range from current page to return * @return array Indecies of pages within the desired range */ public function range(?int $range = self::DEFAULT_RANGE): array { $start = max(1, $this->current - max(0, $range - 2)); $end = min($this->pages, $this->current + $range); $range = []; for ($i = $start; $i <= $end; $i++) { $range[] = $i; } return $range; } /** * Returns a url to a page by index * * @param int $page Page index * @return string Search parameters to the target page */ public function idx(int $page): string { return $this->url($page - 1); } /** * Returns a url to the previous page * * @return string Search parameters to the previous page */ public function previous(): string { return $this->url($this->current - 1); } /** * Returns a url to the next page * * @return string Search parameters to the next page */ public function next(): string { return $this->url($this->current + 1); } /** * Clamp page within range of all pages * * @param int $page Page index * @return int Clamped page index */ private function clamp(int $page): int { return max(0, min($page, $this->pages - 1)); } /** * Construct search parameters for a page while preserving existing search parameters * * @param int $page Page index * @return string A search parameter to the target page */ private function url(int $page): string { return "?" . http_build_query(array_merge($_GET, [$this->key => $page])); } }