Skip to content

Commit

Permalink
Fix Kyslik#44 introducing new variable $sortableAs
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyslik committed Nov 20, 2016
1 parent 68f6bff commit e541912
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 27 deletions.
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@
- [Publish configuration](#publish-configuration)
- [Usage](#usage)
- [Blade Extension](#blade-extension)
- [Config in few words](#config-in-few-words)
- [Configuration in few words](#configuration-in-few-words)
- [Font Awesome (default font classes)](#font-awesome-default-font-classes)
- [Full Example](#full-example)
- [Routes](#routes)
- [Controller's `index()` method](#controllers-index-method)
- [View](#view)
- [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 overloading (advanced)](#columnsortable-overloading-advanced)
- [`$sortableAs` (aliasing)](#sortableas-aliasing)
- [Exception to catch](#exception-to-catch)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand Down Expand Up @@ -252,7 +258,7 @@ In order to tell package to sort using relation:

```
@sortablelink('detail.phone_number', 'phone')
@sortablelink('user.name', 'phone')
@sortablelink('user.name', 'name')
```
>**Note**: package works with relation "name" (method) that you define in model instead of table name.
Expand Down Expand Up @@ -295,6 +301,34 @@ In view just use `@sortablelink('address')`
One more example: [#41](https://github.com/Kyslik/column-sortable/issues/41#issuecomment-250895909)

# `$sortableAs` (aliasing)

It is possible to declare `$sortableAs` array and use it to alias (bypass column exists check),
and ignore prefixing with table.

In model
```
...
$sortableAs = ['nick_name'];
...
```

In controller

```
$users = $user->select(['name as nick_name'])->sortable(['nick_name'])->paginate(10);
```

In view
```
@sortablelink('nick_name', 'nick')
```


Please see [#44](https://github.com/Kyslik/column-sortable/issues/44).


# Exception to catch

#### Package throws custom exception `ColumnSortableException` with three codes (0, 1, 2).
Expand Down
8 changes: 5 additions & 3 deletions src/ColumnSortable/Sortable.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private function queryOrderBuilder($query, array $sortParameters)
}

if (method_exists($this, camel_case($column) . 'Sortable')) {
return call_user_func_array(array($this, camel_case($column) . 'Sortable'), array($query, $direction));
return call_user_func_array([$this, camel_case($column) . 'Sortable'], [$query, $direction]);
}

$explodeResult = SortableLink::explodeSortParameter($column);
Expand All @@ -74,9 +74,11 @@ private function queryOrderBuilder($query, array $sortParameters)
$model = $relation->getRelated();
}

if ($this->columnExists($model, $column)) {
if (isset($model->sortableAs) && in_array($column, $model->sortableAs)) {
$query = $query->orderBy($column, $direction);
} elseif ($this->columnExists($model, $column)) {
$column = $model->getTable() . '.' . $column;
return $query->orderBy($column, $direction);
$query = $query->orderBy($column, $direction);
}

return $query;
Expand Down
60 changes: 38 additions & 22 deletions tests/ColumnSortableTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,51 @@ public function testSortableQueryJoinBuilder()
$query = $this->user->newQuery()->with(['profile']);
$relation = $query->getRelation('profile');
$resultQuery = $this->invokeMethod($this->user, 'queryJoinBuilder', [$query, $relation]);
$expectedQuery = $this->user->newQuery()->select('users.*')->join('profiles', 'users.id', '=', 'profiles.user_id');
$expectedQuery = $this->user->newQuery()->select('users.*')->join('profiles', 'users.id', '=',
'profiles.user_id');
$this->assertEquals($expectedQuery->toSql(), $resultQuery->toSql());

$query = $this->profile->newQuery()->with(['user']);
$relation = $query->getRelation('user');
$resultQuery = $this->invokeMethod($this->user, 'queryJoinBuilder', [$query, $relation]);
$expectedQuery = $this->profile->newQuery()->select('profiles.*')->join('users', 'profiles.user_id', '=', 'users.id');
$expectedQuery = $this->profile->newQuery()->select('profiles.*')->join('users', 'profiles.user_id', '=',
'users.id');
$this->assertEquals($expectedQuery->toSql(), $resultQuery->toSql());
}

/**
* Call protected/private method of a class.
*
* @param object &$object Instantiated object that we will run method on.
* @param string $methodName Method name to call
* @param array $parameters Array of parameters to pass into method.
* @return mixed Method return.
*/
protected function invokeMethod(&$object, $methodName, array $parameters = [])
{
$reflection = new \ReflectionClass(get_class($object));
$method = $reflection->getMethod($methodName);
$method->setAccessible(true);

return $method->invokeArgs($object, $parameters);
}

public function testSortableOverridingQueryOrderBuilder()
{
$sortParameters = ['sort' => 'address', 'order' => 'desc'];
$query = $this->user->newQuery();
$resultQuery = $this->invokeMethod($this->user, 'queryOrderBuilder', [$query, $sortParameters]);
$expectedQuery = $this->user->newQuery()->join('profiles', 'users.id', '=', 'profiles.user_id')->orderBy('address', 'desc')->select('users.*');
$expectedQuery = $this->user->newQuery()->join('profiles', 'users.id', '=',
'profiles.user_id')->orderBy('address', 'desc')->select('users.*');
$this->assertEquals($expectedQuery, $resultQuery);
}

public function testSortableAs()
{
$sortParameters = ['sort' => 'nick_name', 'order' => 'asc'];
$query = $this->user->newQuery()->select('name as nick_name');
$resultQuery = $this->invokeMethod($this->user, 'queryOrderBuilder', [$query, $sortParameters]);
$expectedQuery = $this->user->newQuery()->select('name as nick_name')->orderBy('nick_name', 'asc');
$this->assertEquals($expectedQuery, $resultQuery);
}

Expand Down Expand Up @@ -221,23 +250,6 @@ public function testFormatToSortParameters()
$expected = ['sort' => 'foo', 'order' => 'desc'];
$this->assertEquals($expected, $resultArray);
}

/**
* Call protected/private method of a class.
*
* @param object &$object Instantiated object that we will run method on.
* @param string $methodName Method name to call
* @param array $parameters Array of parameters to pass into method.
* @return mixed Method return.
*/
protected function invokeMethod(&$object, $methodName, array $parameters = array())
{
$reflection = new \ReflectionClass(get_class($object));
$method = $reflection->getMethod($methodName);
$method->setAccessible(true);

return $method->invokeArgs($object, $parameters);
}
}

/**
Expand All @@ -256,6 +268,10 @@ class User extends Model
'amount'
];

public $sortableAs = [
'nick_name'
];

/**
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
Expand All @@ -267,8 +283,8 @@ public function profile()
public function addressSortable($query, $direction)
{
return $query->join('profiles', 'users.id', '=', 'profiles.user_id')
->orderBy('address', $direction)
->select('users.*');
->orderBy('address', $direction)
->select('users.*');
}
}

Expand Down

0 comments on commit e541912

Please sign in to comment.