Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save omar-vasquez-dev/a9e6c1ca0ebed1bc10ae422b69c38310 to your computer and use it in GitHub Desktop.
Save omar-vasquez-dev/a9e6c1ca0ebed1bc10ae422b69c38310 to your computer and use it in GitHub Desktop.
SearchBuilder for Laravel
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use ReflectionFunction;
abstract class SearchBuilder
{
protected $query;
protected $filters;
abstract public function uniqueSearch($query, string $search, $category): Builder;
abstract public function multiSearch($query, array $search, $category): Builder;
public function build($query, array $filters): self
{
$this->query = $query;
$this->filters = $filters;
return $this;
}
public function newQuery()
{
$this->addWith();
$this->addSearchFilter();
$this->addFilters();
return $this->query;
}
private function addSearchFilter()
{
$search = Arr::get($this->filters, 'search', null);
$category = Arr::get($this->filters, 'category', '');
Arr::forget($this->filters, 'search');
Arr::forget($this->filters, 'category');
if ($search === null) {
return;
}
if (is_array($search) && count($search) > 0) {
$this->query = $this->multiSearch($this->query, $search, $category);
return;
}
if (is_string($search) && strlen(trim($search)) > 0) {
$this->query = $this->uniqueSearch($this->query, $search, $category);
}
}
private function addFilters()
{
foreach ($this->filters as $key => $filter) {
$this->dispatchFilter($key, $filter);
}
}
private function dispatchFilter($key, $filter)
{
$functionName = "filter_{$key}";
if (method_exists($this, $functionName)) {
$filterResult = $this->{$functionName}($this->query, $filter);
$this->query = $filterResult ?? $this->query;
}
}
private function addWith()
{
$with = Arr::get($this->filters, 'with', []);
if (is_array($with)) {
foreach ($with as $w) {
$this->query = $this->query->with($w);
}
} else if (is_string($with)) {
$this->query = $this->query->with($with);
}
Arr::forget($this->filters, 'with');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment