Check unique email with password not null in laravel - laravel

I have a user table where there are two fields email and password
$validator = Validator::make($request->all(),[
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:5', 'confirmed','min:8'],
'password_confirmation' => ['min:8']
]);
I'm using unique field to check whether email is unique but i want to show message user already exist only if email already exist and password field not null, because i have a case if user is login through social media account then password is not saved and is null, so when user is trying to register through normal account then i want to update user fields.
Any Suggestion Thanks

You can have a more advanced unique rule:
$validator = Validator::make($request->all(),[
'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users')->where(function ($q) {
$q->whereNotNull('password');
}) ],
'password' => ['required', 'string', 'min:5', 'confirmed','min:8'],
'password_confirmation' => ['min:8']
]);

Related

Laravel validation 'sometimes' with 'present' rule isn't overriding the values rules in the validation

I am trying to make a single method which can be used to update a user profile, to make it easier for a user I want the validation to only work if there is data in the field, however when trying to use the 'sometimes' property with the 'present' property, the validation for string runs for example. in this project I am using vue.js and submit the form data using the inertia.put method, I am also using the vue dev tools chrome extension to view the errors in the inertia prop.
The form object can be seen below
form: {
name: '',
username: '',
email: '',
password: '',
password_confirmation: '',
_token : this.$page.props.csrf
}
below is the method that will run the put request
Inertia.put(route('user.edit', this.user.id), this.form, {
onSuccess: () => {
this.user.username = this.form.username;
this.form.username = '';
this.sweetAlertSuccess('username');
}
});
this is the validation method in Laravel which is a custom request
public function rules(): array
{
return [
'name' => ['sometimes', 'present', 'string', 'max:255'],
'username' => ['sometimes', 'present', 'max:255', 'string', 'unique:users,username'],
'email' => ['sometimes', 'present', 'email', 'unique:users,email', 'max:255'],
'password' => ['sometimes', 'present', 'min:8', 'max:255', 'confirmed']
];
}
here is the error message I am seeing, I only want the message to validate the field which has data in it and fails the rules, if the field is empty then I want it to skip the validation for that particular field in the keyed array.
replacing 'present' with nullable fixed the issue.
public function rules(): array
{
return [
'name' => ['sometimes', 'nullable', 'string', 'max:255'],
'username' => ['sometimes','nullable', 'max:255', 'string', 'unique:users,username'],
'email' => ['sometimes', 'nullable', 'email', 'unique:users,email', 'max:255'],
'password' => ['sometimes', 'nullable','min:8', 'max:255', 'confirmed']
];
}

How to take User Id from Request(rules) for update?

Could I know how to take the user Id to Request an update? for example, when I updated the user and password. But, except email. At that time, It showed "the message that the email is already taken. When I searched for solutions, I found to solve with the user id. I know this question is asked many times. But, I didn't get any suitable answer for me. Could you help me, please?
This is my Controller Code
public function edit(Users $request,$id){
$users=User::whereId($id)->firstorFail();
$users->name = $request->get('name');
$users->email = $request->get('email');
$users->password = Hash::make($request->get('password'));
$users->role = $request->get('role');
$users->update();
$request->session()->forget('editvalue');
$userdata = User::paginate(4);
// session()->flash('status', 'User has been successfully added.');
return view('pages.auth.register', compact('userdata'))->with('status','User has been successfully added.');
}
This is my Request Form. I want to take id value in this. When I take value, it is showing the message that Trying to get property 'id' of non-object
public function rules() {
return [
'name' => 'required', 'string', 'max:255',
'email' => 'sometimes','required', 'string', 'email', 'max:255', 'unique:users,'. $this->users->id,
'password' => 'required', 'string', 'min:8', 'confirmed',
'role' => 'required', 'string',
];
}
This is my web.php
Route::get('users/edit/{id}', 'UsersController#editscreen');
Route::post('users/edit/{id}', 'UsersController#edit');
You should also put the column name to the rule,
the pattern should be unique:table,column,except_id
Can you replace your RequestForm with this:
public function rules()
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => ['sometimes','required', 'string', 'email', 'max:255', 'unique:users,email,'. $this->users->id],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'role' => ['required', 'string'],
];
} }
I think you can't validate {id} in the request class but you can validate with regex in the route. (My Example is for laravel 8 but the principle remains the same)
Route::post('/users/edit/{id}', [UsersController::class, 'editscreen'])
->where('id', '[0-9]+');
I got with this.
use Illuminate\Validation\Rule;//import Rule class
public function rules()
{
return [
'name' => 'required', 'string', 'max:255',
'email' => ['sometimes','required', 'string', 'email', 'max:255',
Rule::unique('users')->ignore($this->id),
],
'password' => 'required', 'string', 'min:8', 'confirmed',
'role' => 'required', 'string',
];
}
I just encountered this problem and managed to solve by adding $this->id only.
public function rules()
{
return [
'name' => ['required', 'string', 'max:255']
'email' => ['required', 'string', 'unique:users,email,' . $this->id]
];
}

remove validation on name in laravel 6 on creating new user

I want to remove validation on the name in laravel 6 on creating a new user. The user is created successfully but when I enter a name with space or capital letters, the login page opens up. But if I remove all spaces from the name everything works fine with the following code.
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
$username = slugify($data['name']) . "-" . mt_rand(10000, 99999);
return User::create([
'name' => $data['name'],
'username' => $username,
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
blade.php code
https://codeshare.io/5e1kX7
Try
//...
'name' => ['required', 'string', 'regex:/^[a-zA-Z0-9\s]+$/', 'max:255'],
//...
I did it by adding regex in the validation
'name' => ['required', 'string','regex:/^[\pL\s\-]+$/u', 'max:255'],

How to create unique column in registration validator for two different tables

I'm creating two different registration (for admin and user). But the username->unique in the validator is only for table users.
protected function validator(array $data)
{
return Validator::make($data, [
'firstname' => ['required', 'string', 'max:255', 'min:3'],
'middlename' => ['required', 'string', 'max:255', 'min:3'],
'lastname' => ['required', 'string', 'max:255', 'min:3'],
'username' => ['required', 'string', 'max:255', 'min:3', 'unique:users'],
'password' => ['required', 'string', 'min:6', 'confirmed'],
]);
}
validate unique username for user registration from the users table and validate unique username for admin registration from the admins table.
You could use the route name or something similar, from the current request to determine which rules have to get used.
protected function validator(array $data)
{
$route = Request::route()->getName();
$rules = [
'firstname' => ['required', 'string', 'max:255', 'min:3'],
'middlename' => ['required', 'string', 'max:255', 'min:3'],
'lastname' => ['required', 'string', 'max:255', 'min:3'],
'password' => ['required', 'string', 'min:6', 'confirmed'],
];
// whatever your route name or identifier to differentiate between
// user and admin registration may be.
if ($route === 'registration.user') {
$rules = $rules + [
'username' => ['required', 'string', 'max:255', 'min:3', 'unique:users'],
];
}
return Validator::make($data, $rules);
}
A Validator should only validate data, it's bad to couple it with concepts about routes etc...
I would create a custom Validator class which will take a table name as parameter.
Then you can instantiate that validator with the correct table parameters in your controller (which will be aware about route, request etc...)

Laravel conditional unique validation

Working with Laravel 5.4, I need to validate if the email field on the users table is unique only if the role_id field is not 999.
In the Register Controller I did this:
return Validator::make($data, [
'first_name' => 'required|max:255',
'last_name' => 'required|max:255',
'email' => [
'required',
'email',
'max:255',
Rule::unique('users')->where(function($query) {
$query->where('role_id', '<>', 999);
})
],
'phone' => 'required|phone',
'password' => 'required|min:6|confirmed'
]);
But when I try to register I get this error:
Class 'App\Http\Controllers\Auth\Rule' not found
What am I doing wrong?
Thank you
You have to include the Rule class with a use at the top of your file after the namespace declaration:
use Illuminate\Validation\Rule;

Resources