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

Refactor pagination #228

Merged
merged 15 commits into from
Dec 9, 2024
Merged
1 change: 0 additions & 1 deletion config/widgets-themes.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
'itemTag()' => ['li'],
'itemAttributes()' => [['class' => 'page-item']],
'linkAttributes()' => [['class' => 'page-link']],
'currentItemClass()' => ['active'],
samdark marked this conversation as resolved.
Show resolved Hide resolved
'disabledItemClass()' => ['disabled'],
],
InputPageSize::class => [
Expand Down
108 changes: 68 additions & 40 deletions src/BaseListView.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@
use Yiisoft\Yii\DataView\Exception\DataReaderNotSetException;
use Yiisoft\Yii\DataView\PageSize\InputPageSize;
use Yiisoft\Yii\DataView\PageSize\PageSizeContext;
use Yiisoft\Yii\DataView\PageSize\PageSizeControlInterface;
use Yiisoft\Yii\DataView\PageSize\PageSizeWidgetInterface;
use Yiisoft\Yii\DataView\PageSize\SelectPageSize;
use Yiisoft\Yii\DataView\Pagination\KeysetPagination;
use Yiisoft\Yii\DataView\Pagination\OffsetPagination;
use Yiisoft\Yii\DataView\Pagination\PaginationContext;
use Yiisoft\Yii\DataView\Pagination\PaginationWidgetInterface;
use Yiisoft\Yii\DataView\Pagination\PaginatorNotSupportedException;

use function array_key_exists;
use function array_slice;
Expand All @@ -48,7 +50,6 @@
use function in_array;
use function is_array;
use function is_int;
use function is_string;

/**
* @psalm-type UrlArguments = array<string,scalar|Stringable|null>
Expand Down Expand Up @@ -90,8 +91,8 @@
*/
private ?string $pageSizeTag = 'div';
private array $pageSizeAttributes = [];
private ?string $pageSizeTemplate = 'Results per page {control}';
private PageSizeControlInterface|null $pageSizeControl = null;
private ?string $pageSizeTemplate = 'Results per page {widget}';
private PageSizeWidgetInterface|null $pageSizeWidget = null;

/**
* A name for {@see CategorySource} used with translator ({@see TranslatorInterface}) by default.
Expand Down Expand Up @@ -126,7 +127,7 @@

private array $offsetPaginationConfig = [];
private array $keysetPaginationConfig = [];
private string|OffsetPagination|KeysetPagination|null $pagination = null;
private PaginationWidgetInterface|null $paginationWidget = null;
protected ?ReadableDataInterface $dataReader = null;
private string $toolbar = '';

Expand Down Expand Up @@ -311,7 +312,7 @@
*
* @psalm-return list{FilterInterface[]|null,ValidationResult}
*/
protected function makeFilters(): array

Check warning on line 315 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 @@ -389,7 +390,7 @@

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

Check warning on line 393 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 @@ -409,7 +410,7 @@
}
}

if ($dataReader->isPaginationRequired()) {

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 "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));
$dataReader = $dataReader->withPageSize(
$this->preparePageSize($pageSize) ?? $this->getDefaultPageSize()
);
Expand All @@ -421,7 +422,7 @@
}
}

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

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->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 @@ -433,7 +434,7 @@
}
}

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

Check warning on line 437 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 437 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 437 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 @@ -537,7 +538,7 @@
*
* The following tokens will be replaced with the corresponding values:
*
* - `{control}` — page size control.
* - `{widget}` — page size widget.
*/
final public function pageSizeTemplate(?string $template): static
{
Expand All @@ -546,17 +547,17 @@
return $new;
}

final public function pageSizeControl(?PageSizeControlInterface $widget): static
final public function pageSizeWidget(?PageSizeWidgetInterface $widget): static
{
$new = clone $this;
$new->pageSizeControl = $widget;
$new->pageSizeWidget = $widget;
return $new;
}

public function pagination(string|KeysetPagination|OffsetPagination|null $pagination): static
public function paginationWidget(PaginationWidgetInterface|null $widget): static
{
$new = clone $this;
$new->pagination = $pagination;
$new->paginationWidget = $widget;
return $new;
}

Expand All @@ -568,7 +569,7 @@
*/
public function offsetPaginationConfig(array $config): static
{
$new = clone $this;

Check warning on line 572 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 @@ -581,7 +582,7 @@
*/
public function keysetPaginationConfig(array $config): static
{
$new = clone $this;

Check warning on line 585 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 @@ -774,55 +775,74 @@
*
* @psalm-return array<string, string>
*/
protected function getOverrideOrderFields(): array

Check warning on line 778 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 [];
}

private function renderPagination(): string
{
$preparedDataReader = $this->preparedDataReader;
if (!$preparedDataReader instanceof PaginatorInterface || !$preparedDataReader->isPaginationRequired()) {
$dataReader = $this->preparedDataReader;
if (!$dataReader instanceof PaginatorInterface || !$dataReader->isPaginationRequired()) {
return '';
}

if (is_string($this->pagination)) {
return $this->pagination;
}

if ($this->pagination === null) {
if ($preparedDataReader instanceof OffsetPaginator) {
$pagination = OffsetPagination::widget(config: $this->offsetPaginationConfig);
} elseif ($preparedDataReader instanceof KeysetPaginator) {
$pagination = KeysetPagination::widget(config: $this->keysetPaginationConfig);
if ($this->paginationWidget === null) {
if ($dataReader instanceof OffsetPaginator) {
$widget = OffsetPagination::widget(config: $this->offsetPaginationConfig);
} elseif ($dataReader instanceof KeysetPaginator) {
$widget = KeysetPagination::widget(config: $this->keysetPaginationConfig);
} else {
return '';
}
try {
$widget = $widget->withPaginator($dataReader);
} catch (PaginatorNotSupportedException) {
return '';
}
} else {
$pagination = $this->pagination;
$widget = $this->paginationWidget->withPaginator($dataReader);
}

if ($pagination instanceof OffsetPagination && $preparedDataReader instanceof OffsetPaginator) {
$pagination = $pagination->paginator($preparedDataReader);
} elseif ($pagination instanceof KeysetPagination && $preparedDataReader instanceof KeysetPaginator) {
$pagination = $pagination->paginator($preparedDataReader);
if ($this->urlCreator === null) {
$nextUrlPattern = '#page=' . PaginationContext::URL_PLACEHOLDER;
$previousUrlPattern = '#previous-page=' . PaginationContext::URL_PLACEHOLDER;
$defaultUrl = '#';
} else {
return '';
}

if ($this->urlCreator !== null) {
$pagination = $pagination->urlCreator($this->urlCreator);
$pageSize = $this->getPageSizeValueForUrl($dataReader);
$sort = $this->getSortValueForUrl($dataReader);
$nextUrlPattern = call_user_func_array(
$this->urlCreator,
UrlParametersFactory::create(
PageToken::next(PaginationContext::URL_PLACEHOLDER),
$pageSize,
$sort,
$this->urlConfig
),
);
$previousUrlPattern = call_user_func_array(
$this->urlCreator,
UrlParametersFactory::create(
PageToken::previous(PaginationContext::URL_PLACEHOLDER),
$pageSize,
$sort,
$this->urlConfig
),
);
$defaultUrl = call_user_func_array(
$this->urlCreator,
UrlParametersFactory::create(null, $pageSize, $sort, $this->urlConfig),
);
}

$context = new PaginationContext(
$this->getOverrideOrderFields(),
$nextUrlPattern,
$previousUrlPattern,
$defaultUrl,
);

return $pagination
->context($context)
->defaultPageSize($this->getDefaultPageSize())
->urlConfig($this->urlConfig)
->render();
return $widget->withContext($context)->render();
}

private function renderPageSize(): string
Expand All @@ -836,7 +856,7 @@
return '';
}

if ($this->pageSizeControl === null) {
if ($this->pageSizeWidget === null) {
if ($this->pageSizeConstraint === false || is_int($this->pageSizeConstraint)) {
$widget = InputPageSize::widget();
} elseif (is_array($this->pageSizeConstraint)) {
Expand All @@ -845,7 +865,7 @@
return '';
}
} else {
$widget = $this->pageSizeControl;
$widget = $this->pageSizeWidget;
}

if ($this->urlCreator === null) {
Expand Down Expand Up @@ -875,11 +895,11 @@
$urlPattern,
$defaultUrl,
);
$control = $widget->withContext($context)->render();
$renderedWidget = $widget->withContext($context)->render();

$content = $this->translator->translate(
$this->pageSizeTemplate,
['control' => $control],
['widget' => $renderedWidget],
$this->translationCategory,
);

Expand Down Expand Up @@ -1003,6 +1023,14 @@
return $translator;
}

private function getPageSizeValueForUrl(PaginatorInterface $paginator): ?string
{
$pageSize = $paginator->getPageSize();
return $pageSize === $this->getDefaultPageSize()
? null
: (string) $pageSize;
}

private function getSortValueForUrl(PaginatorInterface $paginator): ?string
{
$sort = $this->getSort($paginator);
Expand Down
2 changes: 1 addition & 1 deletion src/PageSize/InputPageSize.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Yiisoft\Html\Html;
use Yiisoft\Widget\Widget;

final class InputPageSize extends Widget implements PageSizeControlInterface
final class InputPageSize extends Widget implements PageSizeWidgetInterface
{
use PageSizeContextTrait;

Expand Down
2 changes: 1 addition & 1 deletion src/PageSize/PageSizeContextTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use LogicException;

/**
* @psalm-require-implements PageSizeControlInterface
* @psalm-require-implements PageSizeWidgetInterface
*/
trait PageSizeContextTrait
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Stringable;

interface PageSizeControlInterface extends Stringable
interface PageSizeWidgetInterface extends Stringable
{
public function withContext(PageSizeContext $context): static;

Expand Down
2 changes: 1 addition & 1 deletion src/PageSize/SelectPageSize.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use function count;
use function is_array;

final class SelectPageSize extends Widget implements PageSizeControlInterface
final class SelectPageSize extends Widget implements PageSizeWidgetInterface
{
use PageSizeContextTrait;

Expand Down
Loading
Loading