Validate only if not changed - laravel

I have a user settings form with 4 fields - first and last name, date of birth and username. The username is unique field in the database. The issue that I run into is when I already have set your username but after that want to update the last name or first name it always throws an error that the username is already in use. Can I somehow check if the username hasn't been changed to not validate it? Only to validate the other fields?
public function update(Request $request)
{
$user = Auth::user();
$this->portfolioValidator($request->all())->validate();
$user->username = $request->username;
$user->contact->first_name = $request->first_name;
$user->contact->last_name = $request->last_name;
$user->contact->save();
$user->save();
return response()->json(['message' => 'The changes have been saved'], 201);
}
protected function portfolioValidator(array $data)
{
return Validator::make($data, [
'first_name' => ['required', 'string'],
'last_name' => ['required', 'string'],
'username' => ['required', 'string', 'min:4', 'max:30', 'unique:users'],
]);
}

You can update your unique rule to ignore the current user as described here:
use Illuminate\Validation\Rule;
protected function portfolioValidator(array $data)
{
return Validator::make($data, [
'first_name' => ['required', 'string'],
'last_name' => ['required', 'string'],
'username' => ['required', 'string', 'min:4', 'max:30', Rule::unique('users')->ignore(Auth::user()->id)],
]);
}

Related

How to add id if there's custom validation rule when updating the record in Laravel?

How to add id in stud_num just like in email and username? the codes found in User Controller.
public function update(Request $request, $id)
{
$this->validate($request, [
'first_name' => 'required|max:255|regex:/^([^0-9]*)$/',
'middle_name' => 'nullable|max:255|regex:/^([^0-9]*)$/',
'last_name' => 'required|max:255|regex:/^([^0-9]*)$/',
'contact' => ['required', 'regex:/^(09|\+639)\d{9}$/'],
'course' => 'required',
'role_as' => 'required',
'stud_num' => ['required', 'unique:users,stud_num', 'max:15', new StrMustContain('TG')],
'username' => 'required|alpha_dash|unique:users,username,' . $id,
'email' => 'required|email:rfc,dns|unique:users,email,' . $id
]);
// codes for update
}
Just add id like email and username.
'stud_num' => ['required', 'unique:users,stud_num,'.$id, 'max:15', new StrMustContain('TG')]
you can write it like this:
'stud_num'=>['required',Rule::unique('users','stud_num')->ignore($id),'max:15',new StrMustContain('TG')]

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]
];
}

How to redirect failed validate on register to an url with anchor in laravel jetstream fortify

If I change validate by validator->fails return redirect..... I get error because login want an instance of $user and I send a response.
This defaults work well but not for me
public function create(array $input)
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['required', 'accepted'] : '',
])->validate();
return User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
}
Thats give me a:
Illuminate\Auth\SessionGuard::login(): Argument #1 ($user) must be of type Illuminate\Contracts\Auth\Authenticatable, Illuminate\Http\RedirectResponse given, called in ....endor/laravel/fortify/src/Http/Controllers/RegisteredUserController.php on line 57
public function create(array $input)
{
$validator = Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['required', 'accepted'] : '',
]);
if($validator->fails()) {
return Redirect::to(URL::previous() . "#my-anchor")->withInput()->with('error', $validator->messages()->first());
} //Thats I want
return User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
}
I don't did this before but maybe you can find the way to customize it. The CreateNewUser is called in the RegisteredUserController's store method, and the first return an User's instance. So in this you can
if($validation->fails())
return $validation->messages()->first();
and in the store method
public function store(Request $request, CreatesNewUsers $creator): RegisterResponse
{
$user = $creator->create($request->all()));
if($user instanceof User::class) {
event(new Registered($user);
$this->guard->login($user);
return app(RegisterResponse::class);
} else
return Redirect::to(URL::previous()."#my-anchor")->withInput()->with('error', $user);
}
Try this, but I suggest you if works extends this Register controller and just modify this store method

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

custom table in user model laravel

I'm using oauth2 and my table users is "coUsers" . I added this in my User Model
App\User
protected $table = 'coUsers';
public function getAuthPassword()
{
return $this->pass;
}
AuthController
public function login(Request $request)
{
$request->validate([
'usuario' => 'required|string|email',
'clave' => 'required|string',
//'remember_me' => 'boolean'
]);
$credentials = [
'usuario' => $request->get('usuario'),
'password' => $request->get('clave'),
];
if(!Auth::attempt($credentials)){
return response()->json([
'message' => 'Unauthorized'
], 401);
}
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
if ($request->remember_me)
$token->expires_at = Carbon::now()->addWeeks(1);
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => Carbon::parse($tokenResult->token->expires_at)->toDateTimeString()
]);
}
public function firstLogin(Request $request)
{
$request->validate([
'usuario' => 'required|string|email|unique:users',
'clave' => 'required|string',
'nuevaClave' => 'required|string'
]);
$user = User::where('usuario', $request['usuario'])
->where('clave', $request['clave'])
->first();
$user->clave = bcrypt($request['nuevaClave']);
$user->first_login = false;
$user->save();
return response()->json([
$user->toArray()
]);
}
Auth login works OK, but I want to use User::where in firstLogin.... I get this error:
Illuminate\Database\QueryException: SQLSTATE[42703]: Undefined column: 7 ERROR: column "usuario" does not exist
LINE 1: select count() as aggregate from "users" where "usuario" = ...
^ (SQL: select count() as aggregate from "users" where "usuario" = xxxxx#gmail.com) in file \vendor\laravel\framework\src\Illuminate\Database\Connection.php on line 669
Look in the users table instead of using the table that I indicated in the model.
You may change 'usuario' => 'required|string|email|unique:users', to 'usuario' => 'required|string|email|unique:coUsers', in your firstLogin method
You may also change this 'unique:users' in validator method inside your App\Http\Controllers\Auth\RegisterController
'email' => ['required', 'string', 'email', 'max:255', 'unique:users']
to
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:coUsers'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}

Resources