Reputation: 499
Is it possible to use existing Laravel validation rules in a custom rule?
Example: required|string|max:100
I just want to group these rules in one rule custom_rule_name
.
Either this way
Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
return $value == 'required|string|max:100';//something like this
});
or
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Uppercase implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return $value == 'required|string|max:100';//something like this
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The :attribute must be uppercase.';
}
}
Let me know if there is any possibility?
Thanks,
Kaleem
Upvotes: 2
Views: 1941
Reputation: 71
I know this question is quite outdated, but it may help others. I just figured out the probably most simple way of grouping validation rules in Laravel without any extras or any magic. (just came into my mind on a toilet session)
Simply create a Groups
class with static methods where you can group your rules, e.g.:
<?php
namespace App\Rules;
class Groups
{
public static function email(): array
{
return ['string', 'email:strict,dns,spoof,filter', new EmailLocalpart, 'max:255'];
}
}
(this example also uses one of custom rules EmailLocalpart
which makes email validation even stricter by only allowing specific characters in the local part)
Then, simply use it in your validator or FormRequest:
public function rules()
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => Groups::email(),
];
}
and if you want to combine it with other rules, simply spread the array into an existing one, just mix in your email rules:
<?php
namespace App\Http\Requests;
use App\Rules\Groups;
use Illuminate\Foundation\Http\FormRequest;
class CreateContactRequest extends FormRequest
{
public function rules()
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', ...Groups::email(), 'unique:contacts'],
];
}
}
The spread operator was already introduced in PHP 7.4, so nothing should hold you back using it for this use case.
You can use a single Groups
class where you set up all your grouped rules, and you can spread them anywhere you wish. Don't think it can get any simpler than this, as long as there is no Laravel built-in support for it.
Cheers, Philip
Upvotes: 1
Reputation: 582
You could use the Validator
facade inside the passes()
function. Like this:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\Validator;
class Uppercase implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
$validator = Validator::make([$attribute => $value], [
$attribute => 'required|string|max:100',
]);
return !$validator->fails();
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The :attribute must be uppercase.';
}
}
Upvotes: 3
Reputation: 3030
No, the correct way to do this would be to choose each rule when validating the request, not to create one rule that contains all of the logic.
Upvotes: 0