Skip to content

Instantly share code, notes, and snippets.

@freekmurze
Created February 19, 2020 08:38
Show Gist options
  • Save freekmurze/9344ba437f14e4ba3c2dbd794e5883d9 to your computer and use it in GitHub Desktop.
Save freekmurze/9344ba437f14e4ba3c2dbd794e5883d9 to your computer and use it in GitHub Desktop.
FuzzyFilter
<?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
Copy link

keizah7 commented Feb 8, 2022

image

AllowedFilter::custom('keywords', new FuzzyFilter('name', 'description_1', 'company.name')),

@keizah7
Copy link

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