Custom validation message for regex rule in Laravel? - php

Pretty basic question, I'm trying to customise the error message for a regex validation rule in Laravel. The particular rule is for passwords and requires the password to have 6-20 characters, at least one number and an uppercase and lowercase letter so I'd like to communicate this to the user rather than just the default message which says the format is "invalid".
So I tried to add the message into the lang file in a few different ways:
1)
'custom' => array(
'password.regex:' => 'Password must contain at least one number and both uppercase and lowercase letters.'
)
2)
'custom' => array(
'password.regex' => 'Password must contain at least one number and both uppercase and lowercase letters.'
)
3)
'custom' => array(
'password.regex:((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,20})' => 'Password must contain at least one number and both uppercase and lowercase letters.'
)
None of these have worked. Is there a way to do this?

I was able to solve this by using this method instead:
'custom' => array(
'password' => array(
'regex' => 'Password must contain at least one number and both uppercase and lowercase letters.'
)
)
but I'd love to know why one of the other methods didn't work if anyone happens to know...?

Well seems like laravel 7 solves this:
$messages = [
'email.required' => 'We need to know your e-mail address!',
'password.required' => 'How will you log in?',
'password.confirmed' => 'Passwords must match...',
'password.regex' => 'Regex!'
];
$rules = [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => [
'required',
'string',
'min:7',
'confirmed',
'regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\X])(?=.*[!$#%]).*$/'
]
];
return Validator::make($data, $rules, $messages );

Related

How can I set custom validation error messages from a controller, in Laravel 8?

I am working on a registration form with Laravel 8 and Sanctum.
I have this piece of code in the AuthController to validate the form fields:
public function register(Request $request) {
$fields = $request->validate([
'first_name' => 'required|string,',
'last_name' => 'required|string',
'email' => 'required|string|unique:users,email',
'password' => 'required|string|confirmed',
'accept' => 'accepted',
]);
// More code here
}
I want to display more user-friendly validation error messages.
Rather than changing the validation.php file (resources\lang\en\validation.php), I want to change the set them for the registration form only, in the method above.
The problem
As someone that has used Codeigniter for a long time, I had, in Codeigniter, the posibility to do just that:
$this->form_validation->set_rules('first_name', 'First name', 'required', array('required' => 'The "First name" field is required'));
I was unable to do something similar in Laravel 8.
How do I get the desired result in Laravel 8?
Maybe this can work for ya.
$rules = [
'first_name' => 'required|string,',
'last_name' => 'required|string',
'email' => 'required|string|unique:users,email',
'password' => 'required|string|confirmed',
'accept' => 'accepted'
];
$customMessages = [
'required' => 'The :attribute field is required.'
];
$this->validate($request, $rules, $customMessages);
Also check out the laravel customizing error messages documentation.
The validate function excepts 3 parameters. A) request, B) the rules, C) Custome Messages.
$this->validate($request, $rules, $customMessages); It means define your custom Message Array by key value. Key is the rulename like require. For example:
[
'required' => 'The :attribute is really,really, really required if you use Login!'
'email.required' => 'Without email you dont come in ;-)'
]

Apply laravel validation rule to all fields at once

I have inputs, some of them are array inputs (e.g. <input name="test[]">) and some are normal ones.
Fields have some specific rules, but all of them share 2 rules together.
I want that same validation rule to be applied to all fields instead of copying the same thing again and again for like 10+ fields.
I tried:
$rules = [
'*.*' => ['max:100', new CustomRule], // Apply to all
'name1' => ['array'],
'name1.*' => ['specific_rule'],
]
but it didn't work, then I moved that *.* to bottom like this:
$rules = [
'name1' => ['array'],
'name1.*' => ['specific_rule'],
'*.*' => ['max:100', new CustomRule], // Apply to all
]
and then suddenly it works!
A little confused about why it doesn't work on top, and I'm not sure if this is the right way to do this.
Please advise.
Edit:
The whole thing (removed some of the rules to simplify):
$data = json_decode($request->getContent(), true);
$rules = [
'contact' => ['required', 'array'],
'contact.name' => ['required', 'string', 'max:255'],
'contact.email' => ['required', 'email', 'unique:users,email', 'max:255'],
'subscription' => ['required', 'array'],
'subscription.type' => ['nullable', 'integer'],
'*.*' => [new CustomRule], // Works when it's here, doesn't work on top, this is a Regex rule, looking for some invalid characters in all inputs.
];
$validator = Validator::make($data, $rules);
if($validator->fails())
{
return response()->json($validator->messages(), 400);
}

Laravel validation username must not start with specific string

I want to register user but I want to put validation rule on username that username should not start with special characters and also should not start with web. I found regex that work fine special characters but detect the string it give me error of Invalid format
return [
'username' => [
'required',
'regex:/^\S*$/u',
'regex:/^[_]?[a-zA-Z0-9]+([_.-]?[a-zA-Z0-9])*$/',
'unique:users'
],
'full_name' => 'required',
];
Try this?
return [
'username' => [
'required|
not_regex:/^[web_-][a-z_\-0-9]*/i|
regex:/^[A-Za-z_ \-0-9]+$/u|
unique:users'
],
'full_name' => 'required',
];
This should work as you want it to
return [
'username' => [
'required',
'regex:/^(?!web)[a-zA-Z]\w+$/',
'unique:users'
],
'full_name' => 'required',
];
Here's a regex101 demo for you to test it out.

Laravel 5.4 sometimes|required validation not raising on "null" input

I'm having a problem validating inputs that are only going to be present sometimes in the Request.
// Controller
public function update(Request $request, User $user)
{
$updateResult = $user->updateUser($request);
return dd($updateResult);
}
// User Model
protected $validation = [
'rules' => [
'email' => [
'sometimes',
'email',
'required',
],
'password' => [
'sometimes',
'min:6',
'required',
],
'first_name' => [
'sometimes',
'required',
],
'last_name' => [
'sometimes',
'required',
],
],
'messages' => [
'email.required' => 'An email is required.',
'email.email' => 'The email must be valid.',
'password.required' => 'A password is required.',
'password.min' => 'Your password must be at least six (6) characters long.',
'first_name.required' => 'Your first name is required.',
'last_name.required' => 'Your last name is required.',
],
];
public function updateUser(Request $request)
{
$validation = Validator::make($request->all(), [
$this->validation['rules'],
$this->validation['messages'],
]);
if ($validation->fails())
{
return $validation;
}
else
{
return "OK";
}
}
So in some update pages $request->all() is only going to have a subset of these fields. However, even a field is present, but the value is null, the required doesn't trigger.
[
'first_name' => null,
'last_name' => 'Davidson',
'job_title' => 'Tech Support',
]
The above request array will return "OK"... If I remove sometimes from the fields, then when a partial input request is sent, it fails saying the fields are required.
I am clearing missing something here, but from reading the docs I thought I'd configured this correctly:
In some situations, you may wish to run validation checks against a
field only if that field is present in the input array. To quickly
accomplish this, add the sometimes rule to your rule list:
$v = Validator::make($data, [
'email' => 'sometimes|required|email', ]);
The problem you are facing is simply due to an error in your call to the validator. The second parameter is not a multidimensional array as you passed. The rules array and the messages array are separate parameters.
$validation = Validator::make($request->all(), [
$this->validation['rules'],
$this->validation['messages'],
]);
Should be replaced by
$validation = Validator::make($request->all(),
$this->validation['rules'], $this->validation['messages']);
In Laravel 5.4 empty strings are converted to Null by the ConvertEmptyStringsToNull middleware... that might cause you some issues...
You should add nullable to all your optional validations...
Hope this helps
'first_name' => [
'sometimes',
'required',
],
Will never work as expected. Sometimes indicates: if something comes, what is the next rule? In this case 'required'. Required what? Change this to:
'first_name' => [
'sometimes',
'required',
'min:1',
],
The null value will still be a null value if no input is given and won't fail. If you want to keep the value of the field in the table for updates, populate the input in the form with it's respected values.
The null value was send as '' and got nulled by the ConvertEmptyStringsToNull::class in the app\Http\kernel.php middleware.

Validiation check in Laravel php

I'm trying to write a validation check in PHP Laravel for a username field with the functionality to let the user know what went wrong. I have a couple of if statements with regular expression checks but it won't work. The requirements of the regular expression are: can't start with a ".", No more than 1 "." in a row, No capitals, Only a-z, No special characters. So for example like this "user.name" would be valid, but things like "username." or ".username" would all be invalid.
So far I got this:
$oValidator = Validator::make(Input::all(), [
'username' => 'required|regex:/^[a-zA-Z0-9][\w\.]+[a-zA-Z0-9]$/',
'username' => 'required',
'password' => 'required',
'firstname' => 'required',
'lastname' => 'required',
'email' => 'required|email'
]);
I want to give feedback for the mistakes that user makes, example: user input is ".username", program feedback should be "Dot in front of string is not allowed".
All you have to do is to include a custom message for your validation.
$this->validate($request, [
'username' => 'required|regex:/^[a-zA-Z0-9][\w\.]+[a-zA-Z0-9]$/',
], ['regex' => 'Username cannot start with period(.), etc...]);
Your code should look like this. Please remember regex custom message will apply too all of these fields instead of just username so I would separate username validation like above.
$oValidator = Validator::make(Input::all(), [
'username' => 'required|regex:/^[a-zA-Z0-9][\w\.]+[a-zA-Z0-9]$/',
'username' => 'required',
'password' => 'required',
'firstname' => 'required',
'lastname' => 'required',
'email' => 'required|email'
], ['regex' => 'Username cannot start with period, etc...']);

Categories