Skip to main content

AbortIfMapper

Aborts the entire bind if any existing bindable in the current boundary matches a condition. Unlike the per-bindable doIfInvalid(abort: true), these mappers scan all bindables at once and short-circuit the moment one matches.

FactoryAborts when any existing bindable is …
Mappers::abortIfInvalid()!isValid() — carries a validation error
Mappers::abortIfDirty()isDirty() — its value was changed during the bind

Both return a MapResult(false), which marks the TaskResult invalid and skips any mappers that follow them on the same prop. Non-existing bindables (!doesExist()) are skipped, so an optional prop that is absent never triggers an abort.

Note: abortIfInvalid is the cross-bindable counterpart of doIfInvalid(abort: true); use it when you want one guard to cover a whole props([...]) group rather than each prop individually.

Example: aborting when a prop is invalid​

$result = Bind::attrs(['prop' => 'holeradio'])->prop('prop',
Mappers::bindableClosure(function (Bindable $b) {
$b->addError(ValidationMessages::invalid());
}),
Mappers::abortIfInvalid(),
Mappers::value(function () { /* never reached */ }))
->toArray()->exec();
var_dump($result->isValid()); // false

Output:

bool(false)

The first closure marks prop invalid, so abortIfInvalid() aborts and the trailing value mapper never runs.

Example: aborting when a prop is dirty​

$result = Bind::attrs(['prop' => 'holeradio'])->prop('prop',
Mappers::bindableClosure(fn (Bindable $b) => $b->setDirty(true)),
Mappers::abortIfDirty(),
Mappers::value(function () { /* never reached */ }))
->toArray()->exec();
var_dump($result->isValid()); // false

Output:

bool(false)

When every bindable is clean (or merely valid, for abortIfInvalid), the mapper passes through and the bind continues normally — the trailing mappers run and the result stays valid.