I want to add conditional validation to my request. I have different user roles and different fields for some users.
I want to check if the user role is business then some fields are required and if the user is a worker then business user fields are not required.
$this->validate($this->_request, [
'name' => 'required',
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'phone' => ['required', 'max:22'],
'municipality_of_origin' => 'required',
]);
These are required for all users. Now I want to check if a user is business
if($role == 'business'){
'company_name' => 'required',
'company_title' => 'required',
}
if($role == 'worker'){
'designation' => 'required',
'salary' => 'required',
}
$data = $request->safe()->only('name', 'email', 'phone', 'municipality_of_origin');
$user = User::create($data);
if($role == 'business){
$business_user = $request->safe()->only('company_name', 'company_title');
$business_user['user_id'] = $user->id;
// business is hasOne relationship with User model.
$user->business->create($business_user);
}
Is there any best way to handle this type of conditional validation in laravel? I'm using Laravel 9.
I try Form validation but don't understand how to use FormRequest for this type of validation.
$rules = [];
$rules['name'] = 'required';
$rules['email'] = ['required', 'string', 'email', 'max:255', 'unique:users'];
$rules['phone'] = ['required', 'max:22'];
$rules['municipality_of_origin'] = 'required';
if ($this->attributes->has('some-key')) {
$rules['other-key'] = 'required|unique|etc';
}
and problem is $this->attributes->has() method return null all the time.
Related
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')]
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]
];
}
New to PHP and Laravel but fighting through it. I am using Laravel 8 with Jetstream. Now, when Uploading a new Profile-Picture in the Edit-Section of the Frontend, the Frontend only accepts files <1MB.
Checked my PHP.ini and it is set to 100M - so, normally it should work. Any idea, where there might be an additional validation or limitation?
Best
Pierre
In app\Actions\Fortify\UpdateUserProfileInformation.php in the update() method there is validation on the size of the image you can upload as the profile picture 'photo' => ['nullable', 'image', 'max:1024'].
See method below:
public function update($user, array $input)
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
'photo' => ['nullable', 'image', 'max:1024'],
])->validateWithBag('updateProfileInformation');
if (isset($input['photo'])) {
$user->updateProfilePhoto($input['photo']);
}
if ($input['email'] !== $user->email &&
$user instanceof MustVerifyEmail) {
$this->updateVerifiedUser($user, $input);
} else {
$user->forceFill([
'name' => $input['name'],
'email' => $input['email'],
'designation' => $input['designation'],
'currentemployer' => $input['currentemployer'],
'employementtype' => $input['employementtype'],
])->save();
}
}
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)],
]);
}
I have 1 form, with multiple inputs. each section can have multiple inputs, I want to create a Form Validator inside Requests for they, but don't know how to do it... This is currently how I am doing it:
public function postCreateResume(Request $request, Resume $resume, Education $education)
{
/*
* begin a transaction, because we
* are doing multiple queries
*/
DB::beginTransaction();
/*
* first we must create the resume, then we
* can use the id for the following rows
*/
$this->validate($education, [
'resume_title' => 'required',
'expected_level' => 'required',
'salary' => 'required',
'work_location' => 'required',
'year_experience' => 'required',
'about' => 'required',
]);
$resume->name = $request['resume_title'];
$resume->work_level = $request['expected_level'];
$resume->salary = $request['expected_salary'];
$resume->country = $request['work_location'];
$resume->total_experience = $request['year_experience'];
$resume->about = $request['about'];
$resume->save();
// a user can have multiple educations on their cv
foreach($request->input('education') as $education){
$this->validate($education, [
'institution' => 'required',
'degree' => 'required',
'year_begin' => 'required',
'year_finish' => 'required',
'about' => 'required',
]);
// passed our checks, insert
$education->resume_id = $resume->id;
$education->user_id = Auth::user()->id;
$education->institute = $education['institution'];
$education->degree = $education['degree'];
$education->summary = $education['about'];
$education->started = $education['year_begin'];
$education->ended = $education['year_finish'];
if(!$education->save()){
DB::rollback();
return redirect()->back()->withErrors("There was an error creating this resume")->withInput();
}
}
// a user can have multiple employment on their cv
foreach($request->input('experience') as $employment){
$this->validate($employment, [
'company' => 'required',
'title' => 'required',
'country' => 'required',
'year_begin' => 'required',
'year_finish' => 'required',
'notes' => 'required',
]);
// passed our checks, insert
$employment->resume_id = $resume->id;
$employment->user_id = Auth::user()->id;
$employment->name = $employment['title'];
$employment->company = $employment['company'];
$employment->country = $employment['country'];
$employment->started = $employment['year_begin'];
$employment->ended = $employment['year_finish'];
$employment->summary = $employment['notes'];
if(!$employment->save()){
DB::rollback();
return redirect()->back()->withErrors("There was an error creating this resume")->withInput();
}
}
return redirect()->back()->withSuccess("You have created a resume")->withInput();
}
Notice I have the validate inside each of the foreach in case the user has chosen more than 1 (in this example) work experience, or education, what I am trying to do is move the $this->validate inside the Requests folder, how can I achieve this?
I am using a foreach because I can have unlimited sections, see the image as to why;
Since laravel 5.4 you can pass arrays to the validator itself, for exaple
<input name="myarray[0]['test'] type="text">
Can now be validated like so
$this->validate($request, [
'myarray.*.test' => 'required'
]);
https://laravel.com/docs/5.4/validation#validating-arrays
Validating array based form input fields doesn't have to be a pain. For example, to validate that each e-mail in a given array input field is unique, you may do the following:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
Likewise, you may use the * character when specifying your validation messages in your language files, making it a breeze to use a single validation message for array based fields:
'custom' => [
'person.*.email' => [
'unique' => 'Each person must have a unique e-mail address',
]
],