Use like:
User::query()->search(["first_name", "last_name", "role.name"], "some query")
| Builder::macro('search', function ($fields = [], $string) { | |
| if (!$string) return $this; | |
| // Split into AND groups | |
| $strings = explode(" ", $string); | |
| $query = $this; | |
| foreach($strings as $string) { | |
| // AND | |
| $query = $query->where(function($query) use($fields, $string) { | |
| foreach($fields as $field) { | |
| // OR | |
| if (str_contains($field, ".")) { | |
| $relation = Str::before($field, '.'); | |
| $field = Str::after($field, '.'); | |
| // nested search | |
| $query = $query->with($relation) | |
| ->orWhereHas($relation , function($query) use($field, $string) { | |
| $query->where($field, 'LIKE', '%' . $string . '%'); | |
| }); | |
| } else { | |
| $query = $query->orWhere($field, 'like', '%'.$string.'%'); | |
| } | |
| } | |
| }); | |
| } | |
| return $query; | |
| }); |