From a937e7fde010cc8804f8659f82fcc93df7b6ed2b Mon Sep 17 00:00:00 2001 From: Unay Santisteban Date: Fri, 26 Jan 2024 16:56:31 +1000 Subject: [PATCH] Feature/Add page number support. (#20) --- README.md | 11 +++++------ src/Criteria.php | 11 ++++++++++- src/Page.php | 14 +++++++++++--- tests/CriteriaTest.php | 10 +++++++++- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 62aecfb..067fa78 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ $criteria = Criteria::default() ->withFilterGroup($g1) ->withOrderBy('surname') ->withOrderType('asc') - ->withPageLimit(10) - ->withPageOffset(5); + ->withPageLimit(25) + ->withPageOffset(50); $users = $repository->match($criteria); @@ -45,8 +45,8 @@ $criteria = Criteria::default() ->addFilterIn('country', ['es', 'fr'])) ->withOrderBy('surname') ->withOrderType('asc') - ->withPageLimit(10) - ->withPageOffset(5); + ->withPageLimit(25) + ->withPageOffset(50); // In SQL, we may have something like: // WHERE status = 1 AND followers >= 700 AND country in ('es', 'fr') @@ -66,6 +66,5 @@ $criteria = Criteria::default() ->withFilterGroup(FilterGroup::create()->addFilterContains('content', $term)) ->withOrderBy('created_at') ->withOrderType(Order::TYPE_ASC) - ->withPageLimit(10) - ->withPageOffset(5); + ->withPageNumber(3); ``` diff --git a/src/Criteria.php b/src/Criteria.php index 995bbcb..3964a2e 100644 --- a/src/Criteria.php +++ b/src/Criteria.php @@ -110,7 +110,7 @@ public function withFilterGroups(array $groups): self * Returns a new instance of the criteria adding the given FilterGroup. * * @param FilterGroup|Closure $group - * @return $this + * @return Criteria */ public function withFilterGroup(FilterGroup|Closure $group): self { @@ -175,6 +175,15 @@ public function withPageLimit(int $limit): self ); } + public function withPageNumber(int $number, int $size = null): self + { + return self::create( + groups: $this->groups, + order: $this->order, + page: Page::number($number, is_null($size) ? $this->page->limit() : $size) + ); + } + /** * Returns the list of group filters. * diff --git a/src/Page.php b/src/Page.php index 28d4b21..d41953c 100644 --- a/src/Page.php +++ b/src/Page.php @@ -17,6 +17,9 @@ final class Page implements ValueObject { use IsValueObject; + const DEFAULT_LIMIT = 25; + const DEFAULT_OFFSET = 0; + /** * Page constructor. * @@ -24,17 +27,22 @@ final class Page implements ValueObject * @param int $offset */ public function __construct( - private readonly int $limit = 25, - private readonly int $offset = 0, + private readonly int $limit = self::DEFAULT_LIMIT, + private readonly int $offset = self::DEFAULT_OFFSET, ) { $this->check(); } - public static function create(int $limit = 25, int $offset = 0): self + public static function create(int $limit = self::DEFAULT_LIMIT, int $offset = self::DEFAULT_OFFSET): self { return new self($limit, $offset); } + public static function number(int $number, int $size = self::DEFAULT_LIMIT): self + { + return self::create($size, ($size * $number) - $size); + } + protected function invariantLimitValueMustBePositive(): bool { return $this->limit >= 0; diff --git a/tests/CriteriaTest.php b/tests/CriteriaTest.php index d0c2e4f..6d117a4 100644 --- a/tests/CriteriaTest.php +++ b/tests/CriteriaTest.php @@ -144,4 +144,12 @@ public function pageOffset(): int ->withOrderType('asc'); expect($c->__toString())->toBe('name.=.Vincent+age.>=.35#name.asc#100.0'); -}); \ No newline at end of file +}); + +test('Criteria should configure limit and offset using page number', function () { + $c = Criteria::default() + ->withPageNumber(3, 25); + + expect($c->page()->limit())->toBe(25) + ->and($c->page()->offset())->toBe(50); +});