Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I set the default order on the Table class on cakephp3

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?

like image 947
gmponos Avatar asked Sep 22 '15 09:09

gmponos


5 Answers

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.

like image 181
monsur.hoq Avatar answered Nov 10 '22 01:11

monsur.hoq


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',
    ],
]);
like image 38
floriank Avatar answered Nov 10 '22 01:11

floriank


You can override findAll method in your table class.

public function findAll(Query $query, array $options)
{
    return $query->order(['Country.country' => 'DESC']);
}
like image 4
Leonardo Ruhland Avatar answered Nov 10 '22 02:11

Leonardo Ruhland


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;

}
like image 3
Melvin Avatar answered Nov 10 '22 01:11

Melvin


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'
        ]
    ];

....
like image 2
Wile E. Genius Avatar answered Nov 10 '22 03:11

Wile E. Genius