Created
February 19, 2020 08:38
-
-
Save freekmurze/9344ba437f14e4ba3c2dbd794e5883d9 to your computer and use it in GitHub Desktop.
FuzzyFilter
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 | |
namespace Spatie\Mailcoach\Http\App\Queries\Filters; | |
use Illuminate\Database\Eloquent\Builder; | |
use Illuminate\Support\Arr; | |
use Illuminate\Support\Str; | |
use Spatie\QueryBuilder\Filters\Filter; | |
class FuzzyFilter implements Filter | |
{ | |
/** @var string[] */ | |
protected array $fields; | |
public function __construct(string ...$fields) | |
{ | |
$this->fields = $fields; | |
} | |
public function __invoke(Builder $query, $values, string $property): Builder | |
{ | |
$values = Arr::wrap($values); | |
$query->where(function (Builder $query) use ($values) { | |
$this | |
->addDirectFields($query, $values) | |
->addRelationShipFields($query, $values); | |
}); | |
return $query; | |
} | |
public function addDirectFields(Builder $query, $values) | |
{ | |
collect($this->fields) | |
->reject(fn (string $field) => Str::contains($field, '.')) | |
->each(function (string $field) use ($query, $values) { | |
foreach ($values as $value) { | |
$query->orWhere($field, 'LIKE', "%{$value}%"); | |
} | |
}); | |
return $this; | |
} | |
public function addRelationShipFields(Builder $query, $values) | |
{ | |
collect($this->fields) | |
->filter(fn (string $field) => Str::contains($field, '.')) | |
->each(function (string $field) use ($query, $values) { | |
foreach ($values as $value) { | |
[$relation, $field] = explode('.', $field); | |
$query->orWhereHas($relation, function (Builder $query) use ($field, $value) { | |
$query->where($field, 'LIKE', "%{$value}%"); | |
}); | |
} | |
}); | |
return $this; | |
} | |
} |
keizah7
commented
Feb 8, 2022
Fixed:
public function addRelationShipFields(Builder $query, $values)
{
collect($this->fields)
->filter(fn (string $field) => Str::contains($field, '.'))
->each(function (string $field) use ($query, $values) {
foreach ($values as $value) {
[$relation, $column] = explode('.', $field);
$query->orWhereHas($relation, function (Builder $query) use ($column, $value) {
$query->where($column, 'LIKE', "%{$value}%");
});
}
});
return $this;
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment