Skip to content

Filtering

plokko edited this page Mar 16, 2021 · 6 revisions

To enable client data filtering you must define a set of filters that the user can access; the user can only interact with defined filters so if none are specified the user won't be able to filter the query.

Each filter is composed of a name (the label that will be used by the client), a condition and a field used to specify the name of the field in the query.

The filter name must be unique, you can define multiple filters using the same table field but with different setting by using different field names.

The condition can be either a base SQL condition ( =, !=, <>, like, in, etc.), a shortand helper like like%, %like or %like% that will add a "%" character before, after or at both ends of the input or a Callable function that will resolve the filter.

The filter field must be accessible by the base query; if not specified the filter name will be used (do mind that the filter name may not be directly mapped to a valid query field, in that case the field must be explicitly specified).

Note: Keep in mind that filters will define a set of rules on how the client can filter the data; the actual filtering is done by the client and not statically applied to the query.

Defining filters

Filters can be defined after class instantiation if using QueryBuilder or if you want to edit filters from an already defined class

//--- Using QueryBuilder ---//
$query = User::select(['id','name','email'])->where('id','>',0);
$qr =  new QueryBuilder($query);
$qr->filter('name','like%')
   ->filter('email','%like%');
//...
//--- Editing filters of an already defined class ---//
$qr = new ExampleQuerableResource();
$qr->filter('name','like%')
   ->filter('email','%like%');
//...

or in the init function on the defined class

class ExampleQuerableResource extends ResourceQuery {
    protected function init()
    {
        // Define filters here
        $this
            ->filter('name','like%')
            ->filter('email','%like%');
        //...
    }
    //...
}

The init function will be called in the class constructor.

Adding filters

To add a filter use the filter function of the ResourceQuery class; this will return the defined filter if another with the same name is present or add a new one:

// Only with a name and default field and condition 
$qr->filter('filter-name'); // equals to $qr->filter('filter-name','=','filter-name'); 
// With optional condition
$qr->filter('filter-name2','=');
// With optional condition and field name
$qr->filter('filter-name3','=','query-field');

Setting filter parameters

Apart from the name all the filter parameters can be changed via method invocation. Available functions are:

  • field(String|null $field) - will set the filter field to the specified value
  • condition(string|callable) - will set the filter condition to the specified value
  • ** defaultValue($value)** - Will set a default value if the client won't specify a value (WIP)
  • ** formatValue(callable|null $formatter)** - Will apply a callable function that will parse the user data
  • ** applyIf(callable $cnd)** - Will apply this filter only if the callable returns true
  • ** applyIfPresent(string|array $name,...)** - Will only apply this condition if all the specified filters are present on the query
  • ** applyIfNotPresent(string|array $name,...)** - Will only apply this condition if all the filters specifiead are NOT present on the query All this functions can be declarent via a fluent interface as they return the filter istance:
$qr->filter('filter1')
        ->field('field')
        ->condition('like%')
   ->filter('filter2')
        ->condition('=')
        ->field('field2')
        ->applyIf(function($filters, $condition){return true;})//just an example
   ->filter('filter3')
        ->condition('>=')
        ->field('field3')
        ->applyIfPresent('filter1','filter2')
        ->defaultValue(3)
   ->filter('filter4','=','field4')
        ->applyIfNotPresent(['filter1','filter3'])
        ->defaultValue(3)
   ;

//defaultValue

Removing a filter

To remove a filter definition use the removeFilter function of the ResourceQuery class or the remove function on the filter. Optionally filters can be removed via the unset function on the filters parameter

$qr->removeFilter('filter-name');
//Or
$qr->filter('filter-name2')->remove();
//Or
unset($qr->filters['filter-name3']);

To remove all filter definitions you can use the removeFilters function of ResourceQuery class or the removeAll function of the filters parameter

$qr->removeFilters();
//Or
$qr->filters->removeAll();

Checking for filter existance

To check if a filter is defined use the filterExists function of ResourceQuery class or check via isset function on the filters parameter

$qr->filterExists('filter-name');
// Or
isset($qr->filters['filter-name']);

Getting a filter

To return a filter definition if present (without creating it if not present like with the filter function) you can access the filters parameter of ResourceQuery like an array

$filter = $qr->filters['filter-name'];
// can contain null or a FilterCondition instance
Clone this wiki locally