Skip to content
Commits on Source (1)
......@@ -8,6 +8,9 @@ declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\Helpers;
/**
* @deprecated Use Dbp\Relay\CoreBundle\Pagination\PartialPaginator
*/
class ArrayFullPaginator extends ArrayPaginator
{
}
......@@ -11,6 +11,9 @@ namespace Dbp\Relay\CoreBundle\Helpers;
use ApiPlatform\Core\DataProvider\PaginatorInterface;
use Iterator;
/**
* @deprecated Use Dbp\Relay\CoreBundle\Pagination\PartialPaginator
*/
abstract class ArrayPaginator implements Iterator, PaginatorInterface
{
protected $position = 0;
......
......@@ -8,6 +8,9 @@ declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\Helpers;
/**
* @deprecated Use Dbp\Relay\CoreBundle\Pagination\PartialPaginator
*/
class ArrayPartPaginator extends ArrayPaginator
{
protected $totalItemCount = 0;
......
<?php
declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\Pagination;
use ApiPlatform\Core\DataProvider\PaginatorInterface;
use Dbp\Relay\CoreBundle\Exception\ApiError;
/**
* Paginator that holds the items of one page and is aware of the total amount of result items.
*/
class FullPaginator extends Paginator implements PaginatorInterface
{
/** @var int */
protected $totalNumItems;
/**
* @throws ApiError
*/
public function __construct(array $items, int $page, int $numItemsPerPage, int $totalNumItems)
{
if ($totalNumItems < 0) {
throw new ApiError(500, 'total number of items must be greater than or equal to zero');
}
parent::__construct($items, $page, $numItemsPerPage);
$this->totalNumItems = $totalNumItems;
}
/**
* Gets the last page number (page numbering starts at 1).
*/
public function getLastPage(): float
{
return ceil($this->totalNumItems / $this->maxNumItemsPerPage);
}
/**
* Gets the number of items in the whole result collection.
*/
public function getTotalItems(): float
{
return $this->totalNumItems;
}
}
......@@ -6,29 +6,11 @@ namespace Dbp\Relay\CoreBundle\Pagination;
class Pagination
{
private const CURRENT_PAGE_NUMBER_DEFAULT = 1;
public const MAX_NUM_ITEMS_PER_PAGE_DEFAULT = 30;
private const CURRENT_PAGE_NUMBER_PARAMETER_NAME = 'page';
private const MAX_NUM_ITEMS_PER_PAGE_PARAMETER_NAME = 'perPage';
private const IS_PARTIAL_PAGINATION_PARAMETER_NAME = 'partialPagination';
private const CURRENT_PAGE_NUMBER_DEFAULT = 1;
private const IS_PARTIAL_PAGINATION_DEFAULT = false;
public static function addOptions(array &$targetOptions, array $sourceOptions, int $maxNumItemsPerPageDefault = self::MAX_NUM_ITEMS_PER_PAGE_DEFAULT)
{
$targetOptions[self::CURRENT_PAGE_NUMBER_PARAMETER_NAME] = intval($sourceOptions[self::CURRENT_PAGE_NUMBER_PARAMETER_NAME] ?? self::CURRENT_PAGE_NUMBER_DEFAULT);
$targetOptions[self::MAX_NUM_ITEMS_PER_PAGE_PARAMETER_NAME] = intval($sourceOptions[self::MAX_NUM_ITEMS_PER_PAGE_PARAMETER_NAME] ?? $maxNumItemsPerPageDefault);
$targetOptions[self::IS_PARTIAL_PAGINATION_PARAMETER_NAME] = filter_var(
$sourceOptions[self::IS_PARTIAL_PAGINATION_PARAMETER_NAME] ?? self::IS_PARTIAL_PAGINATION_DEFAULT, FILTER_VALIDATE_BOOLEAN);
}
public static function removeOptions(array &$options)
{
unset($options[self::CURRENT_PAGE_NUMBER_PARAMETER_NAME]);
unset($options[self::MAX_NUM_ITEMS_PER_PAGE_PARAMETER_NAME]);
unset($options[self::IS_PARTIAL_PAGINATION_PARAMETER_NAME]);
}
public static function getCurrentPageNumber(array $options): int
{
......@@ -39,34 +21,4 @@ class Pagination
{
return max(1, intval($options[self::MAX_NUM_ITEMS_PER_PAGE_PARAMETER_NAME] ?? self::MAX_NUM_ITEMS_PER_PAGE_DEFAULT));
}
public static function isPartialPagination(array $options): bool
{
return boolval($options[self::IS_PARTIAL_PAGINATION_PARAMETER_NAME] ?? self::IS_PARTIAL_PAGINATION_DEFAULT);
}
/**
* Creates a new full paginator for the given page items.
*/
public static function createFullPaginator(array $pageItems, array $options, int $totalNumItems): FullPaginator
{
return new FullPaginator($pageItems, self::getCurrentPageNumber($options), self::getMaxNumItemsPerPage($options), $totalNumItems);
}
/**
* Creates a new partial paginator for the given page items.
*/
public static function createPartialPaginator(array $pageItems, array $options): PartialPaginator
{
return new PartialPaginator($pageItems, self::getCurrentPageNumber($options), self::getMaxNumItemsPerPage($options));
}
/**
* Creates a new paginator for the given whole result set.
* Note that this is always a full paginator, even if a partial paginator was requested.
*/
public static function createWholeResultPaginator(array $resultItems, array $options): WholeResultPaginator
{
return new WholeResultPaginator($resultItems, self::getCurrentPageNumber($options), self::getMaxNumItemsPerPage($options));
}
}
......@@ -8,17 +8,17 @@ namespace Dbp\Relay\CoreBundle\Pagination;
* Paginator that holds the whole set of result items.
* Note that it is a full paginator because partial pagination makes no sense with the whole result already at hand.
*/
class WholeResultPaginator extends FullPaginator
class WholeResultPaginator extends PartialPaginator
{
public function __construct(array $items, int $currentPageNumber, int $maxNumItemsPerPage)
{
parent::__construct($items, $currentPageNumber, $maxNumItemsPerPage, count($items));
parent::__construct($items, $currentPageNumber, $maxNumItemsPerPage);
}
public function valid(): bool
{
return
($this->currentPosition < $this->totalNumItems) &&
($this->currentPosition < count($this->items)) &&
($this->currentPosition < ($this->currentPageNumber * $this->maxNumItemsPerPage)) &&
($this->currentPosition >= (($this->currentPageNumber - 1) * $this->maxNumItemsPerPage));
}
......@@ -30,8 +30,8 @@ class WholeResultPaginator extends FullPaginator
public function count(): int
{
return $this->currentPageNumber < $this->getLastPage() ?
return $this->currentPageNumber < ceil(count($this->items) / $this->maxNumItemsPerPage) ?
$this->maxNumItemsPerPage :
(($this->currentPageNumber - 1) * $this->maxNumItemsPerPage) - $this->totalNumItems;
count($this->items) - (($this->currentPageNumber - 1) * $this->maxNumItemsPerPage);
}
}