framework icon indicating copy to clipboard operation
framework copied to clipboard

[12.x] Stops validation if a custom rule specifies it

Open peterfox opened this issue 9 months ago • 6 comments

Changes

  • Adds a Illuminate\Contracts\Validation\StopUponFailure contract.
  • Changes \Illuminate\Validation\Validator::shouldStopValidating() to accept two arguments, the new one being the rule
  • Changes \Illuminate\Validation\Validator::shouldStopValidating() to check if it's an invokable rule and if the custom rule it's using implements the Illuminate\Contracts\Validation\StopUponFailure contract.

Why

This would allow for more control over when validation rules fail and when they should continue. Instead of only relying on bail when one rule can trigger a failure to run all further attributes.

Example use:

class RunAntiVirusScan implements ValidationRule, StopUponFailure
{
    public function shouldStop(): bool
    {
        return true;
    }

    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if ($scan->fails()) {
            $fail(':attribute is not safe');
        }
    }
}
$request->validate([
    'image' => ['image', new RunAntiVirusScan(), 'max:1024'],
]);

peterfox avatar Feb 16 '25 13:02 peterfox

It feels a bit odd to have an interface called StopUponFailure but then have to implement a method which presumably will almost always return true. 🤔

taylorotwell avatar Feb 17 '25 17:02 taylorotwell

@taylorotwell I did consider that It could just be an interface. The user might want to force that condition only in circumstances based on whether they felt it was risky or not to continue validation of that field was where my mind was at. I'm thinking where using AI/ML and you've got a score from a service and don't want to continue processing a file further.

Maybe a new name for the interface would help. MightStop as such for the interface and then a shouldStop method.

peterfox avatar Feb 17 '25 17:02 peterfox

Maybe a new name for the interface would help. MightStop as such for the interface and then a shouldStop method.

What about Stoppable?

shaedrich avatar Feb 17 '25 17:02 shaedrich

We use the term bail in other parts for rules, so maybe Bailable or IsBailable gives better context

jmarcher avatar Feb 18 '25 08:02 jmarcher

Why not name it: StopOnFailure and check if you implemented the empty interface, if so.. Stop on failure then.

flavio-schoute avatar Feb 18 '25 15:02 flavio-schoute

I think @flavio-schoute is the best solution. We can later add Bailable interface that allows a method for conditional bail?

henzeb avatar Feb 22 '25 10:02 henzeb