diff --git a/src/BaseListView.php b/src/BaseListView.php index d0c89ed4d..26e956d6f 100644 --- a/src/BaseListView.php +++ b/src/BaseListView.php @@ -148,8 +148,6 @@ abstract class BaseListView extends Widget */ private $pageNotFoundExceptionCallback = null; - protected ?ReadableDataInterface $preparedDataReader = null; - public function __construct( TranslatorInterface|null $translator = null, protected readonly string $translationCategory = self::DEFAULT_TRANSLATION_CATEGORY, @@ -237,7 +235,11 @@ final public function enableMultiSort(bool $value = true): self * * @psalm-param array $items */ - abstract protected function renderItems(array $items, ValidationResult $filterValidationResult): string; + abstract protected function renderItems( + array $items, + ValidationResult $filterValidationResult, + ?ReadableDataInterface $preparedDataReader, + ): string; final public function containerTag(?string $tag): static { @@ -323,9 +325,9 @@ protected function makeFilters(): array * * @throws PageNotFoundException * - * @psalm-return array + * @psalm-return list{ReadableDataInterface|null, array} */ - private function prepareDataReaderAndGetItems(array $filters): array + private function prepareDataReaderAndItems(array $filters): array { $page = $this->urlParameterProvider?->get( $this->urlConfig->getPageParameterName(), @@ -345,15 +347,15 @@ private function prepareDataReaderAndGetItems(array $filters): array ); try { - $this->preparedDataReader = $this->prepareDataReaderByParams($page, $previousPage, $pageSize, $sort, $filters); - return $this->getItems($this->preparedDataReader); + $preparedDataReader = $this->prepareDataReaderByParams($page, $previousPage, $pageSize, $sort, $filters); + return [$preparedDataReader, $this->getItems($preparedDataReader)]; } catch (InvalidPageException $exception) { } if ($this->ignoreMissingPage) { - $this->preparedDataReader = $this->prepareDataReaderByParams(null, null, $pageSize, $sort, $filters); + $preparedDataReader = $this->prepareDataReaderByParams(null, null, $pageSize, $sort, $filters); try { - return $this->getItems($this->preparedDataReader); + return [$preparedDataReader, $this->getItems($preparedDataReader)]; } catch (InvalidPageException $exception) { } } @@ -709,7 +711,9 @@ protected function renderEmpty(int $colspan): Td public function render(): string { [$filters, $filterValidationResult] = $this->makeFilters(); - $items = $filters === null ? [] : $this->prepareDataReaderAndGetItems($filters); + [$preparedDataReader, $items] = $filters === null + ? [null, []] + : $this->prepareDataReaderAndItems($filters); $content = trim( strtr( @@ -717,10 +721,10 @@ public function render(): string [ '{header}' => $this->renderHeader(), '{toolbar}' => $this->toolbar, - '{items}' => $this->renderItems($items, $filterValidationResult), - '{summary}' => $this->renderSummary(), - '{pager}' => $this->renderPagination(), - '{pageSize}' => $this->renderPageSize(), + '{items}' => $this->renderItems($items, $filterValidationResult, $preparedDataReader), + '{summary}' => $this->renderSummary($preparedDataReader), + '{pager}' => $this->renderPagination($preparedDataReader), + '{pageSize}' => $this->renderPageSize($preparedDataReader), ], ) ); @@ -787,9 +791,8 @@ protected function getOrderProperties(): array return []; } - private function renderPagination(): string + private function renderPagination(?ReadableDataInterface $dataReader): string { - $dataReader = $this->preparedDataReader; if (!$dataReader instanceof PaginatorInterface || !$dataReader->isPaginationRequired()) { return ''; } @@ -851,14 +854,9 @@ private function renderPagination(): string return $widget->withContext($context)->render(); } - private function renderPageSize(): string + private function renderPageSize(?ReadableDataInterface $dataReader): string { - if (empty($this->pageSizeTemplate)) { - return ''; - } - - $dataReader = $this->preparedDataReader; - if (!$dataReader instanceof PaginatorInterface) { + if (empty($this->pageSizeTemplate) || !$dataReader instanceof PaginatorInterface) { return ''; } @@ -914,14 +912,9 @@ private function renderPageSize(): string : Html::tag($this->pageSizeTag, $content, $this->pageSizeAttributes)->encode(false)->render(); } - private function renderSummary(): string + private function renderSummary(?ReadableDataInterface $dataReader): string { - if (empty($this->summaryTemplate)) { - return ''; - } - - $dataReader = $this->preparedDataReader; - if (!$dataReader instanceof OffsetPaginator) { + if (empty($this->summaryTemplate) || !$dataReader instanceof OffsetPaginator) { return ''; } diff --git a/src/GridView.php b/src/GridView.php index 50773a615..306f64672 100644 --- a/src/GridView.php +++ b/src/GridView.php @@ -472,8 +472,11 @@ public function sortableHeaderDescAppend(string|Stringable $content): self /** * Renders the data active record classes for the grid view. */ - protected function renderItems(array $items, ValidationResult $filterValidationResult): string - { + protected function renderItems( + array $items, + ValidationResult $filterValidationResult, + ?ReadableDataInterface $preparedDataReader, + ): string { $columns = $this->getColumns(); $renderers = $this->getColumnRenderers(); @@ -489,9 +492,9 @@ protected function renderItems(array $items, ValidationResult $filterValidationR $this->translationCategory, ); - if ($this->preparedDataReader instanceof PaginatorInterface) { - $pageToken = $this->preparedDataReader->isOnFirstPage() ? null : $this->preparedDataReader->getToken(); - $pageSize = $this->preparedDataReader->getPageSize(); + if ($preparedDataReader instanceof PaginatorInterface) { + $pageToken = $preparedDataReader->isOnFirstPage() ? null : $preparedDataReader->getToken(); + $pageSize = $preparedDataReader->getPageSize(); if ($pageSize === $this->getDefaultPageSize()) { $pageSize = null; } @@ -564,7 +567,7 @@ protected function renderItems(array $items, ValidationResult $filterValidationR if ($this->headerTableEnabled) { $headerContext = new HeaderContext( $this->getSort($dataReader), - $this->getSort($this->preparedDataReader), + $this->getSort($preparedDataReader), $this->getOrderProperties(), $this->sortableHeaderClass, $this->sortableHeaderPrepend, diff --git a/src/ListView.php b/src/ListView.php index b37608375..37a84351d 100644 --- a/src/ListView.php +++ b/src/ListView.php @@ -6,6 +6,7 @@ use Closure; use InvalidArgumentException; +use Yiisoft\Data\Reader\ReadableDataInterface; use Yiisoft\Html\Html; use Yiisoft\View\Exception\ViewNotFoundException; use Yiisoft\View\View; @@ -273,8 +274,11 @@ protected function renderItem(ListItemContext $context): string * * @throws ViewNotFoundException If the item view file doesn't exist. */ - protected function renderItems(array $items, \Yiisoft\Validator\Result $filterValidationResult): string - { + protected function renderItems( + array $items, + \Yiisoft\Validator\Result $filterValidationResult, + ?ReadableDataInterface $preparedDataReader, + ): string { $keys = array_keys($items); $rows = []; diff --git a/tests/GridView/ImmutableTest.php b/tests/GridView/ImmutableTest.php index fa73c30fd..27b08b520 100644 --- a/tests/GridView/ImmutableTest.php +++ b/tests/GridView/ImmutableTest.php @@ -5,6 +5,7 @@ namespace Yiisoft\Yii\DataView\Tests\GridView; use PHPUnit\Framework\TestCase; +use Yiisoft\Data\Reader\ReadableDataInterface; use Yiisoft\Definitions\Exception\CircularReferenceException; use Yiisoft\Definitions\Exception\InvalidConfigException; use Yiisoft\Definitions\Exception\NotInstantiableException; @@ -68,8 +69,11 @@ public function testGridView(): void private function createBaseListView(): DataView\BaseListView { return new class () extends DataView\BaseListView { - public function renderItems(array $items, \Yiisoft\Validator\Result $filterValidationResult): string - { + public function renderItems( + array $items, + \Yiisoft\Validator\Result $filterValidationResult, + ?ReadableDataInterface $preparedDataReader, + ): string { return ''; } };