Level 70
@msslgomez Can you try this:
trait FiltersTrait
{
public function scopeFilter($query, $filters, $attributes, $relationship = null)
{
// Group the search conditions in a closure to avoid breaking the other filters
$query->when($filters['search'] ?? null, function ($q, $search) use ($attributes) {
$q->where(function ($q) use ($search, $attributes) {
foreach (Arr::wrap($attributes) as $key => $attribute) {
if (Str::contains($attribute, '.')) {
$nested = explode('.', $attribute);
$column = array_pop($nested);
$related = implode('.', $nested);
if (is_string($key))
$q->orWhereMorphRelation($related, $key, $column, 'like', "%{$search}%");
else
$q->orWhereRelation($related, $column, 'like', "%{$search}%");
} else {
$q->orWhere($attribute, 'like', "%{$search}%");
}
}
});
});
// Handle trashed records
$query->when($filters['trashed'] ?? null, function ($q, $trashed) {
if ($trashed === 'with') {
$q->withTrashed();
} elseif ($trashed === 'only') {
$q->onlyTrashed();
}
});
// Handle sorting
$query->when($filters['sort_field'] ?? null && $filters['sort_dir'] ?? null, function ($q) use ($filters) {
$q->orderBy($filters['sort_field'], $filters['sort_dir']);
});
// Handle relationships
$query->when($filters['filters'] ?? null && $relationship !== null, function ($q) use ($filters, $relationship) {
foreach (Arr::wrap($filters['filters']) as $key => $item) {
$q->whereHas($relationship[$key], function ($q) use ($filters, $key) {
$q->whereIn('id', $filters['filters'][$key]);
});
}
});
return $query;
}
}
2 likes