From 300b0306e52ca8c7ca311c68ef7ffb0436fa4465 Mon Sep 17 00:00:00 2001 From: Miroslav Vitanov Date: Tue, 11 Oct 2016 15:30:14 +0300 Subject: [PATCH] Handle ListView sorting --- README.md | 14 ++++++++++++++ src/Filter.php | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/README.md b/README.md index 9eac725..c31c6df 100644 --- a/README.md +++ b/README.md @@ -60,4 +60,18 @@ class LessonsController extends Controller return Lesson::filter($filters)->get(); } } +``` + +# [ListView](https://github.com/administrcms/listview) sorting + +By default the base Filter class will handle the sorting for your main table. If you have a ListView that uses a column which is a relationship to the model, you'll have to handle that column for yourself. Let's imagine that you have User model and it has a relationship to UserType (one User has one UserType). So in your ListView you want to sort by the column that shows the name of the UserType. We'll assume that the column in the ListView is defined as `type.name`. In that case you need to define the custom sort like this: + +```php +public function sortTypeName($dir) +{ + return $this + ->builder + ->join('user_types', 'user_types.id', '=', 'users.type_id') + ->orderBy('user_types.id', $dir); +} ``` \ No newline at end of file diff --git a/src/Filter.php b/src/Filter.php index 9595614..399e50b 100644 --- a/src/Filter.php +++ b/src/Filter.php @@ -51,4 +51,38 @@ public function apply(Builder $builder) return $this->builder; } + + /** + * Handle sorting of ListView module. If the field being sorted + * is not in the main table, you have to define a sort method + * which follows the convention sortFieldName, so if the + * column is type.name it will be sortTypeName and it + * will accept the sort direction as parameter + * which will be equeal to 'asc' or 'desc'. + * + * @param array $sort + * @return Builder + */ + public function sort(array $sort) + { + $tableName = $this->builder->getModel()->getTable(); + + foreach($sort as $field => $dir) + { + $builder = $this->builder; + + // Convert to method for sorting - sortId, sortName, sortFirstName ... + $method = 'sort' . studly_case(str_replace('.', '_', $field)); + + // If it is not a method, then try to do the orderBy query for the field + if(! method_exists($this, $method)) { + $builder = $builder->orderBy("{$tableName}.{$field}", $dir); + continue; + } + + $builder = call_user_func([$this, $method], $dir); + } + + return $builder; + } } \ No newline at end of file