CakePHP 3.7.7
I'm using the Paginator (https://book.cakephp.org/3.0/en/views/helpers/paginator.html) to display pagination for a query that has 972 rows.
In my Controller method I am loading the Paginator component and using a custom finder called findFilters()
to return the data that I want paginated.
public function initialize()
{
parent::initialize();
$this->loadComponent('Paginator');
}
public $paginate = [
'finder' => 'filters', // uses custom finder, findFilters() in src/Model/Table/FiltersTable.php
];
/*
* Called via ajax. Renders the data and pagination to a template.
*/
public function getFilters()
{
$this->viewBuilder()->setLayout('ajax');
$this->loadModel('Filters');
$rf_keywords = '';
$rf_keywords = trim($this->request->getData('rf_keywords'));
// Pagination settings (relevant to the question).
$page = $this->request->getData('page') ? (int)$this->request->getData('page') : 1;
$this->paginate = ['limit' => 200, 'page' => $page];
$finder = $this
->Filters
->find('filters' , [
'rf_keywords' => $rf_keywords
]);
$data = $this
->paginate($finder)
->toArray();
$this->set('data', $data);
}
In my template (get_filters.ctp
) I have the following to output the pagination numbers (links to be clicked to go between pages) and the total counts:
<?= $this->Paginator->numbers(); ?>
<?= $this->Paginator->counter([
'format' => 'Page {{page}} of {{pages}}, showing {{current}} records out of
{{count}} total, starting on record {{start}}, ending on {{end}}'
]) ?>
The problem is that changing the limit
in the Controller...
$this->paginate = ['limit' => 200];
... is not updating the output of the Pagination correctly. See examples below:
'limit' => 20
:
Shows page numbers 1 - 9 and:
Page 1 of 49, showing 20 records out of 972 total, starting on record 1, ending on 20
'limit' => 100
:
Shows page numbers 1 - 9 and:
Page 1 of 10, showing 100 records out of 972 total, starting on record 1, ending on 100
'limit' => 500
:
Shows page numbers 1 - 9 and:
Page 1 of 10, showing 100 records out of 972 total, starting on record 1, ending on 100
'limit' => 1000
(more than there are rows in the DB!):
Shows page numbers 1 - 9 and:
Page 1 of 10, showing 100 records out of 972 total, starting on record 1, ending on 100
So there are 2 problems:
It doesn't work with any
limit
value >100. Nothing changes in terms of the pagination output in the template. The behaviour is as though it is ignoring anything supplied as the limit and defaulting to 100.The page number links (
$this->Paginator->numbers();
) are always 1 - 9 when thelimit
is >100. That is to say they stay the same irrespective of whether I use a limit of 100, 200, 500, 1000. I'm guessing this is due to problem (1) where it seems to ignore the actual limit set if it's >100.
I thought this was some caching issue. The ajax requests to getFilters()
are being made via jquery so I have set cache: false
on them to ensure each request appends a timestamp to the URL to ensure it's not using some old cached response.
I have cleared the files in tmp/cache/models/*
I've a force refresh in the browser. Tried an incognito/private browsing window to make sure it's not some session issue.
None of these things solve the problem.
The issue is also consistent if the page
part of Pagination is altered. For example using page => 3
will give the correct rows from the database for page 3. But the Pagination HTML will still be exactly the same as where the problem occurs.
Why isn't this working?
Edit - the custom Finder returns the correct data so I don't think this is an issue. The signature is below and it returns a Query object which is executed via Pagination:
// src/Model/Table/FiltersTable.php
public function findFilters(Query $query, array $options)
{
// $query->find() ...
// ...
return $query;
}