266 lines
5.3 KiB
PHP
Executable File
266 lines
5.3 KiB
PHP
Executable File
<?php
|
|
|
|
/**
|
|
* SysCMS - Content Management System
|
|
*
|
|
* Copyright (c) 2025 Marco Costa
|
|
* All rights reserved.
|
|
*
|
|
* Author: Marco Costa
|
|
* Email: contato@syspanel.com.br
|
|
* Project: SysCMS
|
|
*
|
|
* This software is licensed, not sold.
|
|
* Permission is granted to use this software
|
|
* subject to the terms of the SysCMS Commercial License.
|
|
*
|
|
* Redistribution, sublicensing, resale, or
|
|
* disclosure of this software, in whole or in part,
|
|
* is strictly prohibited without prior written permission.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|
|
*/
|
|
|
|
namespace Modules\PageBuilder\Classes;
|
|
|
|
/**
|
|
* Simple pagination class for PageBuilder module
|
|
*/
|
|
class Paginator
|
|
{
|
|
/**
|
|
* Current page
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $currentPage;
|
|
|
|
/**
|
|
* Items per page
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $perPage;
|
|
|
|
/**
|
|
* Total items
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $total;
|
|
|
|
/**
|
|
* Path for pagination links
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $path;
|
|
|
|
/**
|
|
* Query parameters
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $query;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param int $total
|
|
* @param int $perPage
|
|
* @param int $currentPage
|
|
* @param string $path
|
|
* @param array $query
|
|
*/
|
|
public function __construct(int $total, int $perPage, int $currentPage = 1, string $path = '', array $query = [])
|
|
{
|
|
$this->total = $total;
|
|
$this->perPage = $perPage;
|
|
$this->currentPage = max(1, $currentPage);
|
|
$this->path = $path ?: $_SERVER['REQUEST_URI'] ?? '';
|
|
$this->query = $query;
|
|
}
|
|
|
|
/**
|
|
* Get current page
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getCurrentPage(): int
|
|
{
|
|
return $this->currentPage;
|
|
}
|
|
|
|
/**
|
|
* Get items per page
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getPerPage(): int
|
|
{
|
|
return $this->perPage;
|
|
}
|
|
|
|
/**
|
|
* Get total items
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getTotal(): int
|
|
{
|
|
return $this->total;
|
|
}
|
|
|
|
/**
|
|
* Get last page
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getLastPage(): int
|
|
{
|
|
return max(1, (int) ceil($this->total / $this->perPage));
|
|
}
|
|
|
|
/**
|
|
* Get offset for database query
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getOffset(): int
|
|
{
|
|
return ($this->currentPage - 1) * $this->perPage;
|
|
}
|
|
|
|
/**
|
|
* Check if there are more items
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function hasMorePages(): bool
|
|
{
|
|
return $this->currentPage < $this->getLastPage();
|
|
}
|
|
|
|
/**
|
|
* Check if there are previous pages
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function hasPreviousPages(): bool
|
|
{
|
|
return $this->currentPage > 1;
|
|
}
|
|
|
|
/**
|
|
* Get URL for a specific page
|
|
*
|
|
* @param int $page
|
|
* @return string
|
|
*/
|
|
public function getUrl(int $page): string
|
|
{
|
|
$query = $this->query;
|
|
$query['page'] = $page;
|
|
|
|
$queryString = http_build_query($query);
|
|
|
|
// Remove the existing query string from the path
|
|
$path = strtok($this->path, '?');
|
|
|
|
return $path . ($queryString ? '?' . $queryString : '');
|
|
}
|
|
|
|
/**
|
|
* Get previous page URL
|
|
*
|
|
* @return string|null
|
|
*/
|
|
public function getPreviousPageUrl(): ?string
|
|
{
|
|
if (!$this->hasPreviousPages()) {
|
|
return null;
|
|
}
|
|
|
|
return $this->getUrl($this->currentPage - 1);
|
|
}
|
|
|
|
/**
|
|
* Get next page URL
|
|
*
|
|
* @return string|null
|
|
*/
|
|
public function getNextPageUrl(): ?string
|
|
{
|
|
if (!$this->hasMorePages()) {
|
|
return null;
|
|
}
|
|
|
|
return $this->getUrl($this->currentPage + 1);
|
|
}
|
|
|
|
/**
|
|
* Get array of page numbers to display
|
|
*
|
|
* @param int $onEachSide
|
|
* @return array
|
|
*/
|
|
public function getPageNumbers(int $onEachSide = 3): array
|
|
{
|
|
$lastPage = $this->getLastPage();
|
|
$currentPage = $this->currentPage;
|
|
|
|
if ($lastPage <= ($onEachSide * 2) + 1) {
|
|
return range(1, $lastPage);
|
|
}
|
|
|
|
$pages = [];
|
|
|
|
// First page
|
|
$pages[] = 1;
|
|
|
|
// Pages before current
|
|
$start = max(2, $currentPage - $onEachSide);
|
|
$end = min($lastPage - 1, $currentPage + $onEachSide);
|
|
|
|
if ($start > 2) {
|
|
$pages[] = '...';
|
|
}
|
|
|
|
for ($i = $start; $i <= $end; $i++) {
|
|
$pages[] = $i;
|
|
}
|
|
|
|
if ($end < $lastPage - 1) {
|
|
$pages[] = '...';
|
|
}
|
|
|
|
// Last page
|
|
if ($lastPage > 1) {
|
|
$pages[] = $lastPage;
|
|
}
|
|
|
|
return $pages;
|
|
}
|
|
|
|
/**
|
|
* Convert paginator to array for template rendering
|
|
*
|
|
* @return array
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'current_page' => $this->getCurrentPage(),
|
|
'per_page' => $this->getPerPage(),
|
|
'total' => $this->getTotal(),
|
|
'last_page' => $this->getLastPage(),
|
|
'offset' => $this->getOffset(),
|
|
'has_more_pages' => $this->hasMorePages(),
|
|
'has_previous_pages' => $this->hasPreviousPages(),
|
|
'previous_page_url' => $this->getPreviousPageUrl(),
|
|
'next_page_url' => $this->getNextPageUrl(),
|
|
'page_numbers' => $this->getPageNumbers(),
|
|
];
|
|
}
|
|
}
|