File size: 4.91Kb
<?php
declare(strict_types=1);
namespace MotorORM;
/**
* Page navigation
*
* @license Code and contributions have MIT License
* @link https://visavi.net
* @author Alexander Grigorev <[email protected]>
* @version 3.0
*/
class Pagination
{
public int $limit;
public int $total;
public int $crumbs;
public int $offset;
public int $page;
public ?string $path = null;
public array $appends = [];
public function __construct(
protected ?string $viewPath = null,
protected ?string $pageName = null,
) {
$this->viewPath = $viewPath ?: __DIR__ . '/views/bootstrap5.php';
$this->pageName = $pageName ?: 'page';
}
/**
* Create
*
* @param int $total
* @param int $limit
* @param int $crumbs
*
* @return $this
*/
public function create(int $total, int $limit = 10, int $crumbs = 1): self
{
$this->limit = $limit;
$this->total = $total;
$this->crumbs = $crumbs;
$this->page = $this->page();
$this->offset = $this->offset();
return $this;
}
/**
* Get offset
*
* @return int
*/
public function offset(): int
{
if ($this->total === 0) {
$this->page = 1;
} elseif ($this->total && $this->page * $this->limit >= $this->total) {
$this->page = (int) ceil($this->total / $this->limit);
}
return $this->page * $this->limit - $this->limit;
}
/**
* Get current page
*
* @return int
*/
public function page(): int
{
return ! empty($_GET[$this->pageName]) ? abs((int) $_GET[$this->pageName]) : 1;
}
/**
* Get items
*
* @return array
*/
public function items(): array
{
if (! $this->total) {
return [];
}
$pages = [];
$pageCount = (int) ceil($this->total / $this->limit);
$indexFirst = max($this->page - $this->crumbs, 1);
$indexLast = min($this->page + $this->crumbs, $pageCount);
if ($this->page !== 1) {
$pages[] = [
'link' => $this->buildUrl($this->page - 1),
'page' => $this->page - 1,
'name' => '«',
];
}
if ($this->page > $this->crumbs + 1) {
$pages[] = [
'link' => $this->buildUrl(1),
'page' => 1,
'name' => 1,
];
if ($this->page !== $this->crumbs + 2) {
$pages[] = [
'separator' => true,
];
}
}
for ($i = $indexFirst; $i <= $indexLast; $i++) {
if ($i === $this->page) {
$pages[] = [
'current' => true,
'name' => $i,
];
} else {
$pages[] = [
'link' => $this->buildUrl($i),
'page' => $i,
'name' => $i,
];
}
}
if ($this->page < $pageCount - $this->crumbs) {
if ($this->page !== $pageCount - $this->crumbs - 1) {
$pages[] = [
'separator' => true,
];
}
$pages[] = [
'link' => $this->buildUrl($pageCount),
'page' => $pageCount,
'name' => $pageCount,
];
}
if ($this->page !== $pageCount) {
$pages[] = [
'link' => $this->buildUrl($this->page + 1),
'page' => $this->page + 1,
'name' => '»',
];
}
return $pages;
}
/**
* Get rendered links
*
* @return string
*/
public function links(): string
{
ob_start();
$pages = $this->items();
include($this->viewPath);
return ob_get_clean();
}
/**
* Set view
*
* @param string $view
*
* @return void
*/
public function setView(string $view): void
{
$this->viewPath = $view;
}
/**
* Set page name
*
* @param string $name
*
* @return void
*/
public function setPageName(string $name): void
{
$this->pageName = $name;
}
/**
* Add path
*
* @param string $path
*
* @return void
*/
public function withPath(string $path): void
{
$this->path = $path;
}
/**
* Append params url
*
* @param array $appends
*
* @return void
*/
public function appends(array $appends): void
{
$this->appends = $appends;
}
/**
* Build url
*
* @param int $page
*
* @return string
*/
protected function buildUrl(int $page): string
{
return $this->path . '?' . http_build_query([$this->pageName => $page] + $this->appends);
}
}