Middleware API
Reference for Warrant\WarrantMiddleware. Conceptual coverage is in
Route middleware.
The $target throughout is either a schema key (capability / no-model check)
or a route parameter name bound to a model (targeted check).
Building middleware strings
Section titled “Building middleware strings”public static function string( string $target, string|array $abilities, AbilityMatchMode $matchMode = AbilityMatchMode::ALL,): string;Produces a warrant:... middleware string, e.g. warrant:documents,view. The
match-mode segment (any / all) is inserted only when $matchMode isn’t the
default ALL:
WarrantMiddleware::string('document', 'view');// -> "warrant:document,view"
WarrantMiddleware::string('document', ['view', 'approve'], AbilityMatchMode::ANY);// -> "warrant:document,any,view,approve"Guarding a route group
Section titled “Guarding a route group”public static function guard( string $target, string|array $abilities, Closure $routes, AbilityMatchMode $matchMode = AbilityMatchMode::ALL,): void;WarrantMiddleware::guard('documents', 'view', function () { Route::get('/documents', [DocumentController::class, 'index']);});Standard-ability helpers
Section titled “Standard-ability helpers”Each takes the target and an optional route-group closure. With a closure they guard the group; without one they return the middleware string.
public static function canView(string $target, ?Closure $routes = null): ?string;public static function canCreate(string $target, ?Closure $routes = null): ?string;public static function canUpdate(string $target, ?Closure $routes = null): ?string;public static function canDelete(string $target, ?Closure $routes = null): ?string;public static function canArchive(string $target, ?Closure $routes = null): ?string;public static function canManage(string $target, ?Closure $routes = null): ?string;canView…canArchive map to the matching
StandardAbilities constant.
canManage uses the literal ability 'manage', which is not a standard
ability — declare it on the schema yourself.
Reachability guards
Section titled “Reachability guards”Guards backed by the reachability system —
a purely structural check that runs no conditions and no SQL. Each returns the
middleware string when called without a $routes closure, or guards the group
when given one.
public static function couldEver( string $target, string|array $abilities, ?Closure $routes = null, AbilityMatchMode $matchMode = AbilityMatchMode::ALL,): ?string; // passes when reachability !== NEVER
public static function always( string $target, string|array $abilities, ?Closure $routes = null, AbilityMatchMode $matchMode = AbilityMatchMode::ALL,): ?string; // passes when reachability === ALWAYS
public static function never( string $target, string|array $abilities, ?Closure $routes = null, AbilityMatchMode $matchMode = AbilityMatchMode::ALL,): ?string; // passes when reachability === NEVERThe aliases are warrant.could-ever, warrant.always, and warrant.never, each
with an .any variant for AbilityMatchMode::ANY (e.g. warrant.could-ever.any).
These guards are target-free: $target is a schema key or a schema/model
class, never a route parameter. The schema is resolved by key only (it
throws if the target isn’t a key), and the middleware abort(403)s when the
reachability predicate fails. See Reachability.
The middleware handler
Section titled “The middleware handler”public function handle( Request $request, Closure $next, string $target, string $matchModeOrFirstAbility, string ...$remainingAbilities,): Response;At request time it:
- Resolves
$targetas a schema key first. - Failing that, treats it as a route parameter name, resolves it to a model instance, and finds the schema from the model’s class.
- Reads the segment after the target:
all/anyis the match mode; anything else is the first ability. - Calls
userHasAbilitiesandabort(403)if unauthenticated or unauthorized.
Errors
Section titled “Errors”| Condition | Exception |
|---|---|
| No abilities supplied | InvalidArgumentException — “requires at least one ability.” |
| Route parameter isn’t a model instance | InvalidArgumentException — “must resolve to a model instance.” |
| Target resolves to no schema | InvalidArgumentException — “Unable to resolve access control schema for […]” |
| Unauthenticated / unauthorized | HTTP 403 |
