Download the PHP package omoba/laravel-queryable without Composer
On this page you can find all versions of the php package omoba/laravel-queryable. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package laravel-queryable
laravel-queryable
Declarative search, filter, and sort scopes for Eloquent models — with first-class support for relationship traversal via dot notation.
→ Full documentation
Requirements
- PHP 8.2+
- Laravel 10, 11, or 12
Installation
The service provider is auto-discovered. Optionally publish the config:
Quick start
Add the Queryable trait to your model and implement the three declaration methods:
Then in your controller:
Traits
Use Queryable for all three features, or mix in individual traits:
| Trait | Scopes added |
|---|---|
Queryable |
search, searchEncrypted, filter, filterHaving, sort |
Searchable |
search, searchEncrypted |
Filterable |
filter, filterHaving |
Sortable |
sort |
Each trait requires you to implement its declaration method(s). The compiler will tell you which ones are missing.
Declaration methods
searchable(): array
Required by Searchable. Return column names (or dot-notation relation paths) to include in substring search.
searchableEncrypted(): array
Optional — defaults to []. Columns that store SHA-256 hashed values. Used by searchEncrypted().
hashSearchTerm(string $term): string
Optional override. Defaults to hash('sha256', $term). Override to change the hashing strategy.
filterable(): array
Required by Filterable. Maps field names to filter operators. Three declaration styles:
When no operator is declared, the package infers one: an array with from/to keys becomes between; anything else becomes exact.
Dot notation works the same as in searchable():
having(): array
Optional — defaults to []. Same shape as filterable(), but for columns in a HAVING clause (e.g. aggregates from withCount / selectRaw). Used by filterHaving().
sortable(): array
Required by Sortable. An indexed list of column names permitted for sorting.
Scopes
search(?string $term)
Case-insensitive substring match across all columns declared in searchable(). Columns in related tables use orWhereHas. Returns the unmodified query if $term is null or empty.
Uses ILIKE on PostgreSQL and LIKE on all other drivers.
searchEncrypted(?string $term)
Hashes $term (default: SHA-256) and performs an exact match against columns in searchableEncrypted(). Returns the unmodified query if $term is null or empty.
filter(?array $filters)
Applies WHERE clauses for each key in $filters against the filterable() map. Silently skips null and empty-string values.
filterHaving(?array $filters)
Same as filter() but emits HAVING clauses. Use after aggregating with withCount, selectRaw, etc.
sort(string|array|null $spec)
Applies ORDER BY for each field in $spec. The field must be declared in sortable(). Returns the unmodified query on null or empty input.
Filter operators
| Operator | Enum constant | Value shape | SQL |
|---|---|---|---|
exact |
FilterOperator::Exact |
'foo' · 'a,b,c' · ['a','b','c'] |
= ? or IN (...) |
like |
FilterOperator::Like |
'foo' |
LIKE '%foo%' |
in |
FilterOperator::In |
'a,b,c' · ['a','b','c'] |
IN (...) |
between |
FilterOperator::Between |
['from' => x, 'to' => y] (each side optional) |
BETWEEN · >= · <= |
date_range |
FilterOperator::DateRange |
same as between, parsed as Carbon dates |
BETWEEN · >= · <= |
null |
FilterOperator::Null |
(no user value needed) | IS NULL |
gt |
FilterOperator::Gt |
scalar | > ? |
gte |
FilterOperator::Gte |
scalar | >= ? |
lt |
FilterOperator::Lt |
scalar | < ? |
lte |
FilterOperator::Lte |
scalar | <= ? |
Value sentinels
Any field — regardless of its declared operator — recognises two special string values:
| Sent value | SQL emitted |
|---|---|
'null' |
IS NULL |
'not_null' |
IS NOT NULL |
This lets API clients check for nullability without a separate endpoint:
CSV shorthand
For exact and in operators, a comma-separated string expands to an IN clause:
Relationship traversal
Dot notation in searchable() and filterable() traverses Eloquent relations of any depth. The package uses whereHas / orWhereHas internally:
Relation sorting is not supported in this version — it requires joins that risk duplicate rows and column-name collisions. Use a raw orderBy with an explicit join if you need it.
Strict mode
By default, an unknown key in filter() / filterHaving() / sort() throws an exception.
| Exception | Thrown when |
|---|---|
InvalidFilterField |
Key not declared in filterable() / having() |
InvalidSortField |
Field not declared in sortable() |
Disable strict mode to silently skip unknown keys — useful for public APIs where clients may send extra parameters:
Chaining with native Eloquent
All scopes return the builder, so they compose freely with any Eloquent method:
HAVING example
Full model example
Controller:
Example requests:
Comparison with spatie/laravel-query-builder
Spatie's package is broader in scope (filters, fields, includes, sorts, custom filters). This package takes a different approach:
- Model-side declaration —
filterable(),sortable(),searchable()live on the model, not in a fluent chain at the call site. - First-class
searchas its own concept, distinct from a filter. - No request coupling — scopes accept plain PHP values, not a
Requestobject.
Pick whichever fits your team's mental model.
Testing
License
MIT
All versions of laravel-queryable with dependencies
illuminate/database Version ^10.0|^11.0|^12.0
illuminate/support Version ^10.0|^11.0|^12.0