Laravel: Validation alpha and regex pattern on update - php

Hello all this is my update controller for an user. I want to know how can I apply these laravel validation rules ONLY to updated fields. Currently when I update only the first name, mobile number also get validated. My name fields are alpha validated and phone number is validated via regex.
public function update(Request $request, User $setting)
{
request()->validate([
'name' => ['required', 'alpha','min:2', 'max:255'],
'last_name' => ['required', 'alpha','min:2', 'max:255'],
'mobile'=>['required', 'string','regex:/\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|
2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|
4[987654310]|3[9643210]|2[70]|7|1)\d{1,14}$/'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users,email,'.$setting->id.''],
]);
$setting->update($request->all());
return Redirect::back()->with('success','User updated successfully');
}
I able to handle the email(unique) field, but not the others.

Considering the small chat we had in the comments, what you must do is to first get the model from the database and to diff the request with the model's attributes. Then you can keep the validation rules for the changed attributes only.
public function update(int $id, Request $request, User $userRepository)
{
$user = $userRepository->find($id);
$changedAttributes = array_diff($request->all(), $user->getAttributes());
$validationRules = array_intersect_key([
'name' => ['required', 'alpha','min:2', 'max:255'],
'last_name' => ['required', 'alpha','min:2', 'max:255'],
'mobile' => ['required', 'string', 'regex:/\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|
2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|
4[987654310]|3[9643210]|2[70]|7|1)\d{1,14}$/'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users,email,'.$setting->id.''],
], $changedAttributes);
$this->validate($request, $validationRules);
$user->update($changedAttributes);
return Redirect::back()->with('success','User updated successfully');
}

Related

custom validation error message from a controller in laravel8

protected function validator(array $data)
{
$validation = Validator::make($data, [
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed']
]);
if ($validation->fails())
{
return session()->flash('alert-danger', 'error');
}
}
protected function create(array $data)
{
$company = new Company();
$company->store_name = $data['company_name'];
$company->save();
}
Check the fail status inside the validator function and show the error message
request()->validate([
'email' => 'required'
],
[
'email.required' => 'You have to choose the email!',
]);
try this below code instead of the above validation
request()->validate([
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
];
now if you remove the code
if ($validation->fails())
{
return session()->flash('alert-danger', 'error');
}
the code will run without any error .
and if you do not enter any value in the input field
the the request->validate() will check all the request.
You need to actually return something in your if ($validation->fails()) check. Right now, you're setting a session Flash, but returning null (->flash() has no return value).
You have a couple solutions here, but it depends if this is a Form Submission or an AJAX Request:
protected function validator(array $data) {
return Validator::make($data, [
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed']
]);
}
protected function create(array $data) {
$validator = $this->validator($data);
if ($validator->fails()) {
session()->flash('alert-danger', 'error');
// If this is an AJAX Request:
if (request()->ajax()) {
return response()->json(['errors' => $validator->errors()], 422);
}
// If this is a Form Submission:
return back()->withErrors($validator->errors());
}
$company = new Company();
$company->store_name = $data['company_name'];
$company->save();
}
Basically, modify your validator method to return the Validator::make() instance, check it in your create() method, and return appropriately based on if this is an AJAX Request or Form Submission.

Laravel validation rules are not applying properly

I'm trying to apply these validation rules to my controller function, but any of the rules are not applying
Here is my code
if($request->hasFile('propic'))
{
$this->validate($request, [
'name' => 'required', 'alpha','min:2', 'max:255',
'last_name' => 'required', 'alpha','min:5', 'max:255',
'mobile' => 'required', 'string','min:10','max:14', 'regex:/\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|
2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|
4[987654310]|3[9643210]|2[70]|7|1)\d{1,14}$/',
'email' => 'required', 'string', 'email', 'max:255', 'unique:users,email,'.$setting->id.'',
'propic' => 'required','image','mimes:jpeg,png,jpg,gif,svg','max:2048',
]);
$imageName = time().'.'.$request->propic->extension();
$request->propic->move(public_path('propics'), $imageName);
$setting->propic=$imageName;
$setting->name=$request->input('name');
$setting->last_name=$request->input('last_name');
$setting->mobile=$request->input('mobile');
$setting->email=$request->input('email');
$setting->update();
return Redirect::back()->with('success',__('sentence.User updated successfully'));
}
At time of writing, there's two accepted formats for passing in validation rules:
As an array of strings (note the square brackets, which is what you are missing currently):
$this->validate($request, [
'name' => ['required', 'alpha','min:2', 'max:255'],
...
]);
As a single pipe-delimited string:
$this->validate($request, [
'name' => 'required|alpha|min:2|max:255',
...
]);

Laravel 6 - Modify the `validator` method of the `RegisterController`

I'm a beginner in programming, so please excuse my misunderstanding of validation in Laravel.
I'm trying to create a website for gamers of a specific game, where users can register. When they submit the form, I have to verify whether their account exists or not. To do this I have an external api (api from the game) which I can use to verify their account.
I tried to solve it like this in my RegisterController:
protected function validator(array $data)
{
$validation = $this->isSummonerValid($data['summonername']);
if ($validation) {
return Validator::make($data, [
'summonername' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'region' => ['required', 'string'],
'rank' => ['required', 'string'],
'lane' => ['required', 'array'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
} else {
return view('auth.register');
}
}
Everything which isSummonerValid() does is, it uses the API and returns true if the user exists in the game and false if not.
protected function isSummonerValid($summonerName)
{
$client = new Client();
try {
$response = $client->request('GET',
'https://euw1.api.riotgames.com/lol/summoner/v4/summoners/by-name/' . $summonerName .
'?api_key=' . APIKEY);
} catch (ClientException $e) {
return false;
}
return true;
}
When the API call succeeds, everything works fine. User gets created and can login.
When the API call fails (user doesn't exist) I get this error:
Method Illuminate\View\View::validate does not exist.
Can someone explain how I can create a custom validator in Laravel which calls an external API?
The validator() method of the RegisterController must always return an instance of Illuminate\Contracts\Validation\Validator class but you're returning lluminate\View\View on else condition, try to change the validator to this:
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return tap(Validator::make($data, [
'summonername' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'region' => ['required', 'string'],
'rank' => ['required', 'string'],
'lane' => ['required', 'array'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]),
function ($validator) use ($data) {
$validator->after(function ($validator) use ($data) {
if (! $this->isSummonerValid($data['summonername'])) {
$validator->errors()->add('summonername', 'Something is wrong with this field!');
}
});
}
);
}

Compare a form input with a regex expression

I am using Laravel Auth to make authentication. I need to compare a field input (Phone Number) with a regex expression in validator method. How can I do this. Below is the method code I am using,
(Currently I am hard coding my number "0312 1234567" How can I use a regex expression here?)
public function validator(array $data)
{
if($data['emailOrNumber'] == "03121234567") {
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'emailOrNumber' => ['required', 'numeric','unique:usersNew,phone'],
'password' => ['required', 'string', 'min:8'],
'surname2' => ['required', 'string', 'max:255']
]);
}
}
If you want to check against a regex, you can use the Regex validation rule.
You could use
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'emailOrNumber' => ['required', 'numeric','unique:usersNew,phone', 'regex:/(\+[0-9]{2})?[0-9]{10,12}/g'],
'password' => ['required', 'string', 'min:8'],
'surname2' => ['required', 'string', 'max:255']
]);
Little hint, I wouldn't save the email or phone number in the same column in the database. These are two completely different things, so I would save them in differrent columns. You can always leave on of the two columns empty.
You can read more about this validation on https://laravel.com/docs/5.7/validation#rule-regex

Laravel Validating An Array in Update Method With Multiple Rows Needing Ignoring

I'm trying to validate an array within the update method which means I need to ignore the id's of the rows so that it doesn'r return the error:
contactName has already been taken
Here is my validation from my update method of my controller:
public function update($id, Request $request)
{
$brand = Brand::findOrFail($id);
$request->validate([
'name' => ['required', 'string', 'max:255', Rule::unique('brands')->ignore($id)],
'contactNames' => ['required', 'array'],
'contactNames.*' => ['required', 'max:255', 'string', 'distinct', Rule::unique('brand_managers', 'name')->ignore( //what goes here? )],
'emails' => ['required', 'array'],
'emails.*' => ['required', 'max:255', 'email', 'distinct', Rule::unique('brand_managers', 'email')->ignore( //what goes here? )],
'contactNumbers' => ['array'],
'contactNumbers.*' => ['numeric'],
'groupCheckbox' => ['required', 'min:1'],
]);
}
With the unique validation rule on 'name' I can ignore the id that is coming with the $id using route model binding, but with the contactNames and contactEmails this needs to check a table that has a manyToMany relationship -
how do I ignore the id's of the brand_manager rows for multiple validation checks?
I will try and edit my question for more clarity
Thanks!
You can easily create validation rules dynamically as you wish.
Here is example from my current project which requires unique field except self.
use Illuminate\Validation\Rule;
$unique_check = Rule::unique('brand_managers', 'email'); // table with some unique rows
//if you need ignore multiple rows/multiple conditions
$unique_check->where(function ($query) use ($brand) {
return $query->whereNotIn('id', $brand->brand_managers->pluck('id')->toArray());
});
$request->validate([
'emails.*' => [ // promocode unique string column
'required',
$unique_check
],
]);
$request->validate([
'name' => ['required', 'string', 'max:255', Rule::unique('brands')->ignore($id)],
'contactNames' => ['required', 'array'],
'contactNames.*' => ['required', 'max:255', 'string', 'distinct',.$brand->id, // ID of record which want to ignore
'emails' => ['required', 'array'],
'emails.*' => ['required', 'max:255', 'email', 'distinct', .$brand->id, // ID of record which want to ignore
'contactNumbers' => ['array'],
'contactNumbers.*' => ['numeric'],
'groupCheckbox' => ['required', 'min:1'],
]);`
pass id want to ignore at time of update records.
more information check https://laravel.com/docs/5.7/validation

Categories