Laravel different validation doesn't work with strings containing numbers - php

I want to validate a value that I got from a certain form. The value type is text. I want it to match a specific username from the database from the users table, but also to not match the current user's username.
To achieve that, I used the following validation rules:
'username' => [
'required',
'string',
'exists:App\User,username',
'different:' . auth()->user()->username
]
What I've discovered is that whenever the auth()->user()->username value includes a digit, it passes the validation even if request()->username = auth()->user()->username. Is there anything I can do to prevent this from happening?
Thanks in advance.

Use unique like -
Considering id is your user's id.
'username' => 'required|string|unique:username,id,'.auth()->user()->username,
This will check if username is unique or not except this userId.

The answer to this issue was creating own Rule::exists validation, which is shown below:
'username' => [
'required',
'string',
Rule::exists('users')->where(function ($query) {
$query->where('username', '<>', auth()->user()->username);
})
],

I solved a similar problem as follows.
$request->validate([
'email' => ['required', 'email','unique:users,email,'.Auth::id()],
'phone' => ['required', 'unique:users,phone,'.Auth::id()],
]);

Related

Laravel validate array and exclude on specific array value

I have an array of values that I send together with other fields in a form to laravel.
The array contains a role_id field and a status field, the status can be I (Insert) U (update) D (Delete). When I validate the values in the array I want it to skip the ones where the status equals D. Otherwise I want it to validate.
private function checkValuesUpdate($userid = null)
{
return Request::validate(
[
'displayname' => 'required',
'username' => 'required',
'email' => ['nullable', 'unique:contacts,email' . (is_null($userid ) ? '' : (',' . $userid ))],
'roles.*.role_id' => ['exclude_if:roles.*.status,D', 'required']
]
);
}
I can't seem to get it to work. I've been searching all over the place for functional code as well as the Laravel documentation. But no luck so far. Has anybody ever done this?
Your problem comes from a misunderstanding of the exclude_if rule. It doesn't exclude the value from validation, it only excludes the value from the returned data. So it would not be included if you ran request()->validated() to get the validated input values.
According to the documentation, you can use validation rules with array/star notation so using the required_unless rule might be a better approach. (Note there's also more concise code to replace the old unique rule, and I've added a rule to check contents of the role status.)
$rules = [
'displayname' => 'required',
'username' => 'required',
'email' => [
'nullable',
Rule::unique("contacts")->ignore($userid ?? 0)
],
'roles' => 'array',
'roles.*.status' => 'in:I,U,D',
'roles.*.role_id' => ['required_unless:roles.*.status,D']
];

Laravel validation for ensuring difference in values

For the below code , i don't want the password field to have the same value of currentPassword field. The desired output is to show some validation error like "password & currentPassword canot be the same" ,when one types same value for both password & currentPassword fields. To be more precise, it should work in opposite of the rule - same does.
$validator = Validator::make(
$request->all(),
[
'currentPassword' => 'required',
'password' => 'required|min:6|confirmed',
]
);
You would expect the rule to be named "NotSame", but it is not. Instead the validation rule is called different.
'password' => 'different:currentPassword'

How can I validate to check if a record having this value exists in a table?

I am working on a Laravel project and I have the following problem related to validation.
In the past I created this validation rules (related to a new user registration form):
$rules = [
'name' => 'required',
'surname' => 'required',
'login' => 'required|unique:pm_user,login',
'email' => 'required|email|confirmed|unique:pm_user,email',
'pass' => 'required|required|min:6',
'g-recaptcha-response' => 'required|captcha',
];
In particular this rules array contains this rule:
'login' => 'required|unique:pm_user,login',
it seems to me that this last rule check if the inserted login doesn't yet exist into the pm_user table (so it ensure that not exist a row of the pm_user table having the same inserted value into the login column).
Is it? Correct me if I am doing wrong assertion.
If it work in this way now my problem is how to do the opposite thing in another set of validation rule.
In particular I have this other array of rule (defined into a class extendingFormRequest:
public function rules() {
return [
'email' => 'required|email',
'token' => 'required',
];
}
In particular I have to ensure that into the pm_user table yet exist a record having the value of the column named email that is the same of the emai field of the request.
How can I change this request to perform this validation rule?
Laravel 5.4 already has a built in validation rule for this called exists.
https://laravel.com/docs/5.4/validation#rule-exists
I think you are looking for:
'email' => 'required|email|exists:pm_user,email'

Laravel validation rules - optional, but validated if present

I'm trying to create a user update validation through form, where I pass, for example 'password'=>NULL, or 'password'=>'newone';
I'm trying to make it validate ONLY if it's passed as not null, and nothing, not even 'sometimes' works :/
I'm trying to validate as :
Validator::make(
['test' => null],
['test' => 'sometimes|required|min:6']
)->validate();
But it fails to validate.
Perhaps you were looking for 'nullable'?
'test'=> 'nullable|min:6'
Though the question is a bit old, this is how you should do it. You dont need to struggle so hard, with so much code, on something this simple.
You need to have both nullable and sometimes on the validation rule, like:
$this->validate($request, [
'username' => 'required|unique:login',
'password' => 'sometimes|nullable|between:8,20'
]);
The above will validate only if the field has some value, and ignore if there is none, or if it passes null. This works well.
Do not pass 'required' on validator
Validate like below
$this->validate($request, [
'username' => 'required|unique:login',
'password' => 'between:8,20'
]);
The above validator will accept password only if they are present but should be between 8 and 20
This is what I did in my use case
case 'update':
$rules = [
'protocol_id' => 'required',
'name' => 'required|max:30|unique:tenant.trackers'.',name,' . $id,
'ip'=>'required',
'imei' => 'max:30|unique:tenant.trackers'.',imei,' . $id,
'simcard_no' => 'between:8,15|unique:tenant.trackers'.',simcard_no,' . $id,
'data_retention_period'=>'required|integer'
];
break;
Here the tracker may or may not have sim card number , if present it will be 8 to 15 characters wrong
Update
if you still want to pass hardcoded 'NULL' value then add the
following in validator
$str='NULL';
$rules = [
password => 'required|not_in:'.$str,
];
I think you are looking for filled.
https://laravel.com/docs/5.4/validation#rule-filled
The relevant validation rules are:
required
sometimes
nullable
All have their uses and they can be checked here:
https://laravel.com/docs/5.8/validation#rule-required
if you want validation to always apply
https://laravel.com/docs/5.8/validation#conditionally-adding-rules
if you want to apply validation rules sometimes
https://laravel.com/docs/5.8/validation#a-note-on-optional-fields
if you want your attribute to allow for null as value too

Laravel 5 Unique form validation ignore id / slug

These are my rules in my class:
class AppointmentsController extends Controller
{
protected $rules = [
'appointment' => ['required', 'min:5'],
'slug' => ['required', 'unique:appointments'],
'description' => ['required'],
'date' => ['required', 'date_format:"Y-m-d H:i"'],
];
This is in the laravel official docs:
Sometimes, you may wish to ignore a given ID during the unique check.
For example, consider an "update profile" screen that includes the
user's name, e-mail address, and location. Of course, you will want to
verify that the e-mail address is unique. However, if the user only
changes the name field and not the e-mail field, you do not want a
validation error to be thrown because the user is already the owner of
the e-mail address. You only want to throw a validation error if the
user provides an e-mail address that is already used by a different
user. To tell the unique rule to ignore the user's ID, you may pass
the ID as the third parameter:
'email' => 'unique:users,email_address,'.$user->id.',user_id'
I tried using this in my rules:
'slug' => ['required', 'unique:appointments,id,:id'],
This indeed ignores the current row BUT it ignores it completely. What I want to accomplish is, I want it to ignore the current row only if the slug is unchanged. When it is changed to something that is already unique in another row, I want it to throw an error.
The Unique validator works like that
unique:table,column,except,idColumn
So in your case, you can do it like that:
Get the id you want to validate against, you can get it from the route or with any other way that works for you; something like that
$id = $this->route('id');
'slug' => ['required','unique:appointments,slug,'.$id],
For example we need to update contact info into Users table.
In my model User I created this static method:
static function getContactDataValidationRules( $idUserToExcept ) {
return [
'email' => 'required|email|max:255|unique:users,email,' . $idUserToExcept,
'pec' => 'required|email|max:255',
'phone' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:8|max:20',
'mobile' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:8|max:20',
'phone2' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:8|max:20',
'recovery_email' => 'required|email|max:255',
];
}
and in my UsersController, into the method that update User I've:
$id = $request->input('id');
$request->validate(User::getContactDataValidationRules( $id ));
:-)

Categories