Pagination¶
Overview¶
A paginator is a component which helps with splitting a large amount of data gradually. An example would be displaying all the posts of a blog, 5 at a time. The Phalcon Paginator accepts parameters and based on those returns the relevant slice of the whole resultset so that the developer can present the paginated data.
```php
[ ["id" => 1, "name" => "Artichoke"], ["id" => 2, "name" => "Carrots"], ["id" => 3, "name" => "Beet"], ["id" => 4, "name" => "Lettuce"], ["id" => 5, "name" => ""], ], "limit" => 2, "page" => $currentPage, ] ); $paginate = $paginator->paginate(); ``` The example above uses an array as the source, and limits the results to 2 records at a time. It will return elements with id `3` and `4` because the `page` has been set to `2`. ## Adapters For the source of the data, the component uses adapters. It comes with the following adapters: | Adapter | Description | |---------------------------------------------------------------------------|-------------------------------------------------------------------------------------| | [Phalcon\Paginator\Adapter\Model][paginator-adapter-model] | Use a [Phalcon\Mvc\Model\Resultset][mvc-model-resultset] object as source data. | | [Phalcon\Paginator\Adapter\NativeArray][paginator-adapter-nativearray] | Use a PHP array as source data | | [Phalcon\Paginator\Adapter\QueryBuilder][paginator-adapter-querybuilder] | Use a [Phalcon\Mvc\Model\Query\Builder][mvc-model-query-builder] object as source data | !!! warning "NOTE" Since PDO does not support scrollable cursors, [Phalcon\Paginator\Adapter\Model][paginator-adapter-model] should not be used to paginate a large number of records ### Methods Every adapter requires options to operate properly. These options are passed as a key/value array in the constructor of the adapter. - `builder` - Used only for the [Phalcon\Paginator\Adapter\QueryBuilder][paginator-adapter-querybuilder] to pass the builder object - `data` - The data to paginate. ([Phalcon\Paginator\Adapter\NativeArray][paginator-adapter-nativearray] adapter) - `limit` - `int` - The size of the page slice. If `limit` is negative, an exception will be thrown. - `model` - The data to paginate. ([Phalcon\Paginator\Adapter\Model][paginator-adapter-model] adapter) - `page` - `int` - The current page - `repository` - [Phalcon\Paginator\RepositoryInterface][paginator-repositoryinterface] - A repository object setting up the resultset. For more about repositories see below. The methods exposed are: - `getLimit()` - `int` - Get current rows limit - `getRepository(array $properties = null)` - `RepositoryInterface` - Gets current repository for pagination - `setCurrentPage(int $page)` - `AdapterInterface` - Set the current page number - `setLimit(int $limitRows)` - `AdapterInterface` - Set current rows limit - `setRepository(RepositoryInterface $repository)` - `AdapterInterface` - Sets current repository for pagination ### Model The [Phalcon\Paginator\Adapter\Model][paginator-adapter-model] adapter uses a [Phalcon\Mvc\Model\Resultset][mvc-model-resultset] as the source of the data. This is the result of the `find()` method on a model.<?php
use MyApp\Models\Invoices;
use Phalcon\Paginator\Adapter\Model;
$currentPage = 2;
$paginator = new Model(
[
"model" => Invoices::class,
"parameters" => [
"inv_cst_id = :cst_id:",
"bind" => [
"cst_id" => 1
],
"order" => "inv_title"
],
"limit" => 25,
"page" => $currentPage,
]
);
$paginate = $paginator->paginate();
<?php
use Phalcon\Paginator\Adapter\NativeArray;
$currentPage = 2;
$paginator = new NativeArray(
[
"data" => [
["id" => 1, "name" => "Artichoke"],
["id" => 2, "name" => "Carrots"],
["id" => 3, "name" => "Beet"],
["id" => 4, "name" => "Lettuce"],
["id" => 5, "name" => ""],
],
"limit" => 2,
"page" => $currentPage,
]
);
$paginate = $paginator->paginate();
<?php
use MyApp\Models\Invoices;
use Phalcon\Paginator\Adapter\QueryBuilder;
$builder = $this
->modelsManager
->createBuilder()
->columns("inv_id, inv_title")
->from(Invoices::class)
->orderBy("inv_title");
$paginator = new QueryBuilder(
[
"builder" => $builder,
"limit" => 20,
"page" => 1,
]
);
$paginate = $paginator->paginate();
<?php
use Phalcon\Paginator\Adapter\NativeArray;
$currentPage = 2;
$paginator = new NativeArray(
[
"data" => [
["id" => 1, "name" => "Artichoke"],
["id" => 2, "name" => "Carrots"],
["id" => 3, "name" => "Beet"],
["id" => 4, "name" => "Lettuce"],
["id" => 5, "name" => ""],
],
"limit" => 2,
"page" => $currentPage,
]
);
$paginate = $paginator->paginate();
echo $paginate->getCurrent(); // 2
echo $paginate->current ; // 2
echo $paginate->getFirst(); // 1
echo $paginate->first; // 1
var_dump($paginate->getItems());
// [
// [
// 'id' => 3
// 'name' => "Beet",
// ],
// [
// 'id' => 4,
// 'name' => "Lettuce",
// ]
// ]
var_dump($paginate->getItems());
echo $paginate->getLast(); // 3
echo $paginate->last; // 3
echo $paginate->getLimit(); // 2
echo $paginate->limit; // 2
echo $paginate->getNext(); // 3
echo $paginate->next; // 3
echo $paginate->getPrevious(); // 1
echo $paginate->previous; // 1
echo $paginate->getTotalItems(); // 5
echo $paginate->total_items; // 5
<?php
use Phalcon\Paginator\Repository;
use Phalcon\Paginator\Adapter\NativeArray;
$repository = = new Repository();
$repository->setAliases(
[
'myCurrentPage' => $repository::PROPERTY_CURRENT_PAGE,
'myFirstPage' => $repository::PROPERTY_FIRST_PAGE,
'myLastPage' => $repository::PROPERTY_LAST_PAGE,
'myLimit' => $repository::PROPERTY_LIMIT,
'myNextPage' => $repository::PROPERTY_NEXT_PAGE,
'myTotalItems' => $repository::PROPERTY_TOTAL_ITEMS,
]
);
$currentPage = 2;
$paginator = new NativeArray(
[
"data" => [
["id" => 1, "name" => "Artichoke"],
["id" => 2, "name" => "Carrots"],
["id" => 3, "name" => "Beet"],
["id" => 4, "name" => "Lettuce"],
["id" => 5, "name" => ""],
],
"limit" => 2,
"page" => $currentPage,
'repository' => $repository,
]
);
$paginate = $paginator->paginate();
echo $paginate->myCurrentPage; // 2
echo $paginate->myFirstPage; // 1
echo $paginate->myLastPage; // 3
echo $paginate->myLimit; // 2
echo $paginate->myNextPage; // 3
echo $paginate->myTotalItems; // 1
<?php
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$builder = $this
->modelsManager
->createBuilder()
->columns('inv_id, inv_title')
->from(Invoices::class)
->orderBy('name')
;
$options = [
'builder' => $builder,
'limit' => 20,
'page' => 1,
];
$factory = new PaginatorFactory();
$paginator = $factory->newInstance('queryBuilder');
<?php
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$builder = $this
->modelsManager
->createBuilder()
->columns('inv_id, inv_title')
->from(Invoices::class)
->orderBy('inv_title')
;
$options = [
'builder' => $builder,
'limit' => 20,
'page' => 1,
'adapter' => 'queryBuilder',
];
$paginator = (new PaginatorFactory())->load($options);
<?php
use Phalcon\Paginator\Adapter\NativeArray;
use Phalcon\Paginator\Exception;
try {
$currentPage = 2;
$paginator = new NativeArray(
[
"data" => [
["id" => 1, "name" => "Artichoke"],
["id" => 2, "name" => "Carrots"],
["id" => 3, "name" => "Beet"],
["id" => 4, "name" => "Lettuce"],
["id" => 5, "name" => ""],
],
"limit" => -5,
"page" => $currentPage,
]
);
$paginate = $paginator->paginate();
} catch (Exception $ex) {
echo $ex->getMessage();
}
<?php
use MyApp\Models\Invoices;
use Phalcon\Http\Request;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;
use Phalcon\Paginator\Adapter\Model as PaginatorModel;
/**
* @property Request $request
* @property View $view
*/
class InvoicesController extends Controller
{
public function listAction()
{
$currentPage = $this->request->getQuery('page', 'int', 1);
$paginator = new PaginatorModel(
[
'model' => Invoices::class,
'limit' => 10,
'page' => $currentPage,
]
);
$page = $paginator->paginate();
$this->view->setVar('page', $page);
}
}
<table>
<tr>
<th>Id</th>
<th>Status</th>
<th>Title</th>
</tr>
<?php foreach ($page->getItems() as $item) { ?>
<tr>
<td><?php echo $item['inv_id']; ?></td>
<td><?php echo ($item['inv_status_flag']) ? 'Paid' : ''; ?></td>
<td><?php echo $item['inv_title']; ?></td>
</tr>
<?php } ?>
</table>
<a href="/invoices/list">First</a>
<a href="/invoices/list?page=<?= $page->getPrevious(); ?>">Previous</a>
<a href="/invoices/list?page=<?= $page->getNext(); ?>">Next</a>
<a href="/invoices/list?page=<?= $page->getLast(); ?>">Last</a>
<?php echo "Page {$page->getCurrent()} of {$page->getLast()}"; ?>
<?php
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$factory = new PaginatorFactory();
$currentPage = 2;
$options = [
'model' => Invoices::class,
'limit' => 10,
'page' => $currentPage,
];
$paginator = $factory->newInstance('model', $options);
<?php
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$factory = new PaginatorFactory();
$currentPage = 2;
$options = [
'data' => [
['id' => 1, 'name' => 'Artichoke'],
['id' => 2, 'name' => 'Carrots'],
['id' => 3, 'name' => 'Beet'],
['id' => 4, 'name' => 'Lettuce'],
['id' => 5, 'name' => ''],
],
'limit' => 2,
'page' => $currentPage,
];
$paginator = $factory->newInstance('nativeArray', $options);
<?php
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$factory = new PaginatorFactory();
$currentPage = 2;
$builder = $this
->modelsManager
->createBuilder()
->columns('id, name')
->from('Robots')
->orderBy('name');
$options = [
'builder' => $builder,
'limit' => 20,
'page' => $currentPage,
];
$paginator = $factory->newInstance('queryBuilder', $options);
<?php
use Phalcon\Paginator\Adapter\Model as PaginatorModel;
$currentPage = 2;
$paginator = new PaginatorModel(
[
'model' => Invoices::class,
'limit' => 10,
'page' => $currentPage,
]
);
<?php
use Phalcon\Paginator\Adapter\NativeArray as PaginatorArray;
$currentPage = 2;
$paginator = new PaginatorArray(
[
'data' => [
['id' => 1, 'name' => 'Artichoke'],
['id' => 2, 'name' => 'Carrots'],
['id' => 3, 'name' => 'Beet'],
['id' => 4, 'name' => 'Lettuce'],
['id' => 5, 'name' => ''],
],
'limit' => 2,
'page' => $currentPage,
]
);
<?php
use MyApp\Models\Invoices;
use Phalcon\Paginator\Adapter\QueryBuilder as PaginatorQueryBuilder;
$currentPage = 2;
$builder = $this
->modelsManager
->createBuilder()
->columns('id, name')
->from('Robots')
->orderBy('name');
$paginator = new PaginatorQueryBuilder(
[
'builder' => $builder,
'limit' => 20,
'page' => $currentPage,
]
);
<?php
use Phalcon\Paginator\AdapterInterface as PaginatorInterface;
use Phalcon\Paginator\RepositoryInterface;
class MyPaginator implements PaginatorInterface
{
/**
* Get current rows limit
*/
public function getLimit(): int;
/**
* Returns a slice of the resultset to show in the pagination
*/
public function paginate(): RepositoryInterface;
/**
* Set the current page number
*/
public function setCurrentPage(int $page);
/**
* Set current rows limit
*/
public function setLimit(int $limit);
}