-
Notifications
You must be signed in to change notification settings - Fork 0
Filters
This package allows the user to filter returned data via defined parameters called filters.
Filters can be defined in the init method of the class
class ExampleQuerableResource extends ResourceQuery {
protected function getQuery(): \Illuminate\Database\Eloquent\Builder
{
return User::where('id','>',0); // Just a simple query to demonstrate functionality
}
protected function init()
{
$this
->filter('name','like%')
->filter('email','%like%');
//...
}
}
or after its initialization
$qr = new ExampleQuerableResource();
$qr->filter('name','like%')
->filter('email','%like%');
//...
$query = User::select(['id','name','email'])->where('id','>',0);
$qr = new ResourceQueryBuilder($query);
$qr->filter('name','like%')
->filter('email','%like%');
The init function will be called after the class constructor so any additional filters will be applied after.
Filters are composed of three main components: an unique filter name that will be used as query parameter, a condition that will be used to filter the data, and a field that specifies to what table field the filter will be applied.
You can add filters with the filter function by passing all the filter configuration or by adding it afterwards.
Note: if no field is specified the filter name will be automatically used as field (and will cause errors if not exists) and '=' will be used as a default condition.
$qr = new ExampleQuerableResource();
//You can specify all the basic filter parameter in the builder
$qr->filter('filter-name','=','table-field');
//or specify just the filter name and customize it afterwards
$qr->filter('filter-name2')
->field('table-field2');
->condition('%like%');
You can also add a filter with the filters->add method (alias to filter method)
//alias of $qr->filter(...)
$qr->filters->add('filter-label')->field('fieldA')->condition('=');
The previous functions will add a filter if not exists and edit it if it already exists without overwriting all the previous informations; If you want to re-define all the filter information you can use the fiters->set function.
$qr->filters->set('filter-label2')->field('fieldB')->condition('%like%');
The filter condition can be either an SQL condition (like =
,!=
,<>
,like
,in
, etc.),
a shortand helper like like%
,%like
or %like%
that will perform an SQL like
compare adding a "%" character before, after or at both ends of the input, or a Callable function that will resolve the filter.
Example:
$qr
->filter('filter1')
->condition('=')//Will preforma a direct compare
->filter('filter2')
->condition('like')//Will perform a like
->filter('filter3')
->condition('>=')//Check if the field is greater than the value
->filter('filter4')
->condition('like%')//Check if the field start with the specified value
->filter('filter5')
->condition('%like%')//Check if the field contains the specified value
;
The Callable condition will have 3 parameters:
-
\Illuminate\Database\Eloquent\Builder
$query - The query where to apply the filter -
mixed
$value - The filtered value -
FilterCondition
$filter - The current filter, used to retrive condition or field name, etc.
$qr
->filter('filter1')
->condition(function($query,$value,$filter){
$q->where('field1','>=',FilterCondition $value)
->orWhere('field2','<=',$value);//Just a basic example, you can do whatever you want to the query
//you can retrieve field name by reading $filter->name
});
You can remove a filter with
$qr->removeFilter('<filter-name>');
//Or
$qr->filters->remove('<filter-name>');
If you wish to remove all filters use
$qr->removeFilters();
or
$qr->filters->removeAll();
Additionally you can remove a filter using the unset function
unset($qr->filters['<filter-name>']);
Filters are passed as query parameters, to avoid query parameter conflicts they can be encapsulated as a query array (ex. "url?filter[name]=value1&filter[email]=value2" ) by defining it with setQueryParameter
on the FilterBuilder
$qr->filters->setQueryParameter('filter');//<-- 'filter' will be used as the root query parameter
By default 'filter'
will be used as a query parameter, if the query parameter is set to null
the root query parameter will be used (ex.: "url?name=value1&email=value2")
If you want to apply a default value if the field is not present you can use defaultValue function:
$resource->filter('filter1','=','fieldA')->defaultValue('1234');//If filter "filter1" is not set it will be applied with value "123"
If you want to format the filter value (ex. escaping characters, capitalize, etc.)
before the filter is applied you can add a callable function with the formatValue
function.
The original filter value will be passed as a parameter and the return value will be used as the new filter value.
Example:
$resource->filters->add('filter1','=','fieldA')->formatValue(function($value){ return trim($value); });
If you want to apply a filter ONLY if one or more filters are present you can use applyIfPresent
function
$resource->filters->add('filter1','=','fieldA');
$resource->filters->add('filter2','like','fieldB');
// If fitler1 or filter2 are empty fitler3 will be ignored
$resource->filters->add('filter3','=','fieldC')->applyIfPresent('filter1','filter2');
If you want to apply a filter ONLY if one or more filters are absent you can use applyIfNotPresent
function
$resource->filters->add('filter1','=','fieldA');
$resource->filters->add('filter2','like','fieldB');
// If fitler1 or filter2 are not empty fitler3 will be ignored
$resource->filters->add('filter3','=','fieldC')->applyIfNotPresent('filter1','filter2');
This library allows many ways to access and define the fiters: you can define condition and field directly on the add or set function
$resource->filters->add(<FILTER_NAME:string>,[<CONDITION:string|callable>],[<FIELD_NAME:string>]);
$resource->filters->set(<FILTER_NAME:string>,[<CONDITION:string|callable>],[<FIELD_NAME:string>]);
Or call it as a parameter, array or function (it will work like the add method)
// Called as a parameter
$qr->filters-><FILTER_NAME>;
// Accessed as an array
$qr->filters['<FILTER_NAME>'];
// Called as a function
$qr->filters-><FILTER_NAME>([<CONDITION:string|callable>],[<FIELD_NAME:string>]);
The add and set function can be called also on the condition allowing a fluent filter definition:
$qr->filters
->add('name')->field('name')->condition('like')
->add('email')->field('email')->condition('like'); //the add funtion will add a new filter and set the definition on the new one.