misuzu/src/Pagination.php

78 lines
2.1 KiB
PHP

<?php
namespace Misuzu;
final class Pagination {
private const INVALID_OFFSET = -1;
private const START_PAGE = 1;
public const DEFAULT_PARAM = 'p';
private int $count = 0;
private int $range = 0;
private int $offset = 0;
public function __construct(int $count, int $range = -1, ?string $readParam = self::DEFAULT_PARAM) {
$this->count = max(0, $count);
$this->range = $range < 0 ? $count : $range;
if(!empty($readParam))
$this->readPage($readParam);
}
public function getCount(): int {
return $this->count;
}
public function getRange(): int {
return $this->range;
}
public function getPages(): int {
return (int)ceil($this->getCount() / $this->getRange());
}
public function hasValidOffset(): bool {
return $this->offset !== self::INVALID_OFFSET;
}
public function getOffset(): int {
return $this->hasValidOffset() ? $this->offset : 0;
}
public function setOffset(int $offset): self {
if($offset < 0)
$offset = self::INVALID_OFFSET;
$this->offset = $offset;
return $this;
}
public function getPage(): int {
if($this->getOffset() < 1)
return self::START_PAGE;
return (int)floor($this->getOffset() / $this->getRange()) + self::START_PAGE;
}
public function setPage(int $page, bool $zeroBased = false): self {
if(!$zeroBased)
$page -= self::START_PAGE;
$this->setOffset($this->getRange() * $page);
return $this;
}
public function readPage(string $name = self::DEFAULT_PARAM, int $default = self::START_PAGE, ?array $source = null): self {
$this->setPage(self::param($name, $default, $source));
return $this;
}
public static function param(string $name = self::DEFAULT_PARAM, int $default = self::START_PAGE, ?array $source = null): int {
$source ??= $_GET;
if(isset($source[$name]) && is_string($source[$name]) && ctype_digit($source[$name]))
return (int)$source[$name];
return $default;
}
}