Laravel form request validation - laravel

Is there any way to get original data in request?
I mean, in my case I want to validate updating user's in the form. I want the email to be unique on emails in database except on the email that user wrote to the form.

Laravel already has a validation rule for this, you can add an id of the user to ignore to your unique validator.
'email' => [
'required',
Rule::unique('users')->ignore($currentUser->id),
]

I used something like this:
'email' => ['sometimes', 'email', 'unique:users,email,'.$user->getKey().','.$user->getKeyName().',deleted_at,NULL', 'string'],
Not sure if it is the best solution but works. I kind of do not like it because the $user is based on hidden input from the request.

You can do it liks this:
'email' => 'unique:users,email,'.$user->id
The user id will allow you to keep updating the record but maintain the unique constraint on email. You don't need a hidden input field for $user->id btw.

Related

Does Laravel validation rule default to sometimes?

If you create a validation rule in Laravel, but leave out |required and just use, say the email rule. What does it default to?
For example
$request->validate([
'email' => 'email'
]);
Are these validation rules equal?
$request->validate([
'email' => 'sometimes|email'
]);
// vs
$request->validate([
'email' => 'email'
]);
Apologies if this has been answered before. I tried my very best to search for similar questions, but I may have used the wrong words (not sure how to phrase this for a Google/Stack Overflow search).
$request->validate([
'email' => 'email'
]);
This will always validate the email key, even if empty, to be a valid email format.
$request->validate([
'email' => 'sometimes|email'
]);
This will only validate the email key if the key is present in $request->all().
So the difference is that with sometimes you'll only validate it if the $request object contains it, whilst otherwise it would always validate against the key.
If I could simplify it, I would say sometimes means, only apply the rest of the validation rules if the field shows up in the request. Imagine sometimes is like an if statement that checks if the field is present in the request/input before applying any of the rules.
It can be a tedious thing to wrap ones head around, but here is some examples:
input: []
rules: ['email' => 'sometimes|email']
result: pass, the request is empty so sometimes won't apply any of the rules
input: ['email' => '1']
rules: ['email' => 'sometimes|email']
result: fail, the field is present though invalid email so the email rule fails!
input: []
rules: ['email' => 'email']
result: fail, the request is empty so email is invalid!
I personally have never used the sometimes rule once. According to the docs:
https://laravel.com/docs/7.x/validation#conditionally-adding-rules
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
If I understand correctly, this largely depends on your frontend implementation. If you are using regular html <form> elements where you have an input with name="email", it will send a key named email as soon as you submit the form.
So in order to NOT send such key, you have to remove it from the form, or manually make a HTTP request (so disregarding any HTML form) such that you can decide your own input fields.

Laravel: Validate input only if available in DOM

I created a form with the following fields:
Name
Email
Country
City
Address
If the user selects a country that has states (ex. United States) then the form transforms to:
Name
Email
Country
State
City
Address
To validate this I created a separate form request like so:
public function rules()
{
return [
'name' => 'required|max:255',
'email' => 'required|email,
'country_id' => 'required|integer',
'state_id' => 'nullable|integer',
'city_id' => 'required|integer',
'address' => 'required',
];
}
The problem is that if I leave it like that, then if I don't select a state it will pass validation.
If i make it:
'state_id' => 'sometimes|nullable|integer',
Then again it passes validation.
If I make it:
'state_id' => 'required|nullable|integer',
It will not pass validation, but then again it will throw a validation error if there is no state field in the form.
I read a lot of articles about this but nothing seems to solve it for me.
PS1: I want to solve this in the form request, not in the controller. I assume that an
if($request->has('states')){...}
can help, but then again, i would like to keep everything tidy in the form request.
PS2: I am using VueJS and Axios to add/remove states from the form. The whole form is actually a Vue component.
Any clues?
Thank you in advance!
You can conditionally add rules via the sometimes method on Validator.
$v->sometimes('state_id', 'required|integer', function ($input) {
return in_array($input->countries, [1,2,3,4...]
});
You could use the required_with line of parameters, but because the validation is based on the value of the input instead of just the presence, the custom validation rule is probably your best bet.
Per https://laravel.com/docs/5.7/validation#conditionally-adding-rules

Laravel 5 - Validation

I am confuse how can I validate a user's username if I am updating it. Here's the scenario, if I click a specific user in list of users page it will redirect into a page which has a form with user's data in the form. Now, I have:
public function updateUser(Request $request){
$this->validate($request, [
'username' => 'required|unique:users',
'name' => 'required|max:255'
]);
}
UPDATE
$this->validate($request, [
'name' => 'unique:roles,name,'.$request->id
]);
I know the part where 'username' => 'required|unique:users' is checking if the username exists in the users table, but what if I dont want to change/update the username, and I just want to update the other field, then it says that the username is already exists. How can I validate it in a right way.
Need help guys. This can also help others for this kind of problem.
Laravel will accept a new parameter for the key of the table. This should be the id of the element you would like to ignore in your query.
something like 'username' => 'required|unique:users,username,'.$request->get('id'),
You will have to pass the id variable in your request when updating.
Laravel documentation: https://laravel.com/docs/5.4/validation#rule-unique
You can also try using the Rule class (search for "Forcing A Unique Rule To Ignore A Given ID"), which was added in Laravel version 5.3.
You can see an example of usage of my answer in the documentation at:
https://laravel.com/docs/5.2/validation#rule-unique (search for "Forcing A Unique Rule To Ignore A Given ID")
Update as per question update:
$this->validate($request, [
'name' => 'required|unique:roles, name,'.$request->id
]);
you want to update profile and at that time you stuck with this error "username is already exists". so my suggestion is just remove the required validation from username if username is not updated then don't send it to server, so you no need to check whether it's exists or not in table and also if want to check particular column you can write like this
public function updateUser(Request $request){
$this->validate($request, [
'username' => 'unique:users,column-name',
'name' => 'required|max:255'
]);
}
in above case if we receive a username then we check it's uniqueness else not
You just need to check if the user exists or not
'username' => 'exists:users'
If the user exists in the database you will update it.
What wrong you are doing is: You are trying to update a user and validating that the username should be unique (this validation should be applied during user creation), that is not correct.
Thanks.
EDIT 1
Generally, username or email is a key column which you should not allow the user to update. Otherwise, this problem will always exist.
EDIT 2
I agree with the actual scenario that we can not assume that the username field will always remain same and the user can not update it. If the user is updating the username then you can try this code.
'username' => 'required|unique:users,username,'.$user->id
If your table uses a primary key column name other than id, you may specify it as the fourth parameter:
'username' => 'required|unique:users,username,'.$user->id.',user_id'

How to implement email validation on admin form in Magento2

I want to use email validation in admin form of my custom module. I've seen core module but couldn't get exact idea.
You can also validate the 'email' text field by adding a class ['validate-email'] in your form
$fieldset->addField(
'email',
'text',
[
'name' => 'email',
'label' => __('Email'),
'title' => __('Email'),
'required' => true,
'class' => 'validate-email'
]
);
Validation is Model's issue. Only model knows how your data should look like. You describe your data fields in model, so you should describe validation rules for this fields in the same place.
It seems to be obvious for me, but I'd gladly listen to opponents.
put database validation in the Model (assuming it's a db model) and http data validation in the controller. Xss filtering, for example, does not pertain to the Model. it pertains to the Controller in input and to the View in output
I found an answer by myself, I used PHP email validation in the save controller.

Laravel profile update with e-mail unique:users

I'm new in Laravel. I try to make profile update page... all works good but if I try to apply rule to set email field unique:users I have problem when user try to update for example name and don't want change email.
public function rules()
{
return [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
];
}
I want restrict that user to use the same e-mail that someone else is using... but I want to ignore that if this is the same e-mail already in that user profile and he don't want to change that.
public function updateData(UpdateDataRequest $request)
{
DB::table('users')
->where('id', Auth::user()->id)
->update(array('email' => $request->email, 'name' => $request->name));
return redirect('panel');
}
How to do it right?
This exact situation is used as an example in the docs.
https://laravel.com/docs/5.2/validation#rule-unique
Forcing A Unique Rule To Ignore A Given ID:
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
If your table uses a primary key column name other than id, you may specify it as the fourth parameter:
'email' => 'unique:users,email_address,'.$user->id.',user_id'
In new version. laravel using Rules to ignore a user or record
https://laravel.com/docs/5.8/validation#rule-unique
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
$user->id can be a specific id or the id of current user which is login
try to this validation(Laravel 8.x)
'email' => ['email:rfc','confirmed','unique:App\Models\User,email'],

Resources