Pagination
Implementing pagination
The Paginator
trait
To implement pagination, you will probably need to use the paginator trait. It allows you to quickly deploy a paginable menu.
Note: The Rejoice
framework handles two types of pagination. The first one that we call soft-pagination
is when all the data is retrieved and passed to the framework. It works fine when the data to paginate is small. The second type of pagination called the hard-pagination
is the one that requires the use of the first one is when a menu overflows
The paginator required methods
PaginationFetch
Retrieve the data from the database. Must return the retrieved data.
PaginationCountAll
Must Return the total of rows fetched from the database.
itemAction
When using the paginator trait, instead of the actions
methods, you will use the itemAction
method to specify how to insert the actions in your menu. This method will be used under the hood by the actions method to insert the actions automatically for you. Example
namespace App\Menus;
use Prinx\Rejoice\Menu\Paginator;
class BetsHistory extends Menu
{
use Paginator;
/**
* Number of items to display per page
*/
protected $maxItemsPerPage = 4;
public function message()
{
if (!$this->paginationTotal()) {
return "You don't have any bet.";
} else {
return $this->isPaginationFirstPage() ? 'Your betting history' : '';
}
}
/**
* Defines how the items will be displayed to the user.
*
* This method will automatically be called for each rows of the array
* returned by `paginationFetch`. And its return value will be added to the
* actions
*
* The option is what will be displayed to the user as option to select.
* It's automatically handled by the Paginator
*
* @param array $row
* @param string $option
* @return array
*/
public function itemAction($row, $option)
{
return [
$option => [
'message' => 'Bet ' . $row['id'],
'next_menu' => 'bet::bet_details',
'save_as' => $row['id'],
],
];
}
/**
* Fetches the items from the database
*
* @return array
*/
public function paginationFetch()
{
if (isset($this->bets)) {
return $this->bets;
}
$req = $this->db()->prepare("SELECT * FROM bets
WHERE id > :offset
AND initiator_id = :initiator_id
ORDER BY id
LIMIT :limit");
$offset = $this->lastRetrievedId();
$userId = $this->user('id');
$limit = $this->maxItemsPerPage();
$req->bindParam('offset', $offset, \PDO::PARAM_INT);
$req->bindParam('initiator_id', $userId);
$req->bindParam('limit', $limit, \PDO::PARAM_INT);
$req->execute();
$this->bets = $req->fetchAll(\PDO::FETCH_ASSOC);
$req->closeCursor();
return $this->bets;
}
/**
* Returns the total number of the data to be displayed
*
* @return int
*/
public function paginationCountAll()
{
if ($total = $this->paginationGet('total')) {
return $total;
}
$req = $this->db()->prepare("SELECT COUNT(*) FROM bets WHERE initiator_id = ?");
$req->execute([
$this->user('id')
]);
$paginationTotal = intval($req->fetchColumn());
$req->closeCursor();
$this->paginationSave('total', $paginationTotal);
return $paginationTotal;
}
}
The paginator makes available some methods for our use:
maxItemsPerPage
The maximum number of items that can be showed on the pagination screen; It’s configured as protected property of the menu entity;currentItemsCount
The actual number of items showed on the current screen;isPaginationFirstPage
Check if the current screen is the first screen of the pagination;isPaginationLastPage
Check if the current screen is the last screen of the pagination;lastRetrievedId
Get the id of the last fetched row - the next query to the database to fetch, will begin at that index;paginationSave
Saves a data for pagination purpose;paginationGet
Get a pagination data;paginationHas
Check if a pagination data exists;