ldc-ovoteam/domain/Models/ValueObjects/Pagination.php

95 lines
2.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Domain\Models\ValueObjects;
use Domain\Enums\Pagination\ItemsPerPaginationEnum;
final readonly class Pagination
{
public const MAX_PAGE_SIZE = ItemsPerPaginationEnum::onehundred;
public function __construct(
private int $from,
private int $to,
) {
if ($from < 0) {
throw new \DomainException('From index must be non-negative');
}
if ($to < 0) {
throw new \DomainException('To index must be non-negative');
}
if ($to <= $from) {
throw new \DomainException('To index must be greater than from index');
}
if (($to - $from + 1) > self::MAX_PAGE_SIZE->value()) {
throw new \DomainException('Page size must be less than or equal to ' . self::MAX_PAGE_SIZE->value());
}
}
public function from(): int
{
return $this->from;
}
public function to(): int
{
return $this->to;
}
public function pageSize(): int
{
return $this->to - $this->from + 1;
}
public function pageNumber(): int
{
return (int) ($this->from / $this->pageSize()) + 1;
}
public static function ofIndexes(int $from, int $to): self
{
return new self($from, $to);
}
public static function ofPage(int $pageNumber, int $pageSize): self
{
if ($pageNumber <= 0) {
throw new \DomainException('Page number must be positive and non-zero');
}
if ($pageSize <= 0) {
throw new \DomainException('Page size must be positive and non-zero');
}
$fromIndex = ($pageNumber - 1) * $pageSize;
$toIndex = max($pageNumber * $pageSize - 1, 1);
return new self($fromIndex, $toIndex);
}
public static function ofOffsetAndLimit(int $offset, int $limit): self
{
if ($offset < 0) {
throw new \DomainException('Offset must be non-negative');
}
if ($limit <= 0) {
throw new \DomainException('Limit must be positive and non-zero');
}
$fromIndex = $offset;
$toIndex = max($offset + $limit - 1, 1);
return new self($fromIndex, $toIndex);
}
public static function firstPage(int $pageSize = 25): self
{
return self::ofPage(1, $pageSize);
}
public function __toString(): string
{
return sprintf('Pagination{from=%d, to=%d}', $this->from, $this->to);
}
}