1. Go to this page and download the library: Download teoprayoga/laravel-teorion library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
teoprayoga / laravel-teorion example snippets
use Teoprayoga\Teorion\Filters\Filter;
use Teoprayoga\Teorion\QueryFilter;
class PostQueryFilter extends QueryFilter
{
protected array $defaultSort = ['-created_at'];
public function filters(): array
{
return [
'search' => Filter::multiLike(['title', 'description']),
'status' => Filter::enum('status', StatusEnum::class),
'is_active' => Filter::boolean()->default(true),
'created_by' => Filter::exact(),
'has_image' => Filter::has('image'),
];
}
public function allowedScopes(): array
{
return ['published', 'popular'];
}
public function allowedWiths(): array
{
return ['author', 'comments', 'tags'];
}
public function allowedWithCounts(): array
{
return ['comments', 'reactions'];
}
public function allowedSorts(): array
{
return ['created_at', 'title', 'view_count'];
}
}
use Teoprayoga\Teorion\Traits\Filterable;
class Post extends Model
{
use Filterable;
// Existing scopeXxx() methods stay here — whitelist controls which are exposed.
}
class Post extends Model
{
use Filterable;
protected string $queryFilter = CustomPostQueryFilter::class;
}
use Teoprayoga\Teorion\QueryFilter;
class Post extends Model
{
use Filterable;
public function newQueryFilter(): QueryFilter
{
return new PostQueryFilter();
}
}
public function index(GetRequest $request): mixed
{
return Post::query()->filterAndPaginate($request);
// ^^^^^^^^^^^^^^^^^^^^^^^^
// applies all filters, scopes, withs, sorts,
// and terminates with paginate() or get()
}
public function show(GetRequest $request, string $uuid): mixed
{
return Post::findFiltered($request, $uuid);
}
// AppServiceProvider::boot()
FilterMacroRegistry::register('phone', function ($q, $value, $param) {
return $q->where($param, preg_replace('/\D/', '', $value));
});
// In QueryFilter
'phone_number' => Filter::macro('phone'),
// Controller
use Teoprayoga\Teorion\Attributes\UsesQueryFilter;
class PostController
{
#[UsesQueryFilter(PostQueryFilter::class)]
public function index(GetRequest $request): JsonResponse { ... }
}
use Teoprayoga\Teorion\Concerns\HasQueryFilterRules;
class GetRequest extends FormRequest
{
use HasQueryFilterRules;
protected string $queryFilter = PostQueryFilter::class;
public function rules(): array
{
return array_merge($this->queryFilterRules(), [
// your custom rules
]);
}
}
use Teoprayoga\Teorion\Fingerprint\AlgorithmInterface;
use Teoprayoga\Teorion\Fingerprint\AlgorithmRegistry;
AlgorithmRegistry::register(new class implements AlgorithmInterface {
public function name(): string { return 'blake3'; }
public function hash(string $payload): string { return hash('blake3', $payload); }
});
Post::query()->filterAudited($request)->where('extra', $val)->get();
// → QueryAudited dispatched with terminal_mode='get'
class PersistQueryAudit
{
public function handle(QueryAudited $event): void
{
QueryAuditLog::create([
'fingerprint_hash' => $event->record['fingerprint']['hash'],
'filter_class' => $event->record['filter_class'],
'duration_ms' => $event->record['duration_ms'],
'user_id' => $event->record['user_id'],
'recorded_at' => now(),
]);
}
}
Event::listen(QueryAudited::class, function (QueryAudited $event) {
if ($event->record['duration_ms'] > 500) {
Notification::route('slack', config('alerts.slack_webhook'))
->notify(new SlowQueryAlert($event->record));
}
});