diff --git a/README.md b/README.md
index 93e0eb9..21f5656 100755
--- a/README.md
+++ b/README.md
@@ -1,385 +1,5 @@
-
-
+# Column sorting for Laravel 5.5-8 and above
+# This repository is a fork of the Laravel Column Sorter originally created by https://github.com/Kyslik/column-sortable.
+I have modified the code so now it works for up to 4 levels of nesting such as ->sortable(['relation1.subrelation2.subrelation3.subrelation4.columnName' => 'desc'])
-
-- [Column sorting for Laravel 5.5-8](#column-sorting-for-laravel-55-8)
-- [Setup](#setup)
- - [Composer](#composer)
- - [Laravel's >=5.5 auto discovery](#laravels-55-auto-discovery)
- - [Manual installation (pre 5.5)](#manual-installation-pre-55)
- - [Publish configuration](#publish-configuration)
-- [Usage](#usage)
- - [Blade Extension](#blade-extension)
- - [Configuration in few words](#configuration-in-few-words)
- - [Font Awesome (default font classes)](#font-awesome-default-font-classes)
- - [Font Awesome 5](#font-awesome-5)
- - [Full Example](#full-example)
- - [Routes](#routes)
- - [Controller's `index()` method](#controllers-index-method)
- - [View (_pagination included_)](#view-pagination-included)
-- [HasOne / BelongsTo Relation sorting](#hasone--belongsto-relation-sorting)
- - [Define hasOne relation](#define-hasone-relation)
- - [Define belongsTo relation](#define-belongsto-relation)
- - [Define `$sortable` arrays](#define-sortable-arrays)
- - [Blade and relation sorting](#blade-and-relation-sorting)
-- [ColumnSortable overriding (advanced)](#columnsortable-overriding-advanced)
-- [Aliasing](#aliasing)
- - [Using `withCount()`](#using-withcount)
-- [Exception to catch](#exception-to-catch)
-
-
-
-# Column sorting for Laravel 5.5-8
-
-[![Latest Version](https://img.shields.io/github/release/Kyslik/column-sortable.svg?style=flat-square)](https://github.com/Kyslik/column-sortable/releases)
-[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
-[![Total Downloads](https://img.shields.io/packagist/dt/Kyslik/column-sortable.svg?style=flat-square)](https://packagist.org/packages/Kyslik/column-sortable)
-![run-tests](https://github.com/Kyslik/column-sortable/workflows/run-tests/badge.svg)
-
-Package for handling column sorting in Laravel 5.[5-8]. For earlier versions of Laravel checkout branch [L5.1-3](https://github.com/Kyslik/column-sortable/tree/L5.1-3)
-
-# Setup
-
-## Composer
-
-Pull this package in through Composer (development/latest version `dev-master`)
-
-```json
-{
- "require": {
- "kyslik/column-sortable": "^6.0"
- }
-}
-```
-
-```sh
-composer update
-```
-
-### Laravel's >=5.5 auto discovery
-
-Simply install the package and let Laravel do its magic.
-
->**Note (pre Laravel 6.0)**: : major and minor versions should match with Laravel's version, for example if you are using Laravel 5.4, column-sortable version should be `5.4.*`.
-
-### Manual installation (pre 5.5)
-
-Add the service provider to array of providers in `config/app.php`
-
-```php
-'providers' => [
-
- App\Providers\RouteServiceProvider::class,
-
- /*
- * Third Party Service Providers...
- */
- Kyslik\ColumnSortable\ColumnSortableServiceProvider::class,
-],
-```
-
-## Publish configuration
-
-Publish the package configuration file to your application.
-
-```sh
-php artisan vendor:publish --provider="Kyslik\ColumnSortable\ColumnSortableServiceProvider" --tag="config"
-```
-
-See configuration file [(`config/columnsortable.php`)](https://github.com/Kyslik/column-sortable/blob/master/src/config/columnsortable.php) yourself and make adjustments as you wish.
-
-# Usage
-
-Use **Sortable** trait inside your *Eloquent* model(s). Define `$sortable` array (see example code below).
-
->**Note**: `Scheme::hasColumn()` is run only when `$sortable` is not defined - less DB hits per request.
-
-```php
-use Kyslik\ColumnSortable\Sortable;
-
-class User extends Model implements AuthenticatableContract, CanResetPasswordContract
-{
- use Authenticatable, CanResetPassword, Sortable;
- ...
-
- public $sortable = ['id',
- 'name',
- 'email',
- 'created_at',
- 'updated_at'];
- ...
-}
-```
-
-You're set to go.
-
-**Sortable** trait adds Sortable scope to the models so you can use it with paginate.
-
-## Blade Extension
-
-There is a blade extension for you to use **@sortablelink()**
-
-```blade
-@sortablelink('column', 'Title', ['parameter' => 'smile'], ['rel' => 'nofollow'])
-```
-
-**Column** (1st) parameter is column in database, **Title** (2nd) parameter is displayed inside anchor tags, `array()` parameter (3rd) is default (GET) query strings parameter and `array()` parameter (4th) is for additional anchor-tag attributes. You can use a custom URL as 'href' attribute in the 4th parameter, and the query string will be appended to it.
-
-You can omit 2nd, 3rd and 4th parameter.
-
-Possible examples and usages of blade extension:
-
-```blade
-@sortablelink('name')
-@sortablelink('name', 'Username')
-@sortablelink('address', trans('fields.address'), ['filter' => 'active, visible'])
-@sortablelink('address', trans('fields.address'), ['filter' => 'active, visible'], ['class' => 'btn btn-block', 'rel' => 'nofollow', 'href' => route('my.custom.route')])
-```
-
-If you do not fill **Title** (2nd parameter) column name is used instead.
-
->**Note**: you can set default formatting function that is applied on **Title** (2nd parameter), by default this is set to [`ucfirst`](http://php.net/manual/en/function.ucfirst.php).
-
-## Configuration in few words
-
-**Sortablelink** blade extension distinguishes between *types* (**numeric**, **amount** and **alpha**) and applies different class for each of them.
-
-See following snippet:
-
-```php
-'columns' => [
- 'numeric' => [
- 'rows' => ['created_at', 'updated_at', 'level', 'id'],
- 'class' => 'fa fa-sort-numeric'
- ],
- 'amount' => [
- 'rows' => ['price'],
- 'class' => 'fa fa-sort-amount'
- ],
- 'alpha' => [
- 'rows' => ['name', 'description', 'email', 'slug'],
- 'class' => 'fa fa-sort-alpha',
- ],
-],
-```
-
-Rest of the [config file](https://github.com/Kyslik/column-sortable/blob/master/src/config/columnsortable.php) should be crystal clear and I advise you to skim it.
-
-## Font Awesome (default font classes)
-
-Install [Font-Awesome](https://fontawesome.com/v4.7.0/) for visual [Joy](http://pixar.wikia.com/wiki/Joy). Search "sort" in [cheatsheet](https://fontawesome.com/v4.7.0/icons/) and see used icons (12) yourself.
-
-### Font Awesome 5
-
-Change the suffix class in the [config file](https://github.com/Kyslik/column-sortable/blob/master/src/config/columnsortable.php) from `-asc`/`-desc` (FA 4) to `-up`/`-down` (FA 5) respectively.
-
- ```php
-/* this is FA 5 compatible.
-suffix class that is appended when ascending direction is applied */
-'asc_suffix' => '-up',
-
-/* suffix class that is appended when descending direction is applied */
-'desc_suffix' => '-down',
-```
-
-> **Note**: If you haven't published the config yet, follow the [instructions above](#publish-configuration).
-
-## Full Example
-
-You may be interested in [working example repository](https://github.com/Kyslik/column-sortable-example), where package usage is demonstrated.
-
-### Routes
-
-```php
-Route::get('users', ['as' => 'users.index', 'uses' => 'HomeController@index']);
-```
-
-### Controller's `index()` method
-
-```php
-public function index(User $user)
-{
- $users = $user->sortable()->paginate(10);
-
- return view('user.index')->withUsers($users);
-}
-```
-
-You can set default sorting parameters which will be applied when URL is empty.
-
->**For example**: page is loaded for first time, default direction is [configurable](https://github.com/Kyslik/column-sortable/blob/master/src/config/columnsortable.php#L103) (asc)
-
-```php
-$users = $user->sortable('name')->paginate(10);
-// produces ->orderBy('users.name', 'asc')
-
-$users = $user->sortable(['name'])->paginate(10);
-// produces ->orderBy('users.name', 'asc')
-
-$users = $user->sortable(['name' => 'desc'])->paginate(10);
-// produces ->orderBy('users.name', 'desc')
-```
-
-### View (_pagination included_)
-
-```blade
-@sortablelink('id', 'Id')
-@sortablelink('name')
-
-@foreach ($users as $user)
- {{ $user->name }}
-@endforeach
-{!! $users->appends(\Request::except('page'))->render() !!}
-```
-
->**Note**: Blade's ability to recognize directives depends on having space before directive itself `
@sortablelink('Name')`
-
-# HasOne / BelongsTo Relation sorting
-
-## Define hasOne relation
-
-In order to make relation sorting work, you have to define **hasOne()** relation in your model.
-
-```php
-/**
-* Get the user_detail record associated with the user.
-*/
-public function detail()
-{
- return $this->hasOne(App\UserDetail::class);
-}
-```
-
-## Define belongsTo relation
-
->**Note**: in case there is a self-referencing model (like comments, categories etc.); parent table will be aliased with `parent_` string, for more information see [issue #60](https://github.com/Kyslik/column-sortable/issues/60).
-
-```php
-/**
- * Get the user that owns the phone.
- */
-public function user()
-{
- return $this->belongsTo(App\User::class);
-}
-```
-
-In *User* model we define **hasOne** relation to *UserDetail* model (which holds phone number and address details).
-
-## Define `$sortable` arrays
-
-Define `$sortable` array in both models (else, package uses `Scheme::hasColumn()` which is an extra database query).
-
-for *User*
-
-```php
-public $sortable = ['id', 'name', 'email', 'created_at', 'updated_at'];
-```
-
-for *UserDetail*
-
-```php
-public $sortable = ['address', 'phone_number'];
-```
-
-## Blade and relation sorting
-
-In order to tell package to sort using relation:
-
-```blade
-@sortablelink('detail.phone_number', 'phone')
-@sortablelink('user.name', 'name')
-```
-
->**Note**: package works with relation "name" (method) that you define in model instead of table name.
-
->**WARNING**: do not use combination of two different relations at the same time, you are going to get errors that relation is not defined
-
-In config file you can set your own separator in case `.` (dot) is not what you want.
-
-```php
-'uri_relation_column_separator' => '.'
-```
-
-# ColumnSortable overriding (advanced)
-
-It is possible to override ColumnSortable relation feature, basically you can write your own join(s) / queries and apply `orderBy()` manually.
-
-See example:
-
-```php
-class User extends Model
-{
- use Sortable;
-
- public $sortable = ['name'];
- ...
-
- public function addressSortable($query, $direction)
- {
- return $query->join('user_details', 'users.id', '=', 'user_details.user_id')
- ->orderBy('address', $direction)
- ->select('users.*');
- }
- ...
-```
-
-Controller is the same `$users = $user->sortable()->paginate(10);`
-
-In view just use `@sortablelink('address')`
-
->Huge thanks to @neutralrockets and his comments on [#8](https://github.com/Kyslik/column-sortable/issues/8). Another example on how to use overriding is issue [#41](https://github.com/Kyslik/column-sortable/issues/41#issuecomment-250895909).
-
-# Aliasing
-
-It is possible to declare `$sortableAs` array and use it to alias (bypass column exists check), and ignore prefixing with table.
-
-In model
-
-```php
-...
-$sortableAs = ['nick_name'];
-...
-```
-
-In controller
-
-```php
-$users = $user->select(['name as nick_name'])->sortable(['nick_name'])->paginate(10);
-```
-
-In view
-
-```blade
-@sortablelink('nick_name', 'nick')
-```
-
-See [#44](https://github.com/Kyslik/column-sortable/issues/44) for more information on aliasing.
-
-## Using `withCount()`
-
-Aliasing is useful when you want to sort results with [`withCount()`](https://laravel.com/docs/5.8/eloquent-relationships#counting-related-models), see [issue #49](https://github.com/Kyslik/column-sortable/issues/49) for more information.
-
-# Exception to catch
-
-Package throws custom exception `ColumnSortableException` with three codes (0, 1, 2).
-
-Code **0** means that `explode()` fails to explode URI parameter "sort" in to two values.
-For example: `sort=detail..phone_number` - produces array with size of 3, which causes package to throw exception with code **0**.
-
-Code **1** means that `$query->getRelation()` method fails, that means when relation name is invalid (does not exists, is not declared in model).
-
-Code **2** means that provided relation through sort argument is not instance of **hasOne**.
-
-Example how to catch:
-
-```php
-...
-try {
- $users = $user->with('detail')->sortable(['detail.phone_number'])->paginate(5);
-} catch (\Kyslik\ColumnSortable\Exceptions\ColumnSortableException $e) {
- dd($e);
-}
-```
-
->**Note**: I strongly recommend to catch **ColumnSortableException** because there is a user input in question (GET parameter) and any user can modify it in such way that package throws ColumnSortableException with code `0`.
+Please raise an issue if you find any bug or want to improve. Thank you
diff --git a/composer.json b/composer.json
index 62a2aa9..c9234f2 100755
--- a/composer.json
+++ b/composer.json
@@ -1,5 +1,5 @@
{
- "name": "kyslik/column-sortable",
+ "name": "wasxxm/column-sortable",
"description": "Package for handling column sorting in Laravel 6.x",
"keywords": [
"sortable",
diff --git a/src/ColumnSortable/Sortable.php b/src/ColumnSortable/Sortable.php
index 43dcc0f..3272b0e 100755
--- a/src/ColumnSortable/Sortable.php
+++ b/src/ColumnSortable/Sortable.php
@@ -18,7 +18,7 @@ trait Sortable
/**
* @param \Illuminate\Database\Query\Builder $query
- * @param array|null $defaultParameters
+ * @param array|null $defaultParameters
*
* @return \Illuminate\Database\Query\Builder
* @throws \Kyslik\ColumnSortable\Exceptions\ColumnSortableException
@@ -33,9 +33,9 @@ public function scopeSortable($query, $defaultParameters = null)
$defaultParameters = $this->getDefaultSortable();
}
- if ( ! is_null($defaultParameters)) {
+ if (!is_null($defaultParameters)) {
$defaultSortArray = $this->formatToParameters($defaultParameters);
- if (config('columnsortable.allow_request_modification', true) && ! empty($defaultSortArray)) {
+ if (config('columnsortable.allow_request_modification', true) && !empty($defaultSortArray)) {
request()->merge($defaultSortArray);
}
@@ -55,7 +55,7 @@ private function getDefaultSortable()
{
if (config('columnsortable.default_first_column', false)) {
$sortBy = Arr::first($this->sortable);
- if ( ! is_null($sortBy)) {
+ if (!is_null($sortBy)) {
return [$sortBy => config('columnsortable.default_direction', 'asc')];
}
}
@@ -66,7 +66,7 @@ private function getDefaultSortable()
/**
* @param \Illuminate\Database\Query\Builder $query
- * @param array $sortParameters
+ * @param array $sortParameters
*
* @return \Illuminate\Database\Query\Builder
*
@@ -75,6 +75,7 @@ private function getDefaultSortable()
private function queryOrderBuilder($query, array $sortParameters)
{
$model = $this;
+ $subModel = false;
list($column, $direction) = $this->parseParameters($sortParameters);
@@ -83,31 +84,89 @@ private function queryOrderBuilder($query, array $sortParameters)
}
$explodeResult = SortableLink::explodeSortParameter($column);
- if ( ! empty($explodeResult)) {
- $relationName = $explodeResult[0];
- $column = $explodeResult[1];
-
- try {
- $relation = $query->getRelation($relationName);
- $query = $this->queryJoinBuilder($query, $relation);
- } catch (BadMethodCallException $e) {
- throw new ColumnSortableException($relationName, 1, $e);
- } catch (\Exception $e) {
- throw new ColumnSortableException($relationName, 2, $e);
+ if (!empty($explodeResult) && count($explodeResult) >= 2) {
+ if (count($explodeResult) == 5) {
+ $relationName = $explodeResult[0];
+ $sub1RelationName = $explodeResult[1];
+ $sub2RelationName = $explodeResult[2];
+ $sub3RelationName = $explodeResult[3];
+ $column = $explodeResult[4];
+ try {
+ $relation = $query->getRelation($relationName);
+ $sub1Relation = $relation->getRelation($sub1RelationName);
+ $sub2Relation = $sub1Relation->getRelation($sub2RelationName);
+ $sub3Relation = $sub2Relation->getRelation($sub3RelationName);
+ $query = $this->queryJoinBuilder($query, $relation, $sub1Relation, $sub2Relation, $sub3Relation);
+ } catch (BadMethodCallException $e) {
+ throw new ColumnSortableException($relationName, 1, $e);
+ } catch (\Exception $e) {
+ throw new ColumnSortableException($relationName, 2, $e);
+ }
+ $model = $relation->getRelated();
+ $sub1Model = $sub1Relation->getRelated();
+ $sub2Model = $sub2Relation->getRelated();
+ $sub3Model = $sub3Relation->getRelated();
+ } else if (count($explodeResult) == 4) {
+ $relationName = $explodeResult[0];
+ $sub1RelationName = $explodeResult[1];
+ $sub2RelationName = $explodeResult[2];
+ $column = $explodeResult[3];
+ try {
+ $relation = $query->getRelation($relationName);
+ $sub1Relation = $relation->getRelation($sub1RelationName);
+ $sub2Relation = $sub1Relation->getRelation($sub2RelationName);
+ $query = $this->queryJoinBuilder($query, $relation, $sub1Relation, $sub2Relation);
+ } catch (BadMethodCallException $e) {
+ throw new ColumnSortableException($relationName, 1, $e);
+ } catch (\Exception $e) {
+ throw new ColumnSortableException($relationName, 2, $e);
+ }
+ $model = $relation->getRelated();
+ $sub1Model = $sub1Relation->getRelated();
+ $sub2Model = $sub2Relation->getRelated();
+ } else if (count($explodeResult) == 3) {
+ $relationName = $explodeResult[0];
+ $subRelationName = $explodeResult[1];
+ $column = $explodeResult[2];
+ try {
+ $relation = $query->getRelation($relationName);
+ $subRelation = $relation->getRelation($subRelationName);
+ $query = $this->queryJoinBuilder($query, $relation, $subRelation);
+ } catch (BadMethodCallException $e) {
+ throw new ColumnSortableException($relationName, 1, $e);
+ } catch (\Exception $e) {
+ throw new ColumnSortableException($relationName, 2, $e);
+ }
+ $subModel = $subRelation->getRelated();
+ $model = $relation->getRelated();
+ } else if (count($explodeResult) == 2) {
+ $relationName = $explodeResult[0];
+ $column = $explodeResult[1];
+ try {
+ $relation = $query->getRelation($relationName);
+ $query = $this->queryJoinBuilder($query, $relation, false);
+ } catch (BadMethodCallException $e) {
+ throw new ColumnSortableException($relationName, 1, $e);
+ } catch (\Exception $e) {
+ throw new ColumnSortableException($relationName, 2, $e);
+ }
+ $model = $relation->getRelated();
}
-
- $model = $relation->getRelated();
}
- if (method_exists($model, Str::camel($column).'Sortable')) {
- return call_user_func_array([$model, Str::camel($column).'Sortable'], [$query, $direction]);
+ if (method_exists($model, Str::camel($column) . 'Sortable')) {
+ return call_user_func_array([$model, Str::camel($column) . 'Sortable'], [$query, $direction]);
}
if (isset($model->sortableAs) && in_array($column, $model->sortableAs)) {
$query = $query->orderBy($column, $direction);
- } elseif ($this->columnExists($model, $column)) {
- $column = $model->getTable().'.'.$column;
- $query = $query->orderBy($column, $direction);
+ } elseif ($this->columnExists($model, $subModel, $column)) {
+ if ($subModel) {
+ $column = $subModel->getTable() . '.' . $column;
+ } else {
+ $column = $model->getTable() . '.' . $column;
+ }
+ $query = $query->orderBy($column, $direction);
}
return $query;
@@ -127,7 +186,7 @@ private function parseParameters(array $parameters)
}
$direction = Arr::get($parameters, 'direction', []);
- if ( ! in_array(strtolower($direction), ['asc', 'desc'])) {
+ if (!in_array(strtolower($direction), ['asc', 'desc'])) {
$direction = config('columnsortable.default_direction', 'asc');
}
@@ -143,28 +202,83 @@ private function parseParameters(array $parameters)
*
* @throws \Exception
*/
- private function queryJoinBuilder($query, $relation)
+ private function queryJoinBuilder($query, $relation, $sub1Relation = null, $sub2Relation = null, $sub3Relation = null)
{
+ $sub1RelatedTable = ($sub1Relation) ? $sub1Relation->getRelated()->getTable() : false;
+ $sub2RelatedTable = ($sub2Relation) ? $sub2Relation->getRelated()->getTable() : false;
+ $sub3RelatedTable = ($sub3Relation) ? $sub3Relation->getRelated()->getTable() : false;
+
$relatedTable = $relation->getRelated()->getTable();
- $parentTable = $relation->getParent()->getTable();
+ $parentTable = $relation->getParent()->getTable();
if ($parentTable === $relatedTable) {
- $query = $query->from($parentTable.' as parent_'.$parentTable);
- $parentTable = 'parent_'.$parentTable;
+ $query = $query->from($parentTable . ' as parent_' . $parentTable);
+ $parentTable = 'parent_' . $parentTable;
$relation->getParent()->setTable($parentTable);
}
if ($relation instanceof HasOne) {
$relatedPrimaryKey = $relation->getQualifiedForeignKeyName();
- $parentPrimaryKey = $relation->getQualifiedParentKeyName();
+ $parentPrimaryKey = $relation->getQualifiedParentKeyName();
} elseif ($relation instanceof BelongsTo) {
$relatedPrimaryKey = $relation->getQualifiedOwnerKeyName();
- $parentPrimaryKey = $relation->getQualifiedForeignKeyName();
+ $parentPrimaryKey = $relation->getQualifiedForeignKeyName();
} else {
throw new \Exception();
}
- return $this->formJoin($query, $parentTable, $relatedTable, $parentPrimaryKey, $relatedPrimaryKey);
+ $sub1RelatedParentPrimaryKey = false;
+ $sub1RelatedPrimaryKey = false;
+
+ $sub2RelatedParentPrimaryKey = false;
+ $sub2RelatedPrimaryKey = false;
+
+ $sub3RelatedParentPrimaryKey = false;
+ $sub3RelatedPrimaryKey = false;
+
+ if ($sub1Relation) {
+ if ($sub1Relation instanceof HasOne) {
+ $sub1RelatedParentPrimaryKey = $sub1Relation->getQualifiedForeignKeyName();
+ $sub1RelatedPrimaryKey = $sub1Relation->getQualifiedParentKeyName();
+ } elseif ($sub1Relation instanceof BelongsTo) {
+ $sub1RelatedParentPrimaryKey = $sub1Relation->getQualifiedOwnerKeyName();
+ $sub1RelatedPrimaryKey = $sub1Relation->getQualifiedForeignKeyName();
+ } else {
+ throw new \Exception();
+ }
+ }
+
+ if ($sub2Relation) {
+ if ($sub2Relation instanceof HasOne) {
+ $sub2RelatedParentPrimaryKey = $sub2Relation->getQualifiedForeignKeyName();
+ $sub2RelatedPrimaryKey = $sub2Relation->getQualifiedParentKeyName();
+ } elseif ($sub2Relation instanceof BelongsTo) {
+ $sub2RelatedParentPrimaryKey = $sub2Relation->getQualifiedOwnerKeyName();
+ $sub2RelatedPrimaryKey = $sub2Relation->getQualifiedForeignKeyName();
+ } else {
+ throw new \Exception();
+ }
+ }
+
+ if ($sub3Relation) {
+ if ($sub3Relation instanceof HasOne) {
+ $sub3RelatedParentPrimaryKey = $sub3Relation->getQualifiedForeignKeyName();
+ $sub3RelatedPrimaryKey = $sub3Relation->getQualifiedParentKeyName();
+ } elseif ($sub3Relation instanceof BelongsTo) {
+ $sub3RelatedParentPrimaryKey = $sub3Relation->getQualifiedOwnerKeyName();
+ $sub3RelatedPrimaryKey = $sub3Relation->getQualifiedForeignKeyName();
+ } else {
+ throw new \Exception();
+ }
+ }
+
+ return $this->formJoin($query,
+ $parentTable, $relatedTable, $sub1RelatedTable, $sub2RelatedTable, $sub3RelatedTable,
+ $parentPrimaryKey, $relatedPrimaryKey,
+ $sub1RelatedParentPrimaryKey, $sub1RelatedPrimaryKey,
+ $sub2RelatedParentPrimaryKey, $sub2RelatedPrimaryKey,
+ $sub3RelatedParentPrimaryKey, $sub3RelatedPrimaryKey,
+ );
}
@@ -174,10 +288,15 @@ private function queryJoinBuilder($query, $relation)
*
* @return bool
*/
- private function columnExists($model, $column)
+ private function columnExists($model, $subModel, $column)
{
- return (isset($model->sortable)) ? in_array($column, $model->sortable) :
- Schema::connection($model->getConnectionName())->hasColumn($model->getTable(), $column);
+ if (!$subModel) {
+ return (isset($model->sortable)) ? in_array($column, $model->sortable) :
+ Schema::connection($model->getConnectionName())->hasColumn($model->getTable(), $column);
+ }
+
+ return (isset($subModel->sortable)) ? in_array($column, $subModel->sortable) :
+ Schema::connection($subModel->getConnectionName())->hasColumn($subModel->getTable(), $column);
}
@@ -199,7 +318,7 @@ private function formatToParameters($array)
}
return (key($array) === 0) ? ['sort' => $array[0], 'direction' => $defaultDirection] : [
- 'sort' => key($array),
+ 'sort' => key($array),
'direction' => reset($array),
];
}
@@ -214,10 +333,33 @@ private function formatToParameters($array)
*
* @return mixed
*/
- private function formJoin($query, $parentTable, $relatedTable, $parentPrimaryKey, $relatedPrimaryKey)
+ private function formJoin(
+ $query,
+ $parentTable, $relatedTable, $sub1RelatedTable, $sub2RelatedTable, $sub3RelatedTable,
+ $parentPrimaryKey, $relatedPrimaryKey,
+ $sub1RelatedParentPrimaryKey, $sub1RelatedPrimaryKey,
+ $sub2RelatedParentPrimaryKey, $sub2RelatedPrimaryKey,
+ $sub3RelatedParentPrimaryKey, $sub3RelatedPrimaryKey,
+ )
{
$joinType = config('columnsortable.join_type', 'leftJoin');
- return $query->select($parentTable.'.*')->{$joinType}($relatedTable, $parentPrimaryKey, '=', $relatedPrimaryKey);
+ if ($query->getQuery()->columns === null) {
+ $query->select($parentTable.'.*');
+ }
+
+ $query->{$joinType}($relatedTable, $parentPrimaryKey, '=', $relatedPrimaryKey);
+
+ if ($sub1RelatedTable) {
+ $query->{$joinType}($sub1RelatedTable, $sub1RelatedParentPrimaryKey, '=', $sub1RelatedPrimaryKey);
+ }
+ if ($sub2RelatedTable) {
+ $query->{$joinType}($sub2RelatedTable, $sub2RelatedParentPrimaryKey, '=', $sub2RelatedPrimaryKey);
+ }
+ if ($sub3RelatedTable) {
+ $query->{$joinType}($sub3RelatedTable, $sub3RelatedParentPrimaryKey, '=', $sub3RelatedPrimaryKey);
+ }
+
+ return $query;
}
}
diff --git a/src/ColumnSortable/SortableLink.php b/src/ColumnSortable/SortableLink.php
index 986b0f2..ff4a12e 100644
--- a/src/ColumnSortable/SortableLink.php
+++ b/src/ColumnSortable/SortableLink.php
@@ -81,7 +81,7 @@ public static function explodeSortParameter($parameter)
if (Str::contains($parameter, $separator)) {
$oneToOneSort = explode($separator, $parameter);
- if (count($oneToOneSort) !== 2) {
+ if (count($oneToOneSort) < 1) {
throw new ColumnSortableException();
}
@@ -268,7 +268,7 @@ private static function buildAnchorAttributesString($anchorAttributes)
}
unset($anchorAttributes['href']);
-
+
$attributes = [];
foreach ($anchorAttributes as $k => $v) {
$attributes[] = $k.('' != $v ? '="'.$v.'"' : '');