Construct reusable & cacheable Eloquent queries with custom filters.
You can install the package via composer:
composer require sfneal/datum
The Query abstract class requires a builder()
& execute()
method must be implemented. The builder()
method retrieves a
Builder instance for constructing the query (useful for adding or removing scopes). The execute()
method is where the
remainder of the query params can be added. Expected return type is a Builder but this can be overwritten to be a
Collection, array, string, etc. In this case we're using the HasKeyParam to accept a $modelKey
param in the Query's
__construct method.
use Illuminate\Database\Eloquent\Builder;
use Sfneal\Queries\Query;
use Sfneal\Queries\Traits\HasKeyParam;
class PeopleQuery extends Query
{
use HasKeyParam;
/**
* Retrieve a Query builder.
*
* @return Builder
*/
protected function builder(): Builder
{
return People::query();
}
/**
* Execute a DB query.
*
* @return Builder
*/
public function execute(): Builder
{
return $this->builder()
->where('person_id', '=', $this->modelKey);
}
}
// Example use
$model = (new PeopleQuery($id))->execute()->get()
The FilterableQuery abstract class extends the previously mentioned Query abstract class while providing additional
functionality by using Filters. The execute
method that is required by the abstract Query is pre-defined but a
builder
method must still be implemented. Additionally, FilterableQuery requires a queryFilters()
method be
implemented that returns an array of Filter classes that can be used to add predefined filters to a query.
Before creating a FilterableQuery extension, the Filters that Query will use should be created.
use Illuminate\Database\Eloquent\Builder;
use Sfneal\Filters\Filter;
class NameLastFilter implements Filter
{
/**
* Apply a given search value to the builder instance.
*
* @param Builder $query
* @param mixed $value
* @return Builder $query
*/
public function apply(Builder $query, $value): Builder
{
$query->whereIn('name_last', (array) $value);
return $query;
}
}
class CityFilter implements Filter
{
/**
* Apply a given search value to the builder instance.
*
* @param Builder $query
* @param mixed $value
* @return Builder $query
*/
public function apply(Builder $query, $value): Builder
{
$query->whereIn('city', (array) $value);
return $query;
}
}
Now that we've created our Filters, a FilterableQuery extension can be created that uses them.
use CityFilter;
use NameLastFilter;
use Sfneal\Queries\FilterableQuery;
class PeopleFilterableQuery extends FilterableQuery
{
/**
* Retrieve a Query builder.
*
* @return Builder
*/
protected function builder(): Builder
{
return People::query();
}
/**
* Retrieve an array of model attribute keys & corresponding Filter class values.
*
* @return array
*/
protected function queryFilters(): array
{
return [
'city' => CityFilter::class,
'name_last' => NameLastFilter::class,
];
}
}
With the FilterableQuery finally created, we can pass filter params to it and receive results.
$filters = [
'name_last' => 'Brady'
'city' => 'Brookline',
];
$results = (new PeopleQueryWithFilters($filters))->execute()->get();
Since we built the Filter implementations to mutate filter $values to arrays, we can pass an array of valid filters to retrieve more results.
$filters = [
'name_last' => [
'Neal',
'Brady',
],
'city' => [
'Brookline',
'Boston',
],
];
$results = (new PeopleQueryWithFilters($filters))->execute()->get();
composer test
Please see CHANGELOG for more information what has changed recently.
Please see CONTRIBUTING for details.
If you discover any security related issues, please email stephen.neal14@gmail.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.
This package was generated using the PHP Package Boilerplate.