├── .gitignore ├── README.md ├── composer.json ├── docs └── license.md └── src └── SortRelations.php /.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | /.idea 3 | /vendor 4 | /node_modules 5 | package-lock.json 6 | composer.phar 7 | composer.lock 8 | phpunit.xml 9 | .phpunit.result.cache 10 | .DS_Store 11 | Thumbs.db -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## LifeOnScreen/nova-sort-relations 2 | 3 | This package improves support for sorting relations in Laravel Nova. 4 | 5 | ## Installation 6 | 7 | Install via composer 8 | 9 | ``` bash 10 | $ composer require lifeonscreen/nova-sort-relations 11 | ``` 12 | 13 | ## Usage 14 | 15 | Include `LifeOnScreen\SortRelations\SortRelations` trait to your class. Define base by overriding `indexQuery`. 16 | Define sortable columns in `$sortRelations` array. 17 | 18 | ```php 19 | 20 | ... 21 | use LifeOnScreen\SortRelations\SortRelations; 22 | ... 23 | 24 | class Product extends Resource 25 | { 26 | public static $sortRelations = [ 27 | // overriding id with product.id (this prevent ambiguous id, if you select multiple ids) 28 | 'id' => 'product.id', 29 | // overriding user relation sorting 30 | 'user' => [ 31 | // sorting multiple columns 32 | 'users.name', 33 | 'users.surname', 34 | ], 35 | // overriding company relation sorting 36 | 'company' => 'company.name', 37 | ]; 38 | 39 | public static function indexQuery(NovaRequest $request, $query) 40 | { 41 | // You can modify your base query here. 42 | return $query; 43 | } 44 | } 45 | 46 | ``` 47 | 48 | 49 | ## Security 50 | 51 | If you discover any security-related issues, please email the author instead of using the issue tracker. 52 | 53 | ## Credits 54 | - [Jani Cerar](https://github.com/janicerar) 55 | 56 | ## License 57 | 58 | MIT license. Please see the [license file](docs/license.md) for more information. 59 | 60 | [ico-version]: https://img.shields.io/packagist/v/lifeonscreen/nova-sort-relations.svg?style=flat-square 61 | [ico-downloads]: https://img.shields.io/packagist/dt/lifeonscreen/nova-sort-relations.svg?style=flat-square 62 | 63 | [link-packagist]: https://packagist.org/packages/lifeonscreen/nova-sort-relations 64 | [link-downloads]: https://packagist.org/packages/lifeonscreen/nova-sort-relations 65 | [link-author]: https://github.com/LifeOnScreen -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lifeonscreen/nova-sort-relations", 3 | "description": "This package improves support for sorting relations in Laravel Nova.", 4 | "keywords": [ 5 | "laravel", 6 | "nova", 7 | "sort", 8 | "relations" 9 | ], 10 | "authors": [ 11 | { 12 | "name": "Jani Cerar", 13 | "email": "jani.cerar@lifeonscreen.com" 14 | } 15 | ], 16 | "license": "MIT", 17 | "require": { 18 | "php": ">=7.1.0" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "LifeOnScreen\\SortRelations\\": "src/" 23 | } 24 | }, 25 | "config": { 26 | "sort-packages": true 27 | }, 28 | "minimum-stability": "dev", 29 | "prefer-stable": true 30 | } -------------------------------------------------------------------------------- /docs/license.md: -------------------------------------------------------------------------------- 1 | # The license 2 | 3 | Copyright 2018 LifeOnScreen Global Limited and other contributors, 4 | https://lifeonscreen.com 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/SortRelations.php: -------------------------------------------------------------------------------- 1 | getModel(); 34 | $relation = $column; 35 | $related = $model->{$column}()->getRelated(); 36 | 37 | $foreignKey = Str::snake($relation) . '_' . $related->getKeyName(); 38 | 39 | $query->select($model->getTable() . '.*'); 40 | $query->join($related->getTable(), $model->qualifyColumn($foreignKey), '=', $related->qualifyColumn($related->getKeyName())); 41 | if (is_string($sortRelations[$column])) { 42 | $qualified = $related->qualifyColumn($sortRelations[$column]); 43 | $query->orderBy($qualified, $direction); 44 | } 45 | if (is_array($sortRelations[$column])) { 46 | foreach ($sortRelations[$column] as $orderColumn) { 47 | $query->orderBy($related->qualifyColumn($orderColumn), $direction); 48 | } 49 | } 50 | 51 | return $query; 52 | } 53 | 54 | /** 55 | * Apply any applicable orderings to the query. 56 | * 57 | * @param \Illuminate\Database\Eloquent\Builder $query 58 | * @param array $orderings 59 | * @return \Illuminate\Database\Eloquent\Builder 60 | */ 61 | protected static function applyOrderings($query, array $orderings) 62 | { 63 | if (empty($orderings)) { 64 | return empty($query->orders) 65 | ? $query->latest($query->getModel()->getQualifiedKeyName()) 66 | : $query; 67 | } 68 | 69 | $sortRelations = static::sortableRelations(); 70 | 71 | foreach ($orderings as $column => $direction) { 72 | if (array_key_exists($column, $sortRelations)) { 73 | $query = self::applyRelationOrderings($column, $direction, $query); 74 | } else { 75 | $query->orderBy($column, $direction); 76 | } 77 | } 78 | 79 | return $query; 80 | } 81 | } 82 | --------------------------------------------------------------------------------