CakePHP Version: 4.0.1
Introduction
I have 2 methods that both use the index view, index and search. On index the column can be selected from a select list and a value can be inputted via an input form control enabling a search by column and value. This data is sent via GET to the search method where empty values are checked and the query is executed and the index view is rendered.
In the later 3x versions with the below configuration the index view had the sort on the selected column which is what it is meant to do.
IE: Index view has due_date sorted on the initial load and I select task_name then submit the form to the search method. The task_name has the sort when the view is rendered.
TASKS CONTROLLER
Public pagination property:
public $paginate = [
'sortWhitelist' => [
'Tasks.due_date',
'Tasks.task_name',
'Tasks.type',
'Tasks.priority',
'Tasks.related_to_name',
'Contacts.first_name',
'Contacts.last_name',
'Accounts.account_name',
'Tasks.task_desc'
]
];
Search Method
I initialise the data received from the index method and apply the config to the pagination property and send the query object to the view.
$this->setPage('');
$this->setSort($this->request->getQuery('column'));
$this->setDirection('asc');
// Validation of the page, sort, direction and limit is done here.
// IE: The $this->getSort() must be a string and not be numeric and has a strlen check
// and the $this->getDirection() can only be a string with values 'asc' or 'desc' etc.
if (!empty($this->getPage())) {
$this->paginate['page'] = $this->getPage();
}
$this->paginate['sort'] = $this->getSort();
$this->paginate['direction'] = $this->getDirection();
$this->paginate['limit'] = $this->getLimit();
debug($this->paginate);
$tasks = $this->paginate($query);
$this->set(compact('tasks'));
The result of debug is:
[
'sortWhitelist' => [
(int) 0 => 'Tasks.due_date',
(int) 1 => 'Tasks.task_name',
(int) 2 => 'Tasks.type',
(int) 3 => 'Tasks.priority',
(int) 4 => 'Tasks.related_to_name',
(int) 5 => 'Contacts.first_name',
(int) 6 => 'Contacts.last_name',
(int) 7 => 'Accounts.account_name',
(int) 8 => 'Tasks.task_desc'
],
'sort' => 'Tasks.task_name',
'direction' => 'asc',
'limit' => (int) 25
]
Result
The sort is on the task_name.
A couple of months ago I upgraded to 4 and have just revisted this functionality to find the sort is on the column that was present on index and not the column that was selected. I tried the below to fix the problem:
I referenced this information in the cookbook. And this from SO.
$config = $this->paginate = [
'page' => $this->getPage(),
'sort' => $this->getSort(),
'direction' => $this->getDirection(),
'limit' => $this->getLimit()
];
debug($config);
$tasks = $this->Paginator->paginate($query, $config);
debug($this->Paginator);
$this->set(compact('tasks'));
The result of debug $config is:
[
'page' => '',
'sort' => 'Tasks.task_name',
'direction' => 'asc',
'limit' => (int) 25
]
The result of debug $this->Paginator is:
object(Cake\Controller\Component\PaginatorComponent) {
'components' => [],
'implementedEvents' => [],
'_config' => [
'page' => (int) 1,
'limit' => (int) 20,
'maxLimit' => (int) 100,
'whitelist' => [
(int) 0 => 'limit',
(int) 1 => 'sort',
(int) 2 => 'page',
(int) 3 => 'direction'
]
]
}
NOTE: The whitelist contains limit, sort, page and direction? And the limit is 20 and I don't even have a selection of 20?
Result
The sort is on the due_date and I need it on the task_name.
Extra Info
If I then click the sort on task_name the sort is on the task_name. All the sorts work just not on the initial load?
Question
How can I configure the pagination property so the sort is on the task_name from the initial load of the search method.
Thanks Z.
limit
/sort
/page
/direction
by default (after merging user request data and paginator config). That being said, specifying the default sorting in the pagination config works fine for me, the helper correctly "highlights" (adds the small arrow icon) as expected. You might need to boil this down to a more general, reproducible example. - ndm