-
-
Save zachary/df6a4c6ac1064a4df221345e5b3a4b73 to your computer and use it in GitHub Desktop.
Laravel Custom 'whereLike' Macro for Dynamic 'LIKE' Searches including relationships
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
<?php | |
use Illuminate\Support\ServiceProvider; | |
use Illuminate\Database\Eloquent\Builder; | |
use Illuminate\Support\Arr; | |
class AppServiceProvider extends ServiceProvider | |
{ | |
// ... | |
public function boot() | |
{ | |
// Define the 'whereLike' macro | |
Builder::macro('whereLike', function ($attributes, string $searchTerm) { | |
$this->where(function (Builder $query) use ($attributes, $searchTerm) { | |
foreach (Arr::wrap($attributes) as $attribute) { | |
$query->when( | |
// Check if the attribute is not an expression and contains a dot (indicating a related model) | |
!($attribute instanceof \Illuminate\Contracts\Database\Query\Expression) && | |
str_contains((string) $attribute, '.'), | |
function (Builder $query) use ($attribute, $searchTerm) { | |
// Split the attribute into a relation and related attribute | |
[$relation, $relatedAttribute] = explode('.', (string) $attribute); | |
// Perform a 'LIKE' search on the related model's attribute | |
$query->orWhereHas($relation, function (Builder $query) use ($relatedAttribute, $searchTerm) { | |
$query->where($relatedAttribute, 'LIKE', "%{$searchTerm}%"); | |
}); | |
}, | |
function (Builder $query) use ($attribute, $searchTerm) { | |
// Perform a 'LIKE' search on the current model's attribute | |
// also attribute can be an expression | |
$query->orWhere($attribute, 'LIKE', "%{$searchTerm}%"); | |
} | |
); | |
} | |
}); | |
}); | |
} | |
} | |
// example of usage 👇 | |
Post::query() | |
->whereLike([ | |
'title', | |
// search in the current model's 'title' attribute | |
'description', | |
// search in the current model's 'description' attribute | |
'user.name', | |
// search in the related model's 'name' attribute | |
'user.email', | |
// search in the related model's 'email' attribute | |
DB::raw('DATE_FORMAT(created_at, "%d/%m/%Y")'), | |
// search in the formatted 'created_at' attribute | |
DB::raw('CONCAT(user.first_name, " ", user.last_name)'), | |
// search in the concatenated 'first_name' and 'last_name' attributes | |
], request()->search) | |
// search for the request's 'search' query parameter | |
->with('user') | |
->get(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment