Download the PHP package dowob/laravel-refiner without Composer
On this page you can find all versions of the php package dowob/laravel-refiner. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download dowob/laravel-refiner
More information about dowob/laravel-refiner
Files in dowob/laravel-refiner
Package laravel-refiner
Short Description Refine Laravel Eloquent queries from request data according to the refinement you choose.
License MIT
Informations about the package laravel-refiner
Refine Laravel Eloquent queries
The aim of the package is to provide simple yet flexible filtering to your Eloquent models from query parameters in the
request. You create a refining class that extends \Dowob\Refiner\Refiner
and specify the filter definitions that are
applicable to that refiner. This allows refiners to be re-used throughout your application.
Please read through the Caveats section to ensure this package is suitable for you. This was built to meet my needs which means it won't fit all use cases.
Installation
Run the following to install the package with composer:
Some minimal configuration options are available if you wish to publish the configuration file. The service provider will be registered automatically within Laravel.
Refinable Models
A model must use the trait \Dowob\Refiner\Refinable
to enable refinement on the model.
Refining a model
You can then refine the query by calling refine()
:
As refine()
is a scope, it can be combined with any other calls on the model (scopes, query builder methods,
pagination etc.).
The refine()
method has two optional arguments:
?\Dowob\Refiner\Refiner $refiner = null
if specified, this is the refiner instance you want to use for this refinement. If not specified, it will be automatically determined from the model name and the configured refiner namespace (defaults to\App\Refiners
). For example, the guessed refinerPost
would be\App\Refiners\PostRefiner
.?\Illuminate\Http\Request $request = null
if specified, this will be used as the request object to retrieve query parameters from. Otherwise, we'll use the current request to retrieve the parameters.
Refiners
A refiner defines what refinement is allowed (filters & sorting). This is achieved by specifying
Definitions in a refiner. The refiner will be automatically used if it matches the naming
convention of
ModelNameRefiner
, i.e. PostRefiner
, unless you have specifically passed an instance of a refiner to the refine()
method.
A refiner is typically for a specific model, but you may want to create multiple refiners for a model too. For example,
you may want to use a UserPostRefiner
for when a user is viewing/filtering their specific posts, and you may have
a PostRefiner
that is for anyone to search any posts.
Creating a Refiner
Generate a refiner using the artisan command php artisan make:refiner NameOfYourRefiner
.
Definitions
To make use of a refiner, you'll want to add one or more definitions to it in the definitions()
method. Each
definition must have a name
(passed in the make
method), but everything else is optional. The name
is how the
definition matches up to the request[^1], for example a definition with a name of email
would be triggered by a
request like: ?search[email]=value
. The name
will also be used for the query column, unless you define a
different column through column()
.
[^1]: Unless you use validation rules that cover multiple fields, then those field names will be used instead of the definition name.
You must opt the Definition into search and/or sorting, which is done by calling one of the search*
methods or the
sort
method.
You can specify validation rules for each definition which allows further complexity in how your definitions work.
Examples of definitions being defined within a refiner:
Validation
You can add validation rules to a definition by calling validation($rules)
. By default, basic validation rules
will be added automatically depending on how the definition is configured:
required
unless the definition is set to always run, in which case it would havenullable
array
if using asearchIn()
search filter.
Validation rules use the power of Laravel's validation system:
If specifying a custom search handler via searchCustom($closure)
, you can unlock more powerful use cases for
search filters. For example, if you had a date filter that needed to rely on two fields (start
and end
) within
one definition, you can do:
Note: It's important to know that multiple fields will not work unless you're using
searchCustom
orsearchIn
, as array values are rejected for other search types to prevent array values being passed to methods expecting singular values (i.e. exact match search).
Default sorts
You may want to apply default sorting to your query when there are no sorts specified in the request. This can be
done by specifying an array within the defaultSorts
method, containing one or more sorts to apply if no sorts are
present.
Refiner Registry
When a refiner is created due to no refiner being passed to refine()
, the package registers it in the registry for
you to retrieve (if needed). If you don't need the refiner instance, you can ignore the registry. You may need the
refiner instance if you wish to check what sorts are active in the current request (i.e. for inverting sort links
based on current sort), or what searches are active & the values that were used (i.e. for pre-filling forms), or
using the query()
method to retrieve the validated query parameters (i.e. for pagination ->appends()
method).
Note: The refiner is a singleton, which means you may need to reset its state in long-running applications serving multiple requests like those running on Laravel Octane.
Refiners are added to the registry in the order they are registered via refine()
, and when retrieving a refiner it
is removed from the registry.
You can use the Facade to access the singleton: \Dowob\Refiner\Facades\Registry
.
The below methods are the ones you'll need to know if using the registry.
Both pop
and shift
accept two optional parameters, the class-name of a Refiner
and the class-name of a Model
.
Passing either of these parameters will filter the pop
or shift
action to only refiners registered for that
match those parameters specified.
Example of using optional parameters for registry methods:
Caveats
- This package does NOT support filter combinations other than AND, unless they are within a custom search filter (but that would be AND'd with any other active filters).
- Whilst multiple refiners in a single request is supported, if the definitions have conflicting names then you may
get unexpected results (as both refiners would, if the data validates to their definitions, use them).
- Definition names within a refiner must be unique, this will likely be enforced in a later version.
- If validating multiple fields in one definition, you must pass the definition name to
getSearchValue($name)
which will return an array of values for any fields that passed validation in that definition. You cannot call the fields by their name ingetSearchValue($name)
but could do something likegetSearchValue($name)[$field] ?? null
TODO
- [ ] Refining
- [ ] search via basic relationship
whereHas
to reduce need forsearchCustom
callbacks that achieve the same result- [ ] potential grouping of same relationship queries for better performance
- [ ] search via basic relationship
All versions of laravel-refiner with dependencies
illuminate/database Version ^9.0|^10.0|^11.0
illuminate/http Version ^9.0|^10.0|^11.0
illuminate/validation Version ^9.0|^10.0|^11.0
illuminate/support Version ^9.0|^10.0|^11.0
spatie/laravel-package-tools Version ^1.12