nmihaylov's avatar

Laravel 11 - custom validation rule alias

I am using laravel 11 and I have checkbox question with 4 options. I get the data in this way:

"Q3" => array:4 [▼
    "r1" => "0"
    "r2" => "1"
    "r3" => "1"
    "r4" => "0"
]

I need to validate if the number of the checked boxes is in specific range (example min 2 have to be clicked - have 1 as value) I can't use the default validation rules for my case due various reasons so I created custom one:


namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Translation\PotentiallyTranslatedString;
class CheckboxMin implements ValidationRule
{
    private $limit;
    public function __construct($limit = 1)
    {
        $this->limit = $limit;
    }
    public function __toString(): string
    {
        return 'checkbox_min';
    }
    /**
     * Run the validation rule.
     *
     * @param  Closure(string): PotentiallyTranslatedString  $fail
     */
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (!is_array($value)) {
            $fail("The {$attribute} must be an array.");
        }
        $filtered_array = array_filter(array_values($value)); // converts to array of values and removes all the zeros
        if ($this->limit && count($filtered_array) < $this->limit) {
            $row_rows = $this->limit == 1 ? 'row' : 'rows';
            $fail("Please select at least {$this->limit} {$row_rows} for {$attribute}.");
        }
    }
}

I would like to set alias name to this rule so afterwards I can set a custom error message.

    $request->validate([
        'Q3' => 'required|my_rule',
    ],[
        'Q3.my_rule' => 'My custom message',
    ]);

In previous version of laravel until laravel 10 you can register this custom rules by extending the Validator class in AppServiceProvider.php class like this:

Validator::extend('my_rule', CheckboxMin::class);

But in the latest version laravel 11, this Rule class is deprecated and the validation rules are extending ValidationRule contract instead of Rule and the method with extending the Validator is not working anymore and throws us this message:

App\Rules\CheckboxMin::validate(): Argument #3 ($fail) must be of type Closure, array given, called in /Users/nmihaylov/Projects/css/vendor/laravel/framework/src/Illuminate/Validation/Validator.php on line 1618

Does anyone know how to set an alias for my custom rule so I can set a custom error message?

0 likes
2 replies
s4muel's avatar

i dont know a way of aliasing, and it really seems it is a dead end with the Validator::extend() (https://github.com/laravel/framework/pull/48484#issuecomment-1729628841)

but cant you just simply tweak your custom validation class and add an optional message parameter directly to the constructor?

class CheckboxMin implements ValidationRule
{
    private $limit;
    private ?string $message;

    public function __construct($limit = 1, ?string $message = null)
    {
        $this->limit = $limit;
        $this->message = $message;
    }

and then in the validate() using that message?

//...
$fail($this->message ?? 'fallback error message');

then in the controller/form request just use the rule like this:

$request->validate([
    'Q3' => ['required', new CheckboxMin(1, 'customized error message'),
]);
2 likes
nmihaylov's avatar

lol, thanks! This seems like a clever workaround indeed! Somehow I was hoping for more natural Laravel way for this issue but I'm not able to find anything on that subject :(

Please or to participate in this conversation.