diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fa2860..95ab028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,7 @@ - New #232: Add `All` and `None` filters (@vjik) - Chg #233: Remove nullable types from `withFilter()` and `getFilter()` methods of `FilterableDataInterface` (@vjik) - Bug #234: Fix handling of `null` values in `IterableDataReader` (@vjik) +- New #236: Add `PaginatorInterface::getFilter()` method (@vjik) ## 1.0.1 January 25, 2023 diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index f1c1e8d..bfb6354 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -199,7 +199,7 @@ public function read(): iterable } if ($this->token !== null) { - $dataReader = $dataReader->withFilter($this->getFilter($sort)); + $dataReader = $dataReader->withFilter($this->createFilter($sort)); $this->hasPreviousPage = $this->previousPageExist($dataReader, $sort); } @@ -284,6 +284,11 @@ public function isFilterable(): bool return true; } + public function getFilter(): FilterInterface + { + return $this->dataReader->getFilter(); + } + public function withFilter(FilterInterface $filter): static { $new = clone $this; @@ -376,7 +381,7 @@ private function previousPageExist(ReadableDataInterface $dataReader, Sort $sort return !empty($dataReader->withFilter($reverseFilter)->readOne()); } - private function getFilter(Sort $sort): FilterInterface + private function createFilter(Sort $sort): FilterInterface { /** * @psalm-var PageToken $this->token The code calling this method must ensure that page token is not null. diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index b916804..380969e 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -286,10 +286,19 @@ public function isFilterable(): bool return $this->dataReader instanceof FilterableDataInterface; } + public function getFilter(): FilterInterface + { + if (!$this->isFilterable()) { + throw new LogicException('Data reader doesn\'t support filtering.'); + } + + return $this->dataReader->getFilter(); + } + public function withFilter(FilterInterface $filter): static { if (!$this->isFilterable()) { - throw new LogicException('Changing filtering is not supported.'); + throw new LogicException('Data reader doesn\'t support filtering.'); } $new = clone $this; diff --git a/src/Paginator/PaginatorInterface.php b/src/Paginator/PaginatorInterface.php index c284bc1..6002b74 100644 --- a/src/Paginator/PaginatorInterface.php +++ b/src/Paginator/PaginatorInterface.php @@ -138,16 +138,26 @@ public function withSort(?Sort $sort): static; public function getSort(): ?Sort; /** - * @return bool Whether changing filter via {@see withFilter()} is supported. + * @return bool Whether data reader does support filtering. */ public function isFilterable(): bool; + /** + * Returns data reader filter. + * + * @throws LogicException When data reader doesn't support filter. + * + * @return FilterInterface Data reader filter. + */ + public function getFilter(): FilterInterface; + /** * Returns new instance with data reading criteria set. * * @param FilterInterface $filter Data reading criteria. * - * @throws LogicException When changing filter isn't supported. + * @throws LogicException When data reader doesn't support filter. + * * @return static New instance. */ public function withFilter(FilterInterface $filter): static; diff --git a/tests/Paginator/KeysetPaginatorTest.php b/tests/Paginator/KeysetPaginatorTest.php index d444dcb..8250c22 100644 --- a/tests/Paginator/KeysetPaginatorTest.php +++ b/tests/Paginator/KeysetPaginatorTest.php @@ -822,7 +822,7 @@ public function testGetPreviousPageExistForCoverage(): void $this->assertTrue($this->invokeMethod($paginator, 'previousPageExist', [$dataReader, $sort])); } - public function testGetFilterForCoverage(): void + public function testCreateFilterForCoverage(): void { $sort = Sort::only(['id'])->withOrderString('id'); $dataReader = (new IterableDataReader([]))->withSort($sort); @@ -830,7 +830,7 @@ public function testGetFilterForCoverage(): void $this->assertInstanceOf( GreaterThan::class, - $this->invokeMethod($paginator, 'getFilter', [$sort]), + $this->invokeMethod($paginator, 'createFilter', [$sort]), ); $sort = Sort::only(['id']) @@ -841,7 +841,7 @@ public function testGetFilterForCoverage(): void $this->assertInstanceOf( LessThan::class, - $this->invokeMethod($paginator, 'getFilter', [$sort]), + $this->invokeMethod($paginator, 'createFilter', [$sort]), ); } @@ -1253,4 +1253,13 @@ public function testPreviousPageIterativeReading(): void // Verify we got all the data $this->assertSame($dataSet, $allData); } + + public function testGetFilter(): void + { + $filter = new All(); + $dataReader = (new IterableDataReader([]))->withFilter($filter)->withSort(Sort::only(['id'])); + $paginator = new KeysetPaginator($dataReader); + + $this->assertSame($filter, $paginator->getFilter()); + } } diff --git a/tests/Paginator/OffsetPaginatorTest.php b/tests/Paginator/OffsetPaginatorTest.php index 5ecdad8..320251e 100644 --- a/tests/Paginator/OffsetPaginatorTest.php +++ b/tests/Paginator/OffsetPaginatorTest.php @@ -13,6 +13,7 @@ use Yiisoft\Data\Paginator\PageToken; use Yiisoft\Data\Paginator\PaginatorInterface; use Yiisoft\Data\Reader\CountableDataInterface; +use Yiisoft\Data\Reader\Filter\All; use Yiisoft\Data\Reader\Filter\Equals; use Yiisoft\Data\Reader\Iterable\IterableDataReader; use Yiisoft\Data\Reader\LimitableDataInterface; @@ -587,8 +588,8 @@ public function testWithFilterNonFilterableData(): void $paginator = new OffsetPaginator(new StubOffsetData()); $this->expectException(LogicException::class); - $this->expectExceptionMessage('Changing filtering is not supported.'); - $paginator->withFilter(new Equals('id', 2)); + $this->expectExceptionMessage('Data reader doesn\'t support filtering.'); + $paginator->withFilter(new All()); } public function testWithNulledPageToken(): void @@ -754,4 +755,22 @@ public function testPreviousPageIterativeReading(): void // Verify we got all the data $this->assertSame($dataSet, $allData); } + + public function testGetFilter(): void + { + $filter = new All(); + $dataReader = (new IterableDataReader([]))->withFilter($filter); + $paginator = new OffsetPaginator($dataReader); + + $this->assertSame($filter, $paginator->getFilter()); + } + + public function testGetFilterWithNonFilterableDataReader(): void + { + $paginator = new OffsetPaginator(new StubOffsetData()); + + $this->expectException(LogicException::class); + $this->expectExceptionMessage('Data reader doesn\'t support filtering.'); + $paginator->getFilter(); + } }