-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4e4f508
Showing
5 changed files
with
162 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/dist | ||
/.idea | ||
/vendor | ||
/node_modules | ||
package-lock.json | ||
composer.phar | ||
composer.lock | ||
phpunit.xml | ||
.phpunit.result.cache | ||
.DS_Store | ||
Thumbs.db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "titasgailius/search-relations", | ||
"description": "A Laravel Nova tool.", | ||
"keywords": [ | ||
"laravel", | ||
"nova", | ||
"search", | ||
"relations" | ||
], | ||
"license": "MIT", | ||
"require": { | ||
"php": ">=7.1.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"Titasgailius\\SearchRelations\\": "src/" | ||
} | ||
}, | ||
"config": { | ||
"sort-packages": true | ||
}, | ||
"minimum-stability": "dev", | ||
"prefer-stable": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Search relationships in Laravel Nova | ||
|
||
This package allow you to include relationship columns into Laravel Nova search query. | ||
|
||
## Screenshot | ||
|
||
![screenshot of the search relations tool](./screenshot.png) | ||
|
||
## Installation | ||
|
||
``` | ||
composer require titasgailius/search-relations | ||
``` | ||
|
||
Next, add `Titasgailius\SearchRelations\SearchesRelations` trait to your base resource class `App\Nova\Resource` | ||
```php | ||
use Titasgailius\SearchRelations\SearchesRelations; | ||
|
||
abstract class Resource extends NovaResource | ||
{ | ||
use SearchesRelations; | ||
``` | ||
|
||
## Usage | ||
|
||
Simply add `public static $searchRelations` array to any of your Nova resources. | ||
This array has a relationship name as a key and an array of columns to search for as a value. | ||
```php | ||
/** | ||
* The relationship columns that should be searched. | ||
* | ||
* @var array | ||
*/ | ||
public static $searchRelations = [ | ||
'user' => ['username', 'email'], | ||
]; | ||
``` |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<?php | ||
|
||
namespace Titasgailius\SearchRelations; | ||
|
||
use Closure; | ||
use Illuminate\Database\Eloquent\Builder; | ||
|
||
trait SearchesRelations | ||
{ | ||
/** | ||
* Apply the search query to the query. | ||
* | ||
* @param \Illuminate\Database\Eloquent\Builder $query | ||
* @param string $search | ||
* @return \Illuminate\Database\Eloquent\Builder | ||
*/ | ||
protected static function applySearch($query, $search) | ||
{ | ||
return tap(parent::applySearch($query, $search), function ($query) use ($search) { | ||
static::applyRelationSearch($query, $search); | ||
}); | ||
} | ||
|
||
/** | ||
* Apply the relationship search query to the given query. | ||
* | ||
* @param \Illuminate\Database\Eloquent\Builder $query | ||
* @param string $search | ||
* @return void | ||
*/ | ||
public static function applyRelationSearch(Builder $query, string $search) | ||
{ | ||
foreach (static::searchableRelations() as $relation => $columns) { | ||
$query->orWhereHas($relation, function ($query) use ($columns, $search) { | ||
$query->where(static::searchQueryApplier($columns, $search)); | ||
}); | ||
} | ||
|
||
// All search conditionals have to be combined into 1 nested conditional. | ||
// We just applied a query to search for relationship columns while Nova | ||
// has also applied a separate query to search for model columns. That's | ||
// why we merge last 2 conditionals into 1 nested conditional which leaves | ||
// us with this nicely formatted query that also seatches in relationships. | ||
// SELECT ? FROM ? WHERE ($searchQuery OR $relationQuery) | ||
static::mergeLastWheres($query, 2); | ||
} | ||
|
||
/** | ||
* Get the searchable columns for the resource. | ||
* | ||
* @return array | ||
*/ | ||
public static function searchableRelations(): array | ||
{ | ||
return static::$searchRelations ?? []; | ||
} | ||
|
||
/** | ||
* Returns a Closure that applies a search query for a given columns. | ||
* | ||
* @param array $columns | ||
* @param string $search | ||
* @return \Closure | ||
*/ | ||
public static function searchQueryApplier(array $columns, string $search): Closure | ||
{ | ||
return function ($query) use ($columns, $search) { | ||
foreach ($columns as $column) { | ||
$query->orWhere($column, 'LIKE', '%'.$search.'%'); | ||
} | ||
}; | ||
} | ||
|
||
/** | ||
* Merge last where conditionals into a 1 nested conditional. | ||
* | ||
* @param \Illuminate\Database\Eloquent\Builder $query | ||
* @param int $count | ||
* @return void | ||
*/ | ||
public static function mergeLastWheres(Builder $query, int $count) | ||
{ | ||
$query = $query->getQuery(); | ||
$queries = array_splice($query->wheres, $count); | ||
|
||
$query->where(function ($query) use ($queries) { | ||
$query->wheres = array_merge($query->wheres, $queries); | ||
}); | ||
} | ||
} |