Skip to content

Commit

Permalink
feat: add Closure type parameter for count in all Pageable implemen…
Browse files Browse the repository at this point in the history
…tations (#108)

* feat: add `Closure` type parameter for count in all Pageable implementations

* fix
  • Loading branch information
priyadi authored Jun 28, 2024
1 parent 708f568 commit 3b98eb7
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

# 0.12.3

* feat: add `Closure` type parameter for count in all Pageable implementations

# 0.12.2

* fix(`PagerFantaAdapterAdapter`): rename `$pagerfanta` to `$adapter`
Expand Down
15 changes: 11 additions & 4 deletions packages/rekapager-keyset-pagination/src/KeysetPageable.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ final class KeysetPageable implements PageableInterface
/**
* @param KeysetPaginationAdapterInterface<TKey,T> $adapter
* @param int<1,max> $itemsPerPage
* @param int<0,max>|bool|\Closure():(int<0,max>|bool) $count
*/
public function __construct(
private readonly KeysetPaginationAdapterInterface $adapter,
private readonly int $itemsPerPage = 50,
private readonly int|bool $count = false,
private readonly int|bool|\Closure $count = false,
) {
}

Expand Down Expand Up @@ -138,11 +139,17 @@ public function getPageByIdentifier(object $pageIdentifier): PageInterface

public function getTotalItems(): ?int
{
if (\is_int($this->count) && $this->count >= 0) {
return $this->count;
if ($this->count instanceof \Closure) {
$count = ($this->count)();
} else {
$count = $this->count;
}

if (\is_int($count) && $count >= 0) {
return $count;
}

if ($this->count === false) {
if ($count === false) {
return null;
}

Expand Down
16 changes: 11 additions & 5 deletions packages/rekapager-offset-pagination/src/OffsetPageable.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ final class OffsetPageable implements PageableInterface
/**
* @param OffsetPaginationAdapterInterface<TKey,T> $adapter
* @param int<1,max> $itemsPerPage
* @param int<0,max>|bool $count
* @param int<0,max>|bool|\Closure():(int<0,max>|bool) $count
* @param null|int<1,max> $pageLimit
*/
public function __construct(
private readonly OffsetPaginationAdapterInterface $adapter,
private readonly int $itemsPerPage = 50,
private readonly int|bool $count = false,
private readonly int|bool|\Closure $count = false,
private readonly ?int $pageLimit = 100,
) {
}
Expand Down Expand Up @@ -114,11 +114,17 @@ public function getPageByIdentifier(object $pageIdentifier): PageInterface

public function getTotalItems(): ?int
{
if (\is_int($this->count) && $this->count >= 0) {
return $this->count;
if ($this->count instanceof \Closure) {
$count = ($this->count)();
} else {
$count = $this->count;
}

if ($this->count === false) {
if (\is_int($count) && $count >= 0) {
return $count;
}

if ($count === false) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ final class PagerfantaPageable implements PageableInterface

/**
* @param PagerfantaInterface<T> $pagerfanta
* @param int<0,max>|bool $count
* @param int<0,max>|bool|\Closure():(int<0,max>|bool) $count
* @param null|int<1,max> $pageLimit
*/
public function __construct(
private readonly PagerfantaInterface $pagerfanta,
private readonly int|bool $count = false,
private readonly int|bool|\Closure $count = false,
private readonly ?int $pageLimit = 100,
string|null $indexBy = null,
) {
Expand Down
4 changes: 2 additions & 2 deletions tests/src/App/Contracts/PageableGeneratorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ public function getTitle(): string;

/**
* @param int<1,max> $itemsPerPage
* @param bool|int<0,max> $count
* @param bool|int<0,max>|\Closure():(int<0,max>|bool) $count
* @param int<1,max>|null $pageLimit
* @return PageableInterface<TKey,T>
*/
public function generatePageable(
int $itemsPerPage,
bool|int $count,
bool|int|\Closure $count,
string $setName,
?int $pageLimit = null,
): PageableInterface;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function getTitle(): string

public function generatePageable(
int $itemsPerPage,
bool|int $count,
bool|int|\Closure $count,
string $setName,
?int $pageLimit = null,
): PageableInterface {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function getTitle(): string

public function generatePageable(
int $itemsPerPage,
bool|int $count,
bool|int|\Closure $count,
string $setName,
?int $pageLimit = null,
): PageableInterface {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function getTitle(): string

public function generatePageable(
int $itemsPerPage,
bool|int $count,
bool|int|\Closure $count,
string $setName,
?int $pageLimit = null,
): PageableInterface {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function getTitle(): string

public function generatePageable(
int $itemsPerPage,
bool|int $count,
bool|int|\Closure $count,
string $setName,
?int $pageLimit = null,
): PageableInterface {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function getTitle(): string

public function generatePageable(
int $itemsPerPage,
bool|int $count,
bool|int|\Closure $count,
string $setName,
?int $pageLimit = null,
): PageableInterface {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function getTitle(): string

public function generatePageable(
int $itemsPerPage,
bool|int $count,
bool|int|\Closure $count,
string $setName,
?int $pageLimit = null,
): PageableInterface {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function getTitle(): string

public function generatePageable(
int $itemsPerPage,
bool|int $count,
bool|int|\Closure $count,
string $setName,
?int $pageLimit = null,
): PageableInterface {
Expand Down
4 changes: 2 additions & 2 deletions tests/src/IntegrationTests/Pageable/PageableTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ protected function getItemsPerPage(): int
}

/**
* @return bool|int<0,max>
* @return bool|int<0,max>|(\Closure():int<0,max>|bool)
*/
protected function getPagerCount(): bool|int
protected function getPagerCount(): bool|int|\Closure
{
return false;
}
Expand Down
170 changes: 170 additions & 0 deletions tests/src/UnitTests/CountTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/rekapager package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Rekapager\Tests\UnitTests;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Selectable;
use Pagerfanta\Doctrine\Collections\SelectableAdapter as PagerfantaSelectableAdapter;
use PHPUnit\Framework\TestCase;
use Rekalogika\Contracts\Rekapager\PageableInterface;
use Rekalogika\Rekapager\Doctrine\Collections\SelectableAdapter;
use Rekalogika\Rekapager\Keyset\KeysetPageable;
use Rekalogika\Rekapager\Offset\OffsetPageable;
use Rekalogika\Rekapager\Pagerfanta\PagerfantaAdapterAdapter;
use Rekalogika\Rekapager\Tests\UnitTests\Fixtures\Entity;

class CountTest extends TestCase
{
/**
* @psalm-suppress InvalidReturnType
* @psalm-suppress MixedReturnTypeCoercion
* @return iterable<array-key,array{Collection<array-key,Entity>,PageableInterface<array-key,Entity>,mixed}>
*/
public static function provider(): iterable
{
/** @var Collection<array-key,Entity>&Selectable<array-key,Entity> */
$collection = new ArrayCollection([
new Entity(1),
new Entity(2),
new Entity(3),
new Entity(4),
new Entity(5)
]);

// offset pageable

yield [
$collection,
new OffsetPageable(
adapter: new SelectableAdapter(
collection: $collection
)
),
null,
];

yield [
$collection,
new OffsetPageable(
adapter: new SelectableAdapter(
collection: $collection
),
count: true,
),
5,
];

/** @psalm-suppress ArgumentTypeCoercion */
yield [
$collection,
new OffsetPageable(
adapter: new SelectableAdapter(
collection: $collection
),
count: function () use ($collection) {
return $collection->count();
},
),
5,
];

// keyset pageable

yield [
$collection,
new KeysetPageable(
adapter: new SelectableAdapter(
collection: $collection
),
),
null
];

yield [
$collection,
new KeysetPageable(
adapter: new SelectableAdapter(
collection: $collection
),
count: true,
),
5,
];

/** @psalm-suppress ArgumentTypeCoercion */
yield [
$collection,
new KeysetPageable(
adapter: new SelectableAdapter(
collection: $collection
),
count: function () use ($collection) {
return $collection->count();
},
),
5,
];

// @phpstan-ignore-next-line
yield [
$collection,
new OffsetPageable(
adapter: new PagerfantaAdapterAdapter(
adapter: new PagerfantaSelectableAdapter($collection, Criteria::create())
)
),
null
];

yield [
$collection,
new OffsetPageable(
adapter: new PagerfantaAdapterAdapter(
adapter: new PagerfantaSelectableAdapter($collection, Criteria::create())
),
count: true,
),
5,
];

/** @psalm-suppress ArgumentTypeCoercion */
yield [
$collection,
new OffsetPageable(
adapter: new PagerfantaAdapterAdapter(
adapter: new PagerfantaSelectableAdapter($collection, Criteria::create())
),
count: function () use ($collection) {
return $collection->count();
},
),
5,
];
}

/**
* @param Collection<array-key,Entity> $collection
* @param PageableInterface<array-key,Entity> $pageable
* @dataProvider provider
*/
public function testNoCount(
Collection $collection,
PageableInterface $pageable,
mixed $expected,
): void {
$this->assertSame($expected, $pageable->getTotalItems());
}
}

0 comments on commit 3b98eb7

Please sign in to comment.