Adapters
CursorPagination builds the query of each page, its order and its cursor condition. Running it, limited to
$maxPerPages results, and counting the results, is the job of an adapter, in the Silarhi\CursorPagination\Adapter
namespace. Two adapters wrap Doctrine’s own paginators:
| Adapter | Doctrine class | doctrine/orm |
|---|---|---|
DoctrineCursorPaginatorAdapter |
Doctrine\ORM\Tools\Pagination\CursorPaginator |
3.7 and later |
DoctrinePaginatorAdapter |
Doctrine\ORM\Tools\Pagination\Paginator (deprecated) |
3.x, not 4 |
Default
Section titled “Default”Without the $adapter argument, CursorPagination uses DoctrineCursorPaginatorAdapter when CursorPaginator
exists (doctrine/orm 3.7 and later, 4 included), and DoctrinePaginatorAdapter otherwise. Pass an adapter to choose:
use Silarhi\CursorPagination\Adapter\DoctrinePaginatorAdapter;
$pagination = new CursorPagination($queryBuilder, $configurations, 100, adapter: new DoctrinePaginatorAdapter());Both give the same results. They differ in the queries they run:
- The last page.
CursorPaginatorfetches one more row than$maxPerPagesto tell whether a next page exists: the iteration ends after the last page.Paginatorcannot tell a full page from the last one, so the next page is queried, and comes back empty when the number of results is a multiple of$maxPerPages. - The count.
CursorPaginatoronly counts the results of a page it fetched:DoctrineCursorPaginatorAdapterbuilds the same count query with Doctrine’sCountWalkerandCountOutputWalker. See counting.
CursorPaginator is called without a Doctrine cursor: CursorPagination keeps its own cursor condition, which handles
any order expression, and reads its values with the closures of the order configurations, scalar rows included. See Doctrine’s CursorPaginator for how the two compare.
PaginatorAdapterInterface
Section titled “PaginatorAdapterInterface”interface PaginatorAdapterInterface{ public function fetchPage(Query $query, int $maxResults, bool $fetchJoinCollection, ?bool $useOutputWalkers): PageResult;
public function count(Query $query, ?bool $useOutputWalkers): int;}fetchPage()returns the first$maxResultsresults of$query, in the order of itsORDER BY, which already holds the cursor condition. With$fetchJoinCollection,$maxResultscounts root entities: the page’s distinct ids, then their rows.PageResult::$hasMoretells whether a next page may hold results;falseends the iteration without querying it.count()counts the results of$query: distinct root entities, or rows when the query’sCountWalker::HINT_DISTINCThint isfalse.
CursorPagination creates a new Query for each call: an adapter may change it. $useOutputWalkers is the
CursorPagination argument, or the choice made for the count (see output walkers);
null means Doctrine’s default.
