Download the PHP package mohammad-fouladgar/eloquent-builder without Composer
On this page you can find all versions of the php package mohammad-fouladgar/eloquent-builder. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package eloquent-builder
Eloquent Builder
If you are upgrading from v5 to v6, see UPGRADE.md.
Build clean, reusable, request-driven Eloquent queries in Laravel.
Eloquent Builder lets you map incoming request parameters to reusable Eloquent filters without filling your controllers with conditional query logic.
Current release: v6 PHP: 8.3+
Why Eloquent Builder?
Filtering an Eloquent query can quickly become difficult to maintain when every request parameter requires its own conditional logic:
With Eloquent Builder, the filtering logic can live in dedicated filter classes or lightweight Quick Filters:
Your controllers stay focused on application flow while query-specific logic stays inside filters.
Table of Contents
- Installation
- Quick Start
-
Filters
- Defining a Filter
- Generating Filters with Artisan
- Using Filters
- Fluent Usage
-
Quick Filters
- Exact
- Partial
- Scope
- Callback
- Trashed
- Includes
- Fields
- Quick Filter Precedence
- Filter Groups
- Defaults and Ignored Values
-
Predefined Filters
- Date Filters
- Number Filters
- Sort Filters
- Authorization
- Missing Filter Behavior
- Ignoring Empty and Null Values
- Custom Filter Namespaces
- Dependency Injection
- Choosing the Right Filter
- Testing
- Contributing
- Security
- License
Installation
Install the package via Composer:
Requirements
- PHP 8.3+
- Laravel Eloquent
Warning: The
Lumenframework is no longer supported.
Upgrading from v5
If you are upgrading an existing application from v5, see UPGRADE.md for breaking changes and new features introduced in v6.
Quick Start
Suppose your API accepts these filters:
Create an AgeMoreThanFilter:
Then apply the request filters:
The request key age_more_than is resolved to AgeMoreThanFilter.
For simple conditions, you can skip the filter class entirely and use a Quick Filter.
Filters
Defining a Filter
A filter is a class that extends:
The class must implement apply().
For example:
Filter classes should use the Filter suffix.
With the default namespace, filters for User live under:
For example:
Tip: You can use Laravel local scopes inside your filter classes as well.
Generating Filters with Artisan
Create a filter with:
You can generate multiple filters at once:
Using Filters
Model class
Existing query
You can start with an existing Eloquent query:
Programmatically adding filters
You can also push filter values directly:
When the same filter key is pushed more than once, the latest value takes precedence in v6.
Fluent Usage
For the common filters() use case, you can use the filter() macro directly on an Eloquent model or query:
It also works with an existing query:
This is the simplest way to apply standard filters without using EloquentBuilder::model().
For advanced features such as:
quickFilters()filterGroups()defaults()ignoreValues()
use the full EloquentBuilder API.
Tip: It is recommended to put filter parameters under a
filterrequest key:
Then access them through:
Quick Filters
Quick Filters are designed for simple filtering logic where creating a dedicated filter class would add unnecessary boilerplate.
Import:
Then define filters inline:
Quick Filter Reference
| Quick Filter | Purpose |
|---|---|
exact() |
Exact = comparison |
partial() |
LIKE %value% comparison |
scope() |
Apply an Eloquent local scope |
callback() |
Apply custom query logic |
trashed() |
Control soft-deleted records |
includes() |
Eager-load allowed relationships |
fields() |
Select allowed root-model columns |
Exact
Use exact() for a simple equality condition.
Request:
Equivalent query:
You can map the request key to a different column:
Request:
This applies:
Partial
Use partial() for a LIKE query:
Request:
Equivalent query:
You can also map the request key to a different column:
Scope
Use scope() when the filtering logic already exists as an Eloquent local scope.
For example:
Register the scope:
Request:
The corresponding local scope is invoked with the filter value.
If the request key and scope name are different:
This maps:
Callback
Use callback() when you need custom query logic but do not want to create a dedicated filter class.
Request:
The callback receives:
and can modify the query.
For complex or reusable filtering logic, prefer a class-based filter.
Trashed
trashed() provides filtering for models using Laravel's SoftDeletes trait.
The default request key is:
Include trashed records
Equivalent to:
Only trashed records
Equivalent to:
Any other value uses the default behavior and excludes trashed records.
You can customize the request key:
Warning:
QuickFilter::trashed()requires Laravel'sSoftDeletestrait. Usingwithoronlywith a model that does not support soft deletes results in aBadMethodCallException.
Includes
includes() lets clients request eager-loaded relationships while restricting them to an explicit whitelist.
Request:
The query will eager-load the requested allowed relationships.
The request may also provide an array:
Whitelisting
Only relations present in the $allowed list are accepted.
For example:
allows:
but does not automatically allow:
Anything not present in the whitelist is ignored.
Fields
fields() lets clients request a limited set of columns from the root model.
Request:
The selected columns will include:
The primary key is always selected, even if it was not explicitly requested.
If none of the requested fields are allowed, only the primary key is selected.
Root model only
fields() currently applies only to the root model.
It does not provide relation-specific fieldsets such as:
Use a class-based filter or QuickFilter::callback() for more advanced selection logic.
Important: fields() uses select()
fields() calls Eloquent's select() method.
That means it replaces the query's existing column list.
Avoid combining it with another filter that also calls select().
If another filter needs to add columns after fields() has been applied, use addSelect() where appropriate.
Quick Filter Precedence
Quick Filters take precedence over class-based filters when they use the same request key.
For example:
takes precedence over a class-based StatusFilter for the same status key.
Note: Quick Filters do not support the
authorize()method available to class-based filters. Use a class-based filter when filter-level authorization is required.
Filter Groups
By default, filters are combined with AND.
For example:
normally produces:
Use FilterGroup::or() to combine a group of filter keys with OR:
The same request now produces:
Filter groups can contain:
- class-based filters
- Quick Filters
- a combination of both
Only filter keys that are present in the request are applied.
If only one member is present, it behaves like a normal filter.
If none are present, the group is skipped.
Filters inside groups
Filter groups are intended for filters that add normal where constraints.
Good candidates include:
Avoid putting filters that change the overall query structure inside an OR group, especially filters that:
or otherwise modify query state outside the nested where condition.
QuickFilter::trashed() should also be used outside filter groups.
Defaults and Ignored Values
Defaults
Use defaults() when a filter should receive a value if none is provided.
If the request does not contain filter[status], the default value is used.
An explicitly provided value takes precedence over the default.
Ignored Values
Use ignoreValues() when a specific incoming value should be treated as if the filter was not provided.
This is useful for UI sentinel values such as:
Example:
The value all is ignored.
You can combine ignored values with defaults:
Now:
Values are compared as strings, so:
also matches an incoming '0'.
Note:
defaults()only applies when the filter has no value after processing. A non-empty value that happens to contain no allowed items does not automatically trigger the default.
Predefined Filters
Eloquent Builder provides reusable traits for common filtering requirements:
- Date filtering
- Number filtering
- Sorting
Date Filters
Use FiltersDatesTrait for date-based filters.
Supported conventions:
Date Examples
Date Between
These forms can be used for a range:
Date Equals
These forms represent equality:
Defining a date filter
Number Filters
Use FiltersNumbersTrait for numeric filters.
Supported conventions:
Number Examples
Number Between
or:
or:
Number Equals
or:
Defining a number filter
Sort Filters
Use SortableTrait to expose a controlled set of sortable columns.
For example:
You can also use:
If no direction is specified, asc is used:
Defining a sort filter
Only columns listed in $sortable can be requested by the client.
Custom sort resolvers
A sortable key can map to a custom closure instead of a direct database column.
For example, sorting by the number of posts:
Request:
The resolver receives the builder and sort direction and should mutate the provided builder.
Note: The resolver's return value is ignored. Returning a different
Builderinstance does not replace the current query.
Default sorting
Combine SortableTrait with defaults() to apply a default sort:
Authorization
Class-based filters can implement authorize() when filter-level authorization is required.
For example:
If authorize() returns false, the filter is rejected through Laravel's authorization mechanism.
You do not need to implement authorize() when a filter does not require authorization.
Note: Authorization is performed for filters that are resolved and applied through the Eloquent Builder pipeline. Quick Filters do not provide an
authorize()method.
Missing Filter Behavior
By default, an incoming filter key without a matching Quick Filter or filter class throws a FilterException.
You can change this behavior in the published configuration:
With this option enabled, unrecognized filter keys are silently ignored.
This can be useful when a request payload contains additional parameters that are not intended to be filters.
Note: This only affects unrecognized keys. If a matching filter class exists but is not a valid
Filterinstance, that is still treated as an error.
Ignoring Empty and Null Values
Filter parameters with empty or null values are ignored.
For example:
Only the filter with a meaningful value is applied.
Custom Filter Namespaces
The default filter namespace is:
You can customize it by publishing the configuration:
Then configure:
Per-domain namespaces
For applications using domain-based structures, you can set the namespace for a specific query:
For example:
Note: When
setFilterNamespace()is used, the default namespace and configured namespace are ignored for that builder instance.
Dependency Injection
EloquentBuilder can be injected into a controller or another service.
For example:
Choosing the Right Filter
Use this as a quick decision guide:
| Requirement | Recommended API |
|---|---|
Simple = comparison |
QuickFilter::exact() |
Simple LIKE search |
QuickFilter::partial() |
| Existing Eloquent local scope | QuickFilter::scope() |
| One-off custom query logic | QuickFilter::callback() |
| Soft-delete filtering | QuickFilter::trashed() |
| Client-controlled eager loading | QuickFilter::includes() |
| Client-controlled root columns | QuickFilter::fields() |
| Reusable or complex logic | Class-based Filter |
| Filter-level authorization | Class-based Filter |
| OR conditions | FilterGroup::or() |
| Date comparisons | FiltersDatesTrait |
| Numeric comparisons | FiltersNumbersTrait |
| Controlled sorting | SortableTrait |
Testing
Run the test suite with:
Contributing
Please see CONTRIBUTING.md for details.
Security
If you discover a security-related issue, please email:
Please do not use the public issue tracker for security vulnerabilities.
License
Eloquent Builder is released under the MIT License.
See the LICENSE file for details.
Built with ❤️ for you.
All versions of eloquent-builder with dependencies
illuminate/database Version ^10.0|^11.0|^12.0|^13.0
illuminate/support Version ^10.0|^11.0|^12.0|^13.0