Reputation: 357
I'm using CakePHP 3.2.7. In my controller, I'm paginating a table as follows:
class CollectionsController extends AppController
{
public function index()
{
$page_number = 1;
$page_size = 10;
if($this->request->query('page') !== null){
if(array_key_exists('number', $this->request->query('page'))){
$page_number = $this->request->query['page']['number'];
}
if(array_key_exists('size', $this->request->query('page'))){
$page_size = $this->request->query['page']['size'];
}
}
$this->paginate = [
'limit' => $page_size,
'page' => $page_number,
//'order' => ['Collections.id' => 'desc']
];
$collections = $this->paginate($this->Collections->find('all'));
$this->set(compact('collections'));
$this->set('_serialize', true);
}
}
The paginate options limit
and order
do work. However, the page
and offset
(not shown) options seem to be ignored. When printing the contents of $this->request->params['paging']
(when requesting page 2 with size/limit of 2 of a table with 3 rows, query like http://localhost:8765/api/collections?page[number]=2&page[size]=2
), I get:
"finder": "all",
"page": 1,
"current": 2,
"count": 3,
"perPage": 2,
"prevPage": false,
"nextPage": true,
"pageCount": 2,
"sort": null,
"direction": false,
"limit": null,
"sortDefault": false,
"directionDefault": false
The perPage
option has the value of 2 (which I expect) BUT page
has a value of 1 (when it should be 2). Why is the page
option being ignored while other pagination options are working?
Upvotes: 0
Views: 1072
Reputation: 357
I figured out that this had to do with the way I was structuring my url which was conflicting with the default behavior of pagination in CakePHP.
CakePHP automatically processes the page
query string. While setting 'page' => $page_number,
for paginate options is valid and works, if there is a page
query string, it has priority over the paginate option.
In my case, I was following the JSON API example for the pagination url structure. This looks like ?page[number]=3&page[size]=1
. Since the query string page
was present, it was overriding the paginate option I was setting. However, the value of page
in this case was an associative array and not a number as the Paginator component expects. Therefore, the component uses its default value of 1.
This could be resolved by:
Using the default query string as intended (e.g. ?page=2&size=2
) (as mentioned by @Jsonras).
Using a different query string that doesn't conflict with page
(e.g. ?paging[number]=3&paging[size]=1
) and setting the page
option as in the question.
Keeping the same structure (?page[number]=3&page[size]=1
) and overwriting the value of page
query string after parsing the values. In this case, this code in the question,
$this->paginate = [ 'limit' => $page_size, 'page' => $page_number, ];
would change to:
$this->request->query['page'] = $page_number;
$this->paginate = [
'limit' => $page_size,
];
Upvotes: 1
Reputation: 1160
There is not page option for $this->paginate
This is automatically done for you. All you have to do is pass page number.
See this: http://book.cakephp.org/3.0/en/controllers/components/pagination.html
Cake can also generate the pagination links for you. See here: http://book.cakephp.org/3.0/en/views/helpers/paginator.html
If you're trying to build an API, this is the best way to do it using the CURD Plugin: http://www.bravo-kernel.com/2015/04/how-to-build-a-cakephp-3-rest-api-in-minutes/
Upvotes: 0