Skip to content

Commit

Permalink
feat: pagerfanta adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
priyadi committed Mar 31, 2024
1 parent 565cd5f commit 2b145a0
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 17 deletions.
21 changes: 13 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"Rekalogika\\Rekapager\\Doctrine\\ORM\\": "packages/rekapager-doctrine-orm-adapter/src/",
"Rekalogika\\Rekapager\\Keyset\\": "packages/rekapager-keyset-pagination/src/",
"Rekalogika\\Rekapager\\Offset\\": "packages/rekapager-offset-pagination/src/",
"Rekalogika\\Rekapager\\Pagerfanta\\": "packages/rekapager-pagerfanta-adapter/src/",
"Rekalogika\\Rekapager\\Symfony\\": "packages/rekapager-bundle/src/"
}
},
Expand All @@ -30,6 +31,8 @@
"php": "^8.2",
"doctrine/collections": "^2.2",
"doctrine/orm": "^2.14 || ^3.0",
"pagerfanta/core": "^4.0",
"pagerfanta/doctrine-collections-adapter": "^4.0",
"psr/container": "^2.0",
"spomky-labs/base64url": "^2.0",
"symfony/config": "^6.4 || ^7.0",
Expand All @@ -46,7 +49,7 @@
"doctrine/doctrine-fixtures-bundle": "^3.5",
"doctrine/persistence": "^3.1",
"ekino/phpstan-banned-code": "^1.0",
"fakerphp/faker":"^1.23",
"fakerphp/faker": "^1.23",
"phpstan/phpstan": "^1.10.66 || ^1.11",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpstan/phpstan-phpunit": "^1.3",
Expand All @@ -55,6 +58,7 @@
"psalm/plugin-symfony": "^5.1",
"psr/log": "^2.0",
"ramsey/uuid": "^4.7",
"rekalogika/doctrine-collections-decorator": "^2.3",
"symfony/debug-bundle": "^6.4 || ^7.0",
"symfony/doctrine-bridge": "^6.4 || ^7.0",
"symfony/dotenv": "^6.4 || ^7.0",
Expand All @@ -80,12 +84,13 @@
}
},
"replace": {
"rekalogika/rekapager-bundle": "self.version",
"rekalogika/rekapager-contracts": "self.version",
"rekalogika/rekapager-core": "self.version",
"rekalogika/rekapager-doctrine-collections-adapter": "self.version",
"rekalogika/rekapager-doctrine-orm-adapter": "self.version",
"rekalogika/rekapager-keyset-pagination": "self.version",
"rekalogika/rekapager-offset-pagination": "self.version"
"rekalogika/rekapager-bundle": "0.5.0",
"rekalogika/rekapager-contracts": "0.5.0",
"rekalogika/rekapager-core": "0.5.0",
"rekalogika/rekapager-doctrine-collections-adapter": "0.5.0",
"rekalogika/rekapager-doctrine-orm-adapter": "0.5.0",
"rekalogika/rekapager-keyset-pagination": "0.5.0",
"rekalogika/rekapager-offset-pagination": "0.5.0",
"rekalogika/rekapager-pagerfanta-adapter": "0.5.0"
}
}
3 changes: 3 additions & 0 deletions packages/rekapager-pagerfanta-adapter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# rekalogika/pager

A pagination library for PHP.
24 changes: 24 additions & 0 deletions packages/rekapager-pagerfanta-adapter/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "rekalogika/rekapager-pagerfanta-adapter",
"description": "Adapts Pagerfanta and its adapters for use with Rekapager pagination library",
"homepage": "https://rekalogika.dev/rekapager",
"keywords": [],
"license": "MIT",
"type": "library",
"authors": [
{
"name": "Priyadi Iman Nurcahyo",
"email": "priyadi@rekalogika.com"
}
],
"autoload": {
"psr-4": {
"Rekalogika\\Rekapager\\Pagerfanta\\": "src/"
}
},
"require": {
"php": "^8.2",
"rekalogika/rekapager-contracts": "^0.5",
"rekalogika/rekapager-offset-pagination": "^0.5"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?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\Pagerfanta;

use Pagerfanta\Adapter\AdapterInterface;
use Rekalogika\Rekapager\Offset\OffsetPaginationAdapterInterface;

/**
* @template T
* @implements OffsetPaginationAdapterInterface<array-key,T>
*/
final class PagerfantaAdapterAdapter implements OffsetPaginationAdapterInterface
{
/**
* @param AdapterInterface<T> $pagerfanta
*/
public function __construct(
private readonly AdapterInterface $pagerfanta
) {
}

public function getOffsetItems(int $offset, int $limit): array
{
$this->pagerfanta->getSlice($offset, $limit);

/** @psalm-suppress InvalidArgument */
return iterator_to_array($this->pagerfanta->getSlice($offset, $limit));
}

public function countOffsetItems(int $offset = 0, ?int $limit = null): ?int
{
if ($limit === null) {
return null;
}

$slice = $this->pagerfanta->getSlice($offset, $limit);
$count = 0;

foreach ($slice as $item) {
$count++;
}

return $count;
}

public function countItems(): int
{
return $this->pagerfanta->getNbResults();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace Rekalogika\Rekapager\Tests\App\PageableGenerator;

use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Selectable;
use Rekalogika\Collections\Decorator\LazyMatching\LazyMatchingCollection;
use Rekalogika\Contracts\Rekapager\PageableInterface;
use Rekalogika\Rekapager\Doctrine\Collections\CollectionAdapter;
use Rekalogika\Rekapager\Offset\Contracts\PageNumber;
Expand Down Expand Up @@ -54,19 +54,14 @@ public function generatePageable(
}

// @highlight-start
$posts = $user->getPosts();
\assert($posts instanceof Selectable);
$filteredPosts = $posts->matching(
// LazyMatchingCollection is part of rekalogika/doctrine-collections-decorator package
$lazyPosts = new LazyMatchingCollection($user->getPosts());
$filteredPosts = $lazyPosts->matching(
Criteria::create()
->where(Criteria::expr()->eq('setName', $setName))
);

/**
* @psalm-suppress ArgumentTypeCoercion
* @phpstan-ignore-next-line
*/
$adapter = new CollectionAdapter($filteredPosts);

Check failure on line 64 in tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php

View workflow job for this annotation

GitHub Actions / Symfony 6.*, highest deps, PHP 8.2, ubuntu-latest

ArgumentTypeCoercion

tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php:64:42: ArgumentTypeCoercion: Argument 1 of Rekalogika\Rekapager\Doctrine\Collections\CollectionAdapter::__construct expects Doctrine\Common\Collections\Collection<array-key, mixed>, but parent type Doctrine\Common\Collections\ReadableCollection<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\Selectable&Doctrine\Common\Collections\Selectable<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\ReadableCollection provided (see https://psalm.dev/193)

Check failure on line 64 in tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php

View workflow job for this annotation

GitHub Actions / Symfony 6.*, lowest deps, PHP 8.2, ubuntu-latest

ArgumentTypeCoercion

tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php:64:42: ArgumentTypeCoercion: Argument 1 of Rekalogika\Rekapager\Doctrine\Collections\CollectionAdapter::__construct expects Doctrine\Common\Collections\Collection<array-key, mixed>, but parent type Doctrine\Common\Collections\ReadableCollection<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\Selectable&Doctrine\Common\Collections\Selectable<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\ReadableCollection provided (see https://psalm.dev/193)

Check failure on line 64 in tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php

View workflow job for this annotation

GitHub Actions / Symfony 7.*, highest deps, PHP 8.2, ubuntu-latest

ArgumentTypeCoercion

tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php:64:42: ArgumentTypeCoercion: Argument 1 of Rekalogika\Rekapager\Doctrine\Collections\CollectionAdapter::__construct expects Doctrine\Common\Collections\Collection<array-key, mixed>, but parent type Doctrine\Common\Collections\ReadableCollection<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\Selectable&Doctrine\Common\Collections\Selectable<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\ReadableCollection provided (see https://psalm.dev/193)

Check failure on line 64 in tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php

View workflow job for this annotation

GitHub Actions / Symfony 7.*, lowest deps, PHP 8.2, ubuntu-latest

ArgumentTypeCoercion

tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php:64:42: ArgumentTypeCoercion: Argument 1 of Rekalogika\Rekapager\Doctrine\Collections\CollectionAdapter::__construct expects Doctrine\Common\Collections\Collection<array-key, mixed>, but parent type Doctrine\Common\Collections\ReadableCollection<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\Selectable&Doctrine\Common\Collections\Selectable<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\ReadableCollection provided (see https://psalm.dev/193)

Check failure on line 64 in tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php

View workflow job for this annotation

GitHub Actions / Symfony 6.*, highest deps, PHP 8.3, ubuntu-latest

ArgumentTypeCoercion

tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php:64:42: ArgumentTypeCoercion: Argument 1 of Rekalogika\Rekapager\Doctrine\Collections\CollectionAdapter::__construct expects Doctrine\Common\Collections\Collection<array-key, mixed>, but parent type Doctrine\Common\Collections\ReadableCollection<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\Selectable&Doctrine\Common\Collections\Selectable<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\ReadableCollection provided (see https://psalm.dev/193)

Check failure on line 64 in tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php

View workflow job for this annotation

GitHub Actions / Symfony 7.*, highest deps, PHP 8.3, ubuntu-latest

ArgumentTypeCoercion

tests/src/App/PageableGenerator/OffsetPageableCollectionAdapterCollection.php:64:42: ArgumentTypeCoercion: Argument 1 of Rekalogika\Rekapager\Doctrine\Collections\CollectionAdapter::__construct expects Doctrine\Common\Collections\Collection<array-key, mixed>, but parent type Doctrine\Common\Collections\ReadableCollection<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\Selectable&Doctrine\Common\Collections\Selectable<array-key, Rekalogika\Rekapager\Tests\App\Entity\Post>&Doctrine\Common\Collections\ReadableCollection provided (see https://psalm.dev/193)

$pageable = new OffsetPageable(
adapter: $adapter,
itemsPerPage: $itemsPerPage,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?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\App\PageableGenerator;

use Doctrine\Common\Collections\Criteria;
use Pagerfanta\Doctrine\Collections\SelectableAdapter;
use Rekalogika\Collections\Decorator\LazyMatching\LazyMatchingCollection;
use Rekalogika\Contracts\Rekapager\PageableInterface;
use Rekalogika\Rekapager\Offset\Contracts\PageNumber;
use Rekalogika\Rekapager\Offset\OffsetPageable;
use Rekalogika\Rekapager\Pagerfanta\PagerfantaAdapterAdapter;
use Rekalogika\Rekapager\Tests\App\Contracts\PageableGeneratorInterface;
use Rekalogika\Rekapager\Tests\App\Entity\Post;
use Rekalogika\Rekapager\Tests\App\Repository\UserRepository;

/**
* @implements PageableGeneratorInterface<int,Post,PageNumber>
*/
class OffsetPageablePagerfantaAdapterAdapter implements PageableGeneratorInterface
{
public function __construct(private UserRepository $userRepository)
{
}

public static function getKey(): string
{
return 'offsetpageable-pagerfantaadapteradapter-collection';
}

public function getTitle(): string
{
return 'OffsetPageable - PagerfantaAdapterAdapter - PagerfantaSelectableAdapter - Collection';
}

public function generatePageable(
int $itemsPerPage,
bool|int $count,
string $setName,
?int $pageLimit = null,
): PageableInterface {
$user = $this->userRepository->findOneBy([]);
if ($user === null) {
throw new \RuntimeException('No user found');
}

// @highlight-start
$criteria = Criteria::create()
->where(Criteria::expr()->eq('setName', $setName));

$pagerfantaAdapter = new SelectableAdapter($user->getPosts(), $criteria);
$adapter = new PagerfantaAdapterAdapter($pagerfantaAdapter);

$pageable = new OffsetPageable(
adapter: $adapter,
itemsPerPage: $itemsPerPage,
count: $count,
pageLimit: $pageLimit,
);
// @highlight-end

// @phpstan-ignore-next-line
return $pageable;
}

public function count(): int
{
/** @var int<0,max> */
return $this->userRepository->count([]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Rekalogika\Rekapager\Tests\App\PageableGenerator\KeysetPageableSelectableAdapterCollection;
use Rekalogika\Rekapager\Tests\App\PageableGenerator\KeysetPageableSelectableAdapterEntityRepository;
use Rekalogika\Rekapager\Tests\App\PageableGenerator\OffsetPageableCollectionAdapterCollection;
use Rekalogika\Rekapager\Tests\App\PageableGenerator\OffsetPageablePagerfantaAdapterAdapter;
use Rekalogika\Rekapager\Tests\App\PageableGenerator\OffsetPageableSelectableAdapterCollection;

final class PageableGeneratorProvider
Expand All @@ -31,6 +32,7 @@ public static function all(): iterable
yield [KeysetPageableSelectableAdapterEntityRepository::class];
yield [OffsetPageableCollectionAdapterCollection::class];
yield [OffsetPageableSelectableAdapterCollection::class];
yield [OffsetPageablePagerfantaAdapterAdapter::class];
}

/**
Expand All @@ -50,5 +52,6 @@ public static function offset(): iterable
{
yield [OffsetPageableCollectionAdapterCollection::class];
yield [OffsetPageableSelectableAdapterCollection::class];
yield [OffsetPageablePagerfantaAdapterAdapter::class];
}
}

0 comments on commit 2b145a0

Please sign in to comment.