Download the PHP package teoprayoga/laravel-teorion without Composer
On this page you can find all versions of the php package teoprayoga/laravel-teorion. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download teoprayoga/laravel-teorion
More information about teoprayoga/laravel-teorion
Files in teoprayoga/laravel-teorion
Package laravel-teorion
Short Description Request-driven query filter package for Laravel โ formalized ScopeFilterTrait pattern with whitelist, isolated scope params, and single-call ViewModel support.
License MIT
Informations about the package laravel-teorion
Laravel Teorion
Request-driven query filter package for Laravel โ a formalized, secure replacement for ad-hoc query scope traits, with whitelist enforcement, isolated scope parameters, and single-call ViewModel integration.
Features
- ๐ฏ Declarative QueryFilter classes โ one per resource, central whitelist for filters/scopes/withs/sorts
- ๐ Whitelist enforcement โ no accidental scope/relation exposure to clients
- ๐ Isolated scope params โ
scopes[0][params][role_id]=3keeps params scoped without colliding with global request - ๐ Built-in filter types โ Exact, Like, MultiLike, Boolean, Null, Enum, In, Date, DateRange, Between, Range, GreaterThan, LessThan, Has, JsonContains, Callback, Scope
- ๐ Backward compatible โ supports legacy
scopes[]=nameformat alongside the new isolated-params format - ๐ Dual sort format โ Spatie-style
?sort=-col,col2AND legacy?order_by=...&order_direction=... - ๐๏ธ Auto soft delete handling โ
?with_trashed=1,?only_trashed=1work automatically on SoftDeletes models - ๐ Aggregation support โ
withCount,withSum,withAvg,withMax,withMinviawithAggregates[] - ๐ Cursor pagination โ switch to cursor-based paging via
?pagination=cursorfor large datasets / infinite scroll - ๐ Query audit & fingerprint โ deterministic SHA-256 fingerprint +
QueryAuditedevent for observability, cache key derivation, and N+1 detection - ๐ Fluent filter API โ
.alias(),.default(),.required()chainable - ๐งฐ Macro system โ register custom global filter types via
FilterMacroRegistry - ๐ Scribe integration โ auto-generate API docs from
#[UsesQueryFilter]attribute - โ
Validation rule generator โ
HasQueryFilterRulestrait auto-generates FormRequest rules
Requirements
- PHP 8.1+
- Laravel 10, 11, 12, or 13
| PHP Version | Laravel 10 | Laravel 11 | Laravel 12 | Laravel 13 |
|---|---|---|---|---|
| 8.1 | โ | โ | โ | โ |
| 8.2 | โ | โ | โ | โ |
| 8.3 | โ | โ | โ | โ |
| 8.4 | โ | โ | โ | โ |
Installation
(Service provider auto-discovers via Laravel package discovery.)
Quick Start
1. Generate a QueryFilter class
Creates app/QueryFilters/PostQueryFilter.php.
2. Declare your filters
3. Add the Filterable trait to your model
Three ways to bind a QueryFilter (pick one):
A. Convention (zero boilerplate) โ model Post auto-resolves to App\QueryFilters\PostQueryFilter:
B. Property override โ explicit, IDE-navigable:
C. Method override โ for dynamic resolution:
Customize the convention namespace in config/teorion.php:
4. Use in your ViewModel/Controller
Request Format
| Param | Example | Effect |
|---|---|---|
| Declared filter | ?search=lorem&status=published |
Each declared filter applied if param present |
scopes[] legacy |
?scopes[]=published |
Calls scopePublished($request) with full request |
scopes[N] new |
?scopes[0][name]=forStudent&scopes[0][params][role_id]=3 |
Calls scopeForStudent($scopedRequest) with isolated params |
withs[] |
?withs[]=author&withs[]=comments |
Eager loads (whitelist enforced) |
withCounts[] |
?withCounts[]=comments |
Count loads (whitelist enforced) |
withAggregates |
?withAggregates[comments][sum][]=score |
Sum/avg/max/min aggregates |
sort |
?sort=-created_at,title |
Spatie-style sort, multi-column |
order_by / order_direction |
?order_by=created_at&order_direction=desc |
Legacy single-sort |
is_paginate |
?is_paginate=1&per_page=20 |
Paginate vs get |
pagination |
?pagination=cursor&per_page=20 |
Cursor pagination mode (returns CursorPaginator) |
cursor |
?cursor=eyJpZCI6MTB9 |
Cursor token from previous response |
with_trashed |
?with_trashed=1 |
Auto-detected on SoftDeletes models |
only_trashed |
?only_trashed=1 |
Soft-deleted only |
visibles[] / hiddens[] |
?hiddens[]=password |
makeVisible / makeHidden on result |
Available Filter Types
| Filter | SQL |
|---|---|
ExactFilter |
WHERE col = ? |
LikeFilter |
WHERE col LIKE %?% |
MultiLikeFilter |
WHERE (col1 LIKE %?% OR col2 LIKE %?%) |
BooleanFilter |
WHERE col = 1/0 |
NullFilter |
WHERE col IS NULL / IS NOT NULL |
EnumFilter |
WHERE col = Enum::from(value)->value |
InFilter |
WHERE col IN (?, ?, ...) |
DateFilter |
WHERE DATE(col) = ? |
DateRangeFilter |
WHERE col BETWEEN ? AND ? |
BetweenFilter |
WHERE col BETWEEN ? AND ? (from single param value array) |
RangeFilter |
WHERE col >= ? AND col <= ? (from _min/_max) |
GreaterThanFilter |
WHERE col > ? (or >=) |
LessThanFilter |
WHERE col < ? (or <=) |
HasFilter |
WHERE EXISTS (relation) / NOT EXISTS |
JsonContainsFilter |
WHERE JSON_CONTAINS(col, ?) |
CallbackFilter |
Inline closure |
ScopeFilter |
Delegates to existing scopeXxx() on model |
Fluent API
Macros (Custom Filter Types)
Scribe Integration
Register the strategy in config/scribe.php:
Validation Rule Generator
Configuration
config/teorion.php (published via php artisan vendor:publish --tag=teorion-config):
strict_mode=trueโ throwsDisallowedScopeException/DisallowedWithException/ScopeMethodNotFoundExceptionon unlisted requestsstrict_mode=falseโ silently skips disallowed values (production-safe default)
Cursor Pagination
For large datasets or infinite-scroll UIs, switch from offset to cursor pagination:
The response is a CursorPaginator exposing next_cursor / prev_cursor tokens. Pass via ?cursor=<token> to navigate.
Cursor pagination requires a deterministic orderBy clause โ set one via $defaultSort in your QueryFilter (e.g., protected array $defaultSort = ['-id'];).
Query Audit & Fingerprint
Enable structured audit for every filterAndPaginate() and findFiltered() call:
Listen for the event:
The fingerprint is a deterministic SHA-256 hash of {filter_class, model_class, table, connection, normalized_parameters}. Parameters are recursively ksort-normalized so order doesn't change the hash. Useful for:
- Cache key derivation โ same intent โ same hash โ same cache entry
- N+1 detection โ duplicate hashes within one request indicate suspicious repetition
- Query analytics โ group slow queries by fingerprint to find optimization targets
Customize excluded parameters (defaults exclude page/cursor/CSRF tokens):
Fingerprint Algorithm Choice
The default is sha256 โ available without extensions, deterministic across PHP versions, fast enough (<1ยตs for typical request payloads). Hash itself is rarely the bottleneck โ json_encode and recursive ksort dominate.
Three built-in algorithms (v2.4+):
| Algorithm | Hash length | Speed (relative) | Notes |
|---|---|---|---|
sha256 |
64 hex | 1ร (baseline) | Default. Crypto-grade, but overkill for fingerprinting |
xxh3 |
16 hex | ~5โ10ร faster | PHP 8.1+ native via hash() |
xxh128 |
32 hex | ~3โ5ร faster | Collision-resistant alternative to xxh3 |
Switch via config or env:
Switching invalidates existing fingerprints โ derive cache keys with the algorithm prefix to make rotation safe: "query:{$result->algorithm}:{$result->hash}".
Custom algorithms (e.g., blake3 via ext-blake3) can be registered in your AppServiceProvider:
Sampling
For production scale (10k+ req/min), full-rate audit can flood the event bus. Use audit.sample_rate (0.0โ1.0):
Sampling is deterministic per fingerprint โ same query intent always produces the same audit decision (always-on or always-off). This is intentional: random sampling would break fingerprint-based cache dedup (same query might or might not be audited). Hash-based sampling keeps decisions consistent.
Audit Boundaries
The audit hook is wired to these teorion terminal methods:
| Terminal | Audited? | terminal_mode |
|---|---|---|
filterAndPaginate() |
โ | paginate / cursor / collection |
findFiltered() |
โ | find |
scopeFilter() (raw Builder) |
โ | โ |
scopeFilterAudited() (audited wrapper, v2.4+) |
โ | get / first / paginate / cursorPaginate / count |
| Direct Eloquent calls | โ | โ |
For audit on raw Builder chains, swap filter() โ filterAudited():
Listener Recipes
The package emits events; you decide persistence and side effects. Five patterns:
1. Persist to database โ your own audit log table:
2. Slack alert on slow queries (>500ms):
3. Redis dedup cache (memoize identical queries):
4. N+1 detection within request:
5. Sentry breadcrumb (low-overhead observability):
Testing
License
MIT
All versions of laravel-teorion with dependencies
illuminate/database Version ^10.0|^11.0|^12.0|^13.0
illuminate/http Version ^10.0|^11.0|^12.0|^13.0
illuminate/support Version ^10.0|^11.0|^12.0|^13.0