Pagerfanta

Documentation

Available Adapters

The Pagerfanta package provides out-of-the-box support for a number of storage backends. Please review the installation guide for details on how to install optional packages.

Third Party

Adapters are provided for a number of third party storage solutions, allowing this package to be used in a variety of environments.

Doctrine

Adapters are available for a number of Doctrine packages.

Collections

The collections adapters are available with the pagerfanta/doctrine-collections-adapter package for use with Doctrine Collections.

Below is an example of using the CollectionAdapter on a collection from an entity.

<?php

use App\Entity\User;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Pagerfanta\Doctrine\Collections\CollectionAdapter;

$config = new Configuration();

$connection = [
    'driver' => 'pdo_sqlite',
    'memory' => true,
];

$em = EntityManager::create($connection, $config);

$user = $em->find(User::class, 1);

$adapter = new CollectionAdapter($user->getGroups());

Below is an example of using the SelectableAdapter on a class which implements Doctrine\Common\Collection\Selectable (such as a Doctrine\ORM\PersistentCollection).

<?php

use App\Entity\User;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Pagerfanta\Doctrine\Collections\SelectableAdapter;

$config = new Configuration();

$connection = [
    'driver' => 'pdo_sqlite',
    'memory' => true,
];

$em = EntityManager::create($connection, $config);

$user = $em->find(User::class, 1);

$criteria = Criteria::create()->andWhere(Criteria::expr()->in('id', [1, 2, 3]));

$adapter = new SelectableAdapter($user->getGroups(), $criteria);

DBAL

The DBAL adapters are available with the pagerfanta/doctrine-dbal-adapter package for use with Doctrine's DBAL.

The SingleTableQueryAdapter is a helper class which is optimized for queries which do not have any join statements.

The class constructor requires a Doctrine\DBAL\Query\QueryBuilder and the field name that should be counted (typically this will be your primary key).

Using this adapter requires that you have a table alias for your query.

Below is an example of using the SingleTableQueryAdapter.

<?php

use Doctrine\DBAL\DriverManager;
use Pagerfanta\Doctrine\DBAL\SingleTableQueryAdapter;

$params = [
    'driver' => 'pdo_sqlite',
    'memory' => true,
];

$connection = DriverManager::getConnection($params);

$query = $connection->createQueryBuilder()
    ->select('p.*')
    ->from('posts', 'p');

$adapter = new SingleTableQueryAdapter($query, 'p.id');

The QueryAdapter is the main adapter for use with the DBAL package, you should use this on queries that have join statements.

The class constructor requires a Doctrine\DBAL\Query\QueryBuilder and a callable which can be used to modify a clone of the QueryBuilder for a COUNT query. The callable should have a signature of function (QueryBuilder $queryBuilder): void {}.

Below is an example of using the QueryAdapter.

<?php

use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Query\QueryBuilder;
use Pagerfanta\Doctrine\DBAL\QueryAdapter;

$params = [
    'driver' => 'pdo_sqlite',
    'memory' => true,
];

$connection = DriverManager::getConnection($params);

$query = $connection->createQueryBuilder()
    ->select('p.*')
    ->from('posts', 'p');

$countQueryBuilderModifier = static function (QueryBuilder $queryBuilder): void {
    $queryBuilder->select('COUNT(DISTINCT p.id) AS total_results')
        ->setMaxResults(1);
};

$adapter = new QueryAdapter($query, $countQueryBuilderModifier);

MongoDB ODM

The MongoDB ODM adapter is available with the pagerfanta/doctrine-mongodb-odm-adapter package for use with Doctrine' MongoDB ODM.

The class constructor requires a Doctrine\ODM\MongoDB\Query\Builder.

Below is an example of using the QueryAdapter.

<?php

use App\Document\Article;
use Doctrine\ODM\MongoDB\Configuration;
use Doctrine\ODM\MongoDB\DocumentManager;
use Pagerfanta\Doctrine\MongoDBODM\QueryAdapter;

$config = new Configuration();

$dm = DocumentManager::create(null, $config);

$query = $dm->createQueryBuilder(Article::class);

$adapter = new QueryAdapter($query);

ORM

The ORM adapter is available with the pagerfanta/doctrine-orm-adapter package for use with Doctrine's ORM.

The class constructor requires either a Doctrine\ORM\Query or Doctrine\ORM\QueryBuilder instance. You can also specify whether to query join collections or use output walkers on the underlying Paginator.

Below is an example of using the QueryAdapter.

<?php

use App\Entity\User;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Pagerfanta\Doctrine\ORM\QueryAdapter;

$config = new Configuration();

$connection = [
    'driver' => 'pdo_sqlite',
    'memory' => true,
];

$em = EntityManager::create($connection, $config);

$repository = $em->getRepository(User::class);

$query = $repository->createQueryBuilder('u');

$adapter = new QueryAdapter($query);

PHPCR ODM

The PHPCR ODM adapter is available with the pagerfanta/doctrine-phpcr-odm-adapter package for use with Doctrine's PHPCR ODM.

The class constructor requires a Doctrine\ODM\PHPCR\Query\Builder\QueryBuilder.

Below is an example of using the QueryAdapter.

<?php

use App\Document\Article;
use Doctrine\ODM\PHPCR\Configuration;
use Doctrine\ODM\PHPCR\DocumentManager;
use Pagerfanta\Doctrine\PHPCRODM\QueryAdapter;

$config = new Configuration();

$dm = DocumentManager::create($session, $config);

$query = $dm->createQueryBuilder()
    ->from(Article::class);

$adapter = new QueryAdapter($query);

Elastica

The Elastica adapter is available with the pagerfanta/elastica-adapter package for use with Elastica.

<?php

use Elastica\Index;
use Elastica\Query;
use Elastica\Query\Term;
use Pagerfanta\Elastica\ElasticaAdapter;

// Searchable can be any valid searchable Elastica object. For example, a Type or Index
$searchable = new Index($elasticaClient, 'index_name');

// A Query can be any valid Elastica query (json, array, Query object)
$query = Query::create(
    new Term(
        [
            'name' => 'Fred',
        ]
    )
);

$adapter = new ElasticaAdapter($searchable, $query);
Be careful when paginating a huge set of documents. By default, offset + limit cannot exceed 10,000 items. You can mitigate this by setting the $maxResults parameter when constructing the ElasticaAdapter. For more information, see https://github.com/whiteoctober/Pagerfanta/pull/213#issue-87631892.

Solarium

The Solarium adapter is available with the pagerfanta/solarium-adapter package for use with Solarium.

<?php

use Pagerfanta\Solarium\SolariumAdapter;

$query = $solarium->createSelect();
$query->setQuery('search term');

$adapter = new SolariumAdapter($solarium, $query);

First Party

There are also several "first party" adapters which are not dependent upon an external storage solution. All first party adapters are available with the pagerfanta/core package.

Array

The ArrayAdapter is used to paginate an array of items.

<?php

use Pagerfanta\Adapter\ArrayAdapter;

$adapter = new ArrayAdapter([]);

Callback

The CallbackAdapter uses callable functions to process pagination.

The adapter takes two callables:

  • $nbResultsCallable: A callable to count the number items in the list, the callable should have a signature of function (): int {}
  • $sliceCallable: A callable to get the items for the current page in the paginated list, the callable should have a signature of function (int $offset, int $length): iterable {}
<?php

use Pagerfanta\Adapter\CallbackAdapter;

$adapter = new CallbackAdapter(
    static fn (): int => 0,
    static fn (int $offset, int $length): iterable => []
);

Concatenation

The ConcatenationAdapter allows querying results from multiple adapters. It keeps the order of the given adapters and the order of their results.

<?php

use Pagerfanta\Adapter\ArrayAdapter;
use Pagerfanta\Adapter\ConcatenationAdapter;

$adapter = new ConcatenationAdapter(
    [
        new ArrayAdapter([]),
        new ArrayAdapter([]),
    ]
);

Fixed Size

The FixedAdapter takes a fixed data set and returns it no matter the request.

It is best used when you need to do a custom paging solution and don't want to implement a full adapter for a one-off use case.

<?php

use Pagerfanta\Adapter\FixedAdapter;

$adapter = new FixedAdapter(5, ['boo', 'doo', 'foo', 'goo', 'moo']);

Null Values

The NullAdapter generates a list of null values for the number of items specified, useful in a testing environment where you don't want to set up a database.

<?php

use Pagerfanta\Adapter\NullAdapter;

$adapter = new NullAdapter(5);

Transforming

The TransformingAdapter is an adapter decorator which can be used to standardize the data from the wrapped adapter.

The transformer is a callable which accepts the item to be transformed and the key from the iterable, it should have a signature of function (mixed $item, int|string $key): mixed {}

<?php

use Pagerfanta\Adapter\ArrayAdapter;
use Pagerfanta\Adapter\TransformingAdapter;

$formatter = new \NumberFormatter('en', \NumberFormatter::SPELLOUT);

$adapter = new TransformingAdapter(
    new ArrayAdapter(range(1, 100)),
    static fn (int $item, int $key): string => $formatter->format($item)
);