Last active
February 22, 2023 05:51
-
-
Save kingwill101/3a7a7a21682c960cab65c28042b32675 to your computer and use it in GitHub Desktop.
Laravel query builder filtering
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 Api\Queries; | |
use Illuminate\Database\Eloquent\Builder; | |
use Illuminate\Support\Arr; | |
use Illuminate\Support\Carbon; | |
trait QueryFilterTrait | |
{ | |
/** | |
* | |
* Filter resources based on provided filters | |
* | |
* filters can be provided in several forms | |
* filter[{{resource_field_name}}]={{resource_field_value}} | |
* filter[{{resource_field_name}}][value]={{resource_field_value}} | |
* | |
* for advance lookups named filters can be used | |
* | |
* filter[{{custom-filter-name}}][condition][value]={{resource_field_value}} | |
* filter[{{custom-filter-name}}][condition][operator]= {{resource_field_operator}} | |
* filter[{{custom-filter-name}}][condition][path]={{resource_field_name}} | |
* | |
* or | |
* | |
* filter[{{custom-filter-name}}][condition][value]={{resource_field_value}} | |
* filter[{{custom-filter-name}}][condition][path]={{resource_field_name}} | |
* | |
* | |
* @param Builder $query | |
* @param array $params | |
* @param array $allowed_filters | |
* @param array $property_aliases | |
* @param array $allowed_operators | |
*/ | |
public function parseFilters(Builder $query, array $params, array $allowed_filters = [], array $property_aliases = [], array $allowed_operators = ["lt", "lte", "gt", "gte", "eq", "like", "or"]) | |
{ | |
if (!isset($params["filter"]) || !is_array($params["filter"])) { | |
return; | |
} | |
$filters = $params["filter"]; | |
foreach (array_keys($filters) as $key) { | |
$filtered = $filters[$key]; | |
if (!isset($filtered)) { | |
continue; | |
} | |
if (!is_array($filtered)) { | |
if (!in_array($key, $allowed_filters) && !Arr::has($property_aliases, $key)) { | |
continue; | |
} | |
//filter[status]=1 | |
$this->where($query, Arr::has($property_aliases, $key) ? | |
Arr::get($property_aliases, $key) : $key, "=", | |
$filtered); | |
continue; | |
} | |
if (isset($filtered["value"])) { | |
//short version | |
//filter[status][value]=1 | |
if (!in_array($key, $allowed_filters) && !Arr::has($property_aliases, $key)) { | |
continue; | |
} | |
$key = Arr::has($property_aliases, $key) ? Arr::get($property_aliases, $key) : $key; | |
$this->where($query, $key, "=", $filtered["value"]); | |
} else if (isset($filtered["condition"])) { | |
//long version(named filters) | |
$value = $filtered["condition"]["value"] ?? null; | |
$operator = $filtered["condition"]["operator"] ?? null; | |
$path = $filtered["condition"]["path"] ?? null; | |
if (!isset($path) && (!Arr::has($allowed_filters, $path) || !Arr::has($property_aliases, $path))) { | |
continue; | |
} | |
$path = Arr::has($property_aliases, $path) ? Arr::get($property_aliases, $path) : $path; | |
if (isset($operator) && isset($value)) { | |
//filter[status-filter][condition][value]=1 | |
//filter[status-filter][condition][operator]= 'eq' | |
//filter[status-filter][condition][path]=status | |
if (!in_array($operator, $allowed_operators)) { | |
continue; | |
} | |
switch ($operator) { | |
case "lt": | |
$this->where($query, $path, "<", $value); | |
break; | |
case "lte": | |
$this->where($query, $path, "<=", $value); | |
break; | |
case "gt": | |
$this->where($query, $path, ">", $value); | |
break; | |
case "gte": | |
$this->where($query, $path, ">=", $value); | |
break; | |
case "eq": | |
$this->where($query, $path, "=", $value); | |
break; | |
case "or": | |
$this->where($query, $path, "=", $value, true); | |
break; | |
case "like": | |
$this->where($query, $path, "like", "%" . $value . "%"); | |
break; | |
default: | |
break; | |
} | |
} else if (isset($value)) { | |
//filter[status-filter][condition][value]=1 | |
//filter[status-filter][condition][path]=status | |
$this->where($query, $path, "=", $value); | |
} | |
} | |
} | |
} | |
private function where(Builder $query, $col, $operator, $value, bool $or = false) | |
{ | |
if (in_array($col, $query->getModel()->getDates())) { | |
if ($or) { | |
$query->orWhereDate($col, $operator, Carbon::parse($value)); | |
return; | |
} | |
$query->whereDate($col, $operator, Carbon::parse($value)); | |
return; | |
} | |
if ($or) { | |
$query->orWhere($col, $operator, $value); | |
return; | |
} | |
$query->where($col, $operator, $value); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Updated to handle the querying of date fields