Skip to content

Commit 4e4f508

Browse files
committed
Init
0 parents  commit 4e4f508

File tree

5 files changed

+162
-0
lines changed

5 files changed

+162
-0
lines changed

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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

composer.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "titasgailius/search-relations",
3+
"description": "A Laravel Nova tool.",
4+
"keywords": [
5+
"laravel",
6+
"nova",
7+
"search",
8+
"relations"
9+
],
10+
"license": "MIT",
11+
"require": {
12+
"php": ">=7.1.0"
13+
},
14+
"autoload": {
15+
"psr-4": {
16+
"Titasgailius\\SearchRelations\\": "src/"
17+
}
18+
},
19+
"config": {
20+
"sort-packages": true
21+
},
22+
"minimum-stability": "dev",
23+
"prefer-stable": true
24+
}

readme.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Search relationships in Laravel Nova
2+
3+
This package allow you to include relationship columns into Laravel Nova search query.
4+
5+
## Screenshot
6+
7+
![screenshot of the search relations tool](./screenshot.png)
8+
9+
## Installation
10+
11+
```
12+
composer require titasgailius/search-relations
13+
```
14+
15+
Next, add `Titasgailius\SearchRelations\SearchesRelations` trait to your base resource class `App\Nova\Resource`
16+
```php
17+
use Titasgailius\SearchRelations\SearchesRelations;
18+
19+
abstract class Resource extends NovaResource
20+
{
21+
use SearchesRelations;
22+
```
23+
24+
## Usage
25+
26+
Simply add `public static $searchRelations` array to any of your Nova resources.
27+
This array has a relationship name as a key and an array of columns to search for as a value.
28+
```php
29+
/**
30+
* The relationship columns that should be searched.
31+
*
32+
* @var array
33+
*/
34+
public static $searchRelations = [
35+
'user' => ['username', 'email'],
36+
];
37+
```

screenshot.png

103 KB
Loading

src/SearchesRelations.php

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
namespace Titasgailius\SearchRelations;
4+
5+
use Closure;
6+
use Illuminate\Database\Eloquent\Builder;
7+
8+
trait SearchesRelations
9+
{
10+
/**
11+
* Apply the search query to the query.
12+
*
13+
* @param \Illuminate\Database\Eloquent\Builder $query
14+
* @param string $search
15+
* @return \Illuminate\Database\Eloquent\Builder
16+
*/
17+
protected static function applySearch($query, $search)
18+
{
19+
return tap(parent::applySearch($query, $search), function ($query) use ($search) {
20+
static::applyRelationSearch($query, $search);
21+
});
22+
}
23+
24+
/**
25+
* Apply the relationship search query to the given query.
26+
*
27+
* @param \Illuminate\Database\Eloquent\Builder $query
28+
* @param string $search
29+
* @return void
30+
*/
31+
public static function applyRelationSearch(Builder $query, string $search)
32+
{
33+
foreach (static::searchableRelations() as $relation => $columns) {
34+
$query->orWhereHas($relation, function ($query) use ($columns, $search) {
35+
$query->where(static::searchQueryApplier($columns, $search));
36+
});
37+
}
38+
39+
// All search conditionals have to be combined into 1 nested conditional.
40+
// We just applied a query to search for relationship columns while Nova
41+
// has also applied a separate query to search for model columns. That's
42+
// why we merge last 2 conditionals into 1 nested conditional which leaves
43+
// us with this nicely formatted query that also seatches in relationships.
44+
// SELECT ? FROM ? WHERE ($searchQuery OR $relationQuery)
45+
static::mergeLastWheres($query, 2);
46+
}
47+
48+
/**
49+
* Get the searchable columns for the resource.
50+
*
51+
* @return array
52+
*/
53+
public static function searchableRelations(): array
54+
{
55+
return static::$searchRelations ?? [];
56+
}
57+
58+
/**
59+
* Returns a Closure that applies a search query for a given columns.
60+
*
61+
* @param array $columns
62+
* @param string $search
63+
* @return \Closure
64+
*/
65+
public static function searchQueryApplier(array $columns, string $search): Closure
66+
{
67+
return function ($query) use ($columns, $search) {
68+
foreach ($columns as $column) {
69+
$query->orWhere($column, 'LIKE', '%'.$search.'%');
70+
}
71+
};
72+
}
73+
74+
/**
75+
* Merge last where conditionals into a 1 nested conditional.
76+
*
77+
* @param \Illuminate\Database\Eloquent\Builder $query
78+
* @param int $count
79+
* @return void
80+
*/
81+
public static function mergeLastWheres(Builder $query, int $count)
82+
{
83+
$query = $query->getQuery();
84+
$queries = array_splice($query->wheres, $count);
85+
86+
$query->where(function ($query) use ($queries) {
87+
$query->wheres = array_merge($query->wheres, $queries);
88+
});
89+
}
90+
}

0 commit comments

Comments
 (0)