Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #218: Add ability to set page size #219

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
106 changes: 100 additions & 6 deletions src/BaseListView.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,52 @@

use function array_slice;
use function extension_loaded;
use function in_array;
use function is_array;
use function is_int;
use function is_string;

/**
* @psalm-type UrlArguments = array<string,scalar|Stringable|null>
* @psalm-type UrlCreator = callable(UrlArguments,array):string
* @psalm-type PageNotFoundExceptionCallback = callable(PageNotFoundException):void
* @psalm-type PageSizeConstraint = list<positive-int>|positive-int|bool
* @psalm-import-type TOrder from Sort
*/
abstract class BaseListView extends Widget
{
/**
* Page size is fixed to default value.
*/
public const PAGE_SIZE_FIXED = true;

Check failure on line 56 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

MissingClassConstType

src/BaseListView.php:56:18: MissingClassConstType: Class constant "Yiisoft\Yii\DataView\BaseListView::PAGE_SIZE_FIXED" should have a declared type. (see https://psalm.dev/359)

/**
* Page size could be any value.
*/
public const PAGE_SIZE_ANY = false;

Check failure on line 61 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.3-ubuntu-latest

MissingClassConstType

src/BaseListView.php:61:18: MissingClassConstType: Class constant "Yiisoft\Yii\DataView\BaseListView::PAGE_SIZE_ANY" should have a declared type. (see https://psalm.dev/359)

/**
* @psalm-var UrlCreator|null
*/
protected $urlCreator = null;
protected UrlConfig $urlConfig;

/**
* @var int Page size that is used in case it is not set explicitly.
* @psalm-var positive-int
*/
protected int $defaultPageSize = PaginatorInterface::DEFAULT_PAGE_SIZE;

/**
* @var array|bool|int Page size constraint.
* - `true` - default only.
* - `false` - no constraint.
* - int - maximum page size.
* - [int, int, ...] - a list of page sizes to choose from.
* @psalm-var PageSizeConstraint
*/
protected bool|int|array $pageSizeConstraint = true;

/**
* A name for {@see CategorySource} used with translator ({@see TranslatorInterface}) by default.
* @psalm-suppress MissingClassConstType
Expand Down Expand Up @@ -273,7 +300,7 @@
*
* @psalm-return list{FilterInterface[]|null,ValidationResult}
*/
protected function makeFilters(): array

Check warning on line 303 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "ProtectedVisibility": --- Original +++ New @@ @@ * * @psalm-return list{FilterInterface[]|null,ValidationResult} */ - protected function makeFilters() : array + private function makeFilters() : array { return [[], new ValidationResult()]; }
{
return [[], new ValidationResult()];
}
Expand Down Expand Up @@ -351,7 +378,7 @@

if (!$dataReader instanceof PaginatorInterface) {
if (
$dataReader instanceof OffsetableDataInterface

Check warning on line 381 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "LogicalAnd": --- Original +++ New @@ @@ { $dataReader = $this->getDataReader(); if (!$dataReader instanceof PaginatorInterface) { - if ($dataReader instanceof OffsetableDataInterface && $dataReader instanceof CountableDataInterface && $dataReader instanceof LimitableDataInterface) { + if (($dataReader instanceof OffsetableDataInterface || $dataReader instanceof CountableDataInterface) && $dataReader instanceof LimitableDataInterface) { $dataReader = new OffsetPaginator($dataReader); } elseif ($dataReader instanceof FilterableDataInterface && $dataReader instanceof SortableDataInterface && $dataReader instanceof LimitableDataInterface) { if ($dataReader->getSort() !== null) {
&& $dataReader instanceof CountableDataInterface
&& $dataReader instanceof LimitableDataInterface
) {
Expand All @@ -371,10 +398,10 @@
}
}

if ($dataReader->isPaginationRequired()) {

Check warning on line 401 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "IfNegation": --- Original +++ New @@ @@ return $dataReader; } } - if ($dataReader->isPaginationRequired()) { + if (!$dataReader->isPaginationRequired()) { $dataReader = $dataReader->withPageSize($this->preparePageSize($pageSize) ?? $this->getDefaultPageSize()); if ($page !== null) { $dataReader = $dataReader->withToken(PageToken::next($page));
if ($pageSize !== null) {
$dataReader = $dataReader->withPageSize((int) $pageSize);
}
$dataReader = $dataReader->withPageSize(
$this->preparePageSize($pageSize) ?? $this->getDefaultPageSize()
);

if ($page !== null) {
$dataReader = $dataReader->withToken(PageToken::next($page));
Expand All @@ -383,7 +410,7 @@
}
}

if (!empty($sort) && $dataReader->isSortable()) {

Check warning on line 413 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndSingleSubExprNegation": --- Original +++ New @@ @@ $dataReader = $dataReader->withToken(PageToken::previous($previousPage)); } } - if (!empty($sort) && $dataReader->isSortable()) { + if (!empty($sort) && !$dataReader->isSortable()) { $sortObject = $dataReader->getSort(); if ($sortObject !== null) { $order = OrderHelper::stringToArray($sort);
$sortObject = $dataReader->getSort();
if ($sortObject !== null) {
$order = OrderHelper::stringToArray($sort);
Expand All @@ -395,7 +422,7 @@
}
}

if (!empty($filters) && $dataReader->isFilterable()) {

Check warning on line 425 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "LogicalAnd": --- Original +++ New @@ @@ $dataReader = $dataReader->withSort($sortObject->withOrder($order)); } } - if (!empty($filters) && $dataReader->isFilterable()) { + if (!empty($filters) || $dataReader->isFilterable()) { $dataReader = $dataReader->withFilter(new All(...$filters)); } return $dataReader;

Check warning on line 425 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndNegation": --- Original +++ New @@ @@ $dataReader = $dataReader->withSort($sortObject->withOrder($order)); } } - if (!empty($filters) && $dataReader->isFilterable()) { + if (!(!empty($filters) && $dataReader->isFilterable())) { $dataReader = $dataReader->withFilter(new All(...$filters)); } return $dataReader;

Check warning on line 425 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "LogicalAndSingleSubExprNegation": --- Original +++ New @@ @@ $dataReader = $dataReader->withSort($sortObject->withOrder($order)); } } - if (!empty($filters) && $dataReader->isFilterable()) { + if (!empty($filters) && !$dataReader->isFilterable()) { $dataReader = $dataReader->withFilter(new All(...$filters)); } return $dataReader;
$dataReader = $dataReader->withFilter(new All(...$filters));
}

Expand Down Expand Up @@ -483,7 +510,7 @@
*/
public function offsetPaginationConfig(array $config): static
{
$new = clone $this;

Check warning on line 513 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "CloneRemoval": --- Original +++ New @@ @@ */ public function offsetPaginationConfig(array $config) : static { - $new = clone $this; + $new = $this; $new->offsetPaginationConfig = $config; return $new; }
$new->offsetPaginationConfig = $config;
return $new;
}
Expand All @@ -496,7 +523,7 @@
*/
public function keysetPaginationConfig(array $config): static
{
$new = clone $this;

Check warning on line 526 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "CloneRemoval": --- Original +++ New @@ @@ */ public function keysetPaginationConfig(array $config) : static { - $new = clone $this; + $new = $this; $new->keysetPaginationConfig = $config; return $new; }
$new->keysetPaginationConfig = $config;
return $new;
}
Expand Down Expand Up @@ -638,14 +665,48 @@
->render();
}

/**
* @psalm-return positive-int
*/
protected function getDefaultPageSize(): int
{
$dataReader = $this->getDataReader();
if ($dataReader instanceof PaginatorInterface) {
return $dataReader->getPageSize();
$pageSize = $dataReader instanceof PaginatorInterface
? $dataReader->getPageSize()
: $this->defaultPageSize;

if (is_int($this->pageSizeConstraint)) {
return $pageSize <= $this->pageSizeConstraint
? $pageSize
: $this->pageSizeConstraint;
}

if (is_array($this->pageSizeConstraint)) {
return in_array($pageSize, $this->pageSizeConstraint, true)
? $pageSize
: $this->pageSizeConstraint[0];
}

return $this->defaultPageSize;
return $pageSize;
}

/**
* Get a new instance with a page size constraint set.
*
* @param array|bool|int $pageSizeConstraint Page size constraint.
* `true` - default only.
* `false` - no constraint.
* int - maximum page size.
* [int, int, ...] - a list of page sizes to choose from.
* @return static New instance.
*
* @psalm-param PageSizeConstraint $pageSizeConstraint
*/
public function pageSizeConstraint(array|int|bool $pageSizeConstraint): static
{
$new = clone $this;
$new->pageSizeConstraint = $pageSizeConstraint;
return $new;
}

/**
Expand All @@ -654,7 +715,7 @@
*
* @psalm-return array<string, string>
*/
protected function getOverrideOrderFields(): array

Check warning on line 718 in src/BaseListView.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.2-ubuntu-latest

Escaped Mutant for Mutator "ProtectedVisibility": --- Original +++ New @@ @@ * * @psalm-return array<string, string> */ - protected function getOverrideOrderFields() : array + private function getOverrideOrderFields() : array { return []; }
{
return [];
}
Expand Down Expand Up @@ -767,6 +828,39 @@
};
}

/**
* @psalm-return positive-int|null
*/
private function preparePageSize(?string $rawPageSize): ?int
{
if ($this->pageSizeConstraint === true) {
return null;
}

if ($rawPageSize === null) {
return null;
}

$pageSize = (int) $rawPageSize;
if ($pageSize < 1) {
return null;
}

if ($this->pageSizeConstraint === false) {
return $pageSize;
}

if (is_int($this->pageSizeConstraint) && $pageSize <= $this->pageSizeConstraint) {
return $pageSize;
}

if (is_array($this->pageSizeConstraint) && in_array($pageSize, $this->pageSizeConstraint, true)) {
return $pageSize;
}

return null;
}

/**
* Creates default translator to use if {@see $translator} wasn't set explicitly in the constructor. Depending on
* "intl" extension availability, either {@see IntlMessageFormatter} or {@see SimpleMessageFormatter} is used as
Expand Down
3 changes: 3 additions & 0 deletions src/BasePagination.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ public function urlConfig(UrlConfig $config): static
/**
* Creates the URL suitable for pagination with the specified page number. This method is mainly called by pagers
* when creating URLs used to perform pagination.
*
* @param PageToken $pageToken Token for the page.
* @return string Created URL.
*/
protected function createUrl(PageToken $pageToken): string
{
Expand Down
23 changes: 23 additions & 0 deletions tests/Support/SimpleUrlParameterProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Yii\DataView\Tests\Support;

use Yiisoft\Yii\DataView\UrlParameterProviderInterface;

final class SimpleUrlParameterProvider implements UrlParameterProviderInterface
{
/**
* @param string[] $parameters
*/
public function __construct(
private readonly array $parameters = [],
) {
}

public function get(string $name, int $type): ?string
{
return $this->parameters[$name] ?? null;
}
}
Loading