In CakePHP 2.x there was a property $order
in Models. So I used this property to order my data globally. So for example assuming that I need to show a select box with countries on a view in my Country
model used to add the line:
$order = 'Country.country DESC';
and then when I fetched the countries from any controller the data where ordered by the country name and not by the id
or any other field. This was very helpful specially for the select boxes. On CakePHP 3.x I can't seem to find any similar reference at the documentation.
Is there anything that I can do to have my data sorted globally when I fetch them and not use the order option in each find?
In CakePHP 3.x, if you want so set default order for every query of a model, then you can place following code in your table:
public function beforeFind ($event, $query, $options, $primary)
{
$order = $query->clause('order');
if ($order === null || !count($order)) {
$query->order( [$this->alias() . '.sort_field_name' => 'sort_order'] );
}
}
If any order
set from outside, it skip the default order. Otherwise, it will always sort by sort_field_name
according sort_order
.
Just add your beloved property back and use the beforeFind() callback in the Table object to add the value from the property to the query.
Or just create a custom finder:
public function findOrdered(Query $query, $options) {
return $query->order([
$this->alias() . '.name' => 'ASC'
]);
}
And use it
$this->find('list')->find('ordered')->all();
Or create an ordered list find that returns the whole ordered list.
public function findOrderedList(Query $query, $options) {
return $this->findList($query, $options)
->order([
$this->alias() . '.name' => 'ASC'
]);
}
Or overload the findList() method directly and call the parent.
Or if your find()
gets called via a relationship, you can set the default order for the relationship by using the sort
option.
$this->hasMany('AuditLogs', [
'sort' => [
'AuditLogs.timestamp' => 'desc',
],
]);
You can override findAll method in your table class.
public function findAll(Query $query, array $options)
{
return $query->order(['Country.country' => 'DESC']);
}
CakePHP3.x:
If you would like to sort the data in your model for every query related to this model, you can simple order the query in the model file via beforeFind:
public function beforeFind(Event $event, Query $query, $options, $primary) {
$query->order(['Model.field' => 'ASC']);
return $query;
}
According to the official docs, see cakephp book, you can add a public variable to the controller object in order to set the default sort order:
class InvoicesController extends AppController
{
public $paginate = [
'order' => [
'Invoices.id' => 'desc'
]
];
....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With