@@ -435,21 +435,54 @@ $errors = Query::validate($queries, ['name', 'age', 'status']);
435435[$limit, $offset] = Query::page(3, 10);
436436```
437437
438- ** Pluggable extensions ** — customize attribute mapping, identifier wrapping, and inject extra conditions :
438+ ** Hooks ** — extend the builder with reusable, testable hook classes for attribute resolution and condition injection :
439439
440440``` php
441+ use Utopia\Query\Hook\AttributeMapHook;
442+ use Utopia\Query\Hook\TenantFilterHook;
443+ use Utopia\Query\Hook\PermissionFilterHook;
444+
441445$result = (new Builder())
442446 ->from('users')
443- ->setAttributeResolver(fn(string $a) => match($a) {
444- '$id' => '_uid', '$createdAt' => '_createdAt', default => $a
445- })
447+ ->addHook(new AttributeMapHook([
448+ '$id' => '_uid',
449+ '$createdAt' => '_createdAt',
450+ ]))
451+ ->addHook(new TenantFilterHook(['tenant_abc']))
446452 ->setWrapChar('"') // PostgreSQL
447- ->addConditionProvider(fn(string $table) => [
448- "_uid IN (SELECT _document FROM {$table}_perms WHERE _type = 'read')",
449- [],
450- ])
451453 ->filter([Query::equal('status', ['active'])])
452454 ->build();
455+
456+ // SELECT * FROM "users" WHERE "status" IN (?) AND _tenant IN (?)
457+ // bindings: ['active', 'tenant_abc']
458+ ```
459+
460+ Built-in hooks:
461+
462+ - ` AttributeMapHook ` — maps query attribute names to underlying column names
463+ - ` TenantFilterHook ` — injects a tenant ID filter (multi-tenancy)
464+ - ` PermissionFilterHook ` — injects a permission subquery filter
465+
466+ Custom hooks implement ` FilterHook ` or ` AttributeHook ` :
467+
468+ ``` php
469+ use Utopia\Query\Condition;
470+ use Utopia\Query\Hook\FilterHook;
471+
472+ class SoftDeleteHook implements FilterHook
473+ {
474+ public function filter(string $table): Condition
475+ {
476+ return new Condition('deleted_at IS NULL');
477+ }
478+ }
479+
480+ $result = (new Builder())
481+ ->from('users')
482+ ->addHook(new SoftDeleteHook())
483+ ->build();
484+
485+ // SELECT * FROM `users` WHERE deleted_at IS NULL
453486```
454487
455488### ClickHouse Builder
0 commit comments