Laravel 5 - Validation - 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'

Related

exists validation is not working in laravel

LoginController
public function login(Request $request)
{
$request->validate([
'email'=>'required|exists:users',
'password'=>'required|exists:users',
]);
$email=$request->email;
$password=$request->password;
if (Auth::attempt(['email' => $email, 'password' => $password,'role'=>'admin'])) {
$token = $request->user()->createToken($request->email)->plainTextToken;
return response([
'token'=>$token,
'message'=>'Admin logged in successfully',
],200);
}
if (Auth::attempt(['email' => $email, 'password' => $password,'role'=>'user'])) {
$token = $request->user()->createToken($request->email)->plainTextToken;
return response([
'token'=>$token,
'message'=>'User logged in successfully',
],200);
}
return response([
'message'=>'Email or password is wrong',
],401);
}
I am creating a login API. So, I want to show email is wrong and password is wrong if the user or admin enters wrong email and wrong password. Here, when I enter the correct email and wrong password it displays only password is wrong error which is ok but when I enter the wrong email and correct password it shows two error messages that the email is wrong and the password is wrong. It should have shown only email is wrong error but why it is showing two errors can anyone explain it to me?
There are two type of validation rules in the laravel docs for this type of case.
exists - The field under validation must exist in a given database table.
'email' => 'exists:users,email'
unique - The field under validation must not exist within the given database table.
'email' => 'unique:users,email'
In both case specify the column name with a comma.
You cannot use exists in this way for checking the password. All you can do is check that it has been provided.
'password'=>'required|exists:users',
This will check that the supplied value is present in the password field of ANY user. Since the passwords are hashed, it would never match any user, never mind the user being checked.
As a security point, you should not indicate which of the items is wrong because this is a weakness and tells the person accessing the API that they have correctly guessed a username or a password.
Change both validations to required only and leave the Auth::attempt() to do the rest, returning the 401 if the credentials are not matched.

How can I validate "Username" field in Laravel to contain letters, numbers, underscores and dashes?

public function store()
{
$this->validate(request(),[
// Third try
‘username’ => ‘required|string|regex:/\w*$/|max:255|unique:users’,
// Second try
‘username’ => ‘required|string|regex:/^[A-Za-z0-9]+(?:[_-][A-Za-z0-9]+)*$/|max:255|unique:users‘,
// First try
’username’ => ‘required|string|max:255’,
]);
}
The username field was working well with numbers included (at first try) but then I forgot to include “unique:users”, then the form started rejecting it (redirects back with username field underlined with wriggle red line). Plus I have used laravel’s “alpha_dash” several times but keeps rejecting the input. My aim is mixture of letters, numbers, underscores and dashes.
Some please help me make this right. Thanks
You're missing parameters. It should be unique:table,column,except,primarykeyname
The last two parameters are optional. In your case, your validation for storing an user should look like this:
'username' => 'required|string|regex:/\w*$/|max:255|unique:users,username',
That way, you're saying there should not be an user with that same username in the database.
When you want to update an user however, you should add the user's id as the third parameter so the validation for unique username ignores the user you're trying to update.
'username' => 'required|string|regex:/\w*$/|max:255|unique:users,username,'.$user->id,
If your primary key is not named id, you add its name as the fourth parameter:
'username' => 'required|string|regex:/\w*$/|max:255|unique:users,username,'.$user->userId.',userId',
When using the regex pattern, it may be necessary to specify rules in an array instead of using pipe delimiters, especially if the regular expression contains a pipe character :
public function store(Request $request)
{
$validatedData = $request->validate([
'username' =>
array(
'required',
'unique:users,username',
'max:255',
'regex:/\w*$/'
)
]);
}

Laravel form request validation

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.

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'],

Boolean validation check cakephp not working

Hey trying to get a validation check working on a boolean field called 'activated'. Basically if the boolean is 1 then the account is active, meaning they can login. If it is anything else then users cannot login.
Here is my check from the User Model:
public $checkActive = array(
'activated'=>array(
'rule'=>array('equalTo', '1'),
'message'=>'The account must be activated, please check your email.'
));
Unfortunately users are able to login when they are not suppose to.
I believe that validation in models are only tested when data is being saved.
If you are using the Authentication component, you can define a 'scope' which is a condition which must equal true for the user to be authenticated.
'scope' => array('User.activated' => 1)
More info and an example: http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html)
If you have written your own authentication then you could add the condition to your current find statement.
$this->User->find('all', array('conditions' => array('username' => $username, 'password' => $password, 'activated' =>1);
Hope this answers your question.

Resources