Conditional Validation with dependency to other fields in import - laravel

I am trying to validate import data using Laravel Excel. I got through to using required_if when a field is required when another field has a certain value. But what if validation rule I want to implement in this scenario is regex instead of required.
public function collection(Collection $rows){
$validator = Validator::make($rows->toArray(), [
'*.question_categories' => 'required',
'*.question' => 'required',
'*.question_type' => 'required',
'*.mark' => 'required',
'*.correct_answer' => ['required_if:*.question_type,Single Answer',
]
])->validate();
// Code below
}
Here I want to check value of "question_type" to determine the regular expression for "correct_answer".
I am using Laravel 6x.

Related

Laravel, use only custom rule class for validation?

I have some dynamic fields and can't use usual field validation. My question is, how can I use only my custom rule class without defining if it's required or not?
This doesn't work:
$this->validate($request, [
'social_links.fb' => new SocialFieldValidation($fieldDataFb),
'social_links.linkedin' => new SocialFieldValidation($fieldDataLinkedIn),
'social_links.twitter' => new SocialFieldValidation($fieldDataTwitter)
]);
To get this work I need to add something like:
$this->validate($request, [
'social_links.fb' => ['sometimes', new SocialFieldValidation($fieldDataFb)],
'social_links.linkedin' => ['sometimes', new SocialFieldValidation($fieldDataLinkedIn)],
'social_links.twitter' => ['sometimes', new SocialFieldValidation($fieldDataTwitter)]
]);
To use always validation class I need to set required or sometimes but I would need only to use validation class without other definitions, is that possible?
As mentionned in your comment, if putting your custom rule validation in array works but you want this working in case of null value, then you need to do use the nullable validation:
$this->validate($request, [
'social_links.fb' => ['nullable', new SocialFieldValidation($fieldDataFb)],
'social_links.linkedin' => ['nullable', new SocialFieldValidation($fieldDataLinkedIn)],
'social_links.twitter' => ['nullable', new SocialFieldValidation($fieldDataTwitter)]
]);
If you need the documentation:
https://laravel.com/docs/8.x/validation#rule-nullable
https://laravel.com/docs/8.x/validation#a-note-on-optional-fields

Array Validation: unique validation on multiple columns

I am trying to check unique validation on three columns employee_id,designation_id,station_id but the data are coming as an array which is making my situation unique and different from other SO questions/answers. I already checked few question like below: checks unique validation on multiple columns
But in my case, I can't get the value as they are inside an array. I also tried to implement Custom Rule or Request but in vain. For all the attempts, I am failing to get the field value such as $request->employee_id as they are inside an array for my case. May be I'm not trying it right.
Controller Code:
$this->validate($request, [
'posting.*.employee_id' => 'required,unique: // what to do here ??',
'posting.*.designation_id' => 'required',
'posting.*.station_id' => 'required',
'posting.*.from_date' => 'required|date',
]);
I am trying to validate uniqueness for both create and update (along with ignore $this->id facility) but don't know how to implement it here for array. It would be no problem if there was no array. Any help/suggestion/guide is much appreciated. Thanks in advance.
You can do this by creating a rule i.e UniquePosting so your controller code would look like
$this->validate($request, [
'posting' => ['required'],
'posting.*' => ['required', new UniquePosting()],
'posting.*.employee_id' => 'required',
'posting.*.designation_id' => 'required',
'posting.*.station_id' => 'required',
'posting.*.from_date' => 'required|date',
]);
Now inside your UniquePosting rule passes function will look like
public function passes($attribute, $value) {
$exists = Posting::where(['employee_id' => $value['employee_id'], 'designation_id' => $value['designation_id'],'station_id' => $value['station_id')->exists();
return !$exists;
}
Add any change if needed, overall that's the concept for testing uniqueness of the whole array.

Laravel validations

I want to validate my backend code with the following data.I passed date as $request->get('date_from'),$request->get('date_to') and time as $request->get('time_from'), $request->get('time_to') from my angular frontend and I convert date time as follows.
$dateTime_from=date('Y-m-d',strtotime($request->get('date_from'))).' '.$request->get('time_from');
$dateTime_to=date('Y-m-d',strtotime($request->get('date_to'))).' '.$request->get('time_to');
Now I want to validate DateTime with laravel backend validations. dateTime_from should be less than dateTime_to.How can write down that code inside validator?
$this->validate($request, [
'vehicle_id'=>'required',
'time_to'=>'required',
'event_id'=>'required',
]);
You can use the after validation rule.
$this->validate($request, [
'vehicle_id' => 'required',
'date_to' => 'required|after:date_from',
'event_id' => 'required'
]);
https://laravel.com/docs/5.8/validation#rule-after
you can use the after rule like follows
'date_to' => 'required|date|after:date_from'
Instead of passing a date string to be evaluated by strtotime, you may specify another field to compare against the date:
Also, you have rule-before as well
EDIT
I think after rule takes the time into consideration as well, but not sure.
And you have really complex validation to do, better write a custom rule class or a closure to handle it for you
'date_to' => [ 'required',
'date',
function ($attribute, $value, $fail) {
if (strtotime($value) <= strtotime($request->date_from) {
$fail(':attribute needs to be higher than date_from!'); // or whatever mesage ou need to send
}
]

Laravel Validation custom messages using nested attributes

I would like to ask for some advices about Laravel Validation...
Let's say I've got an input named invoiceAddress[name] and in a controller I've got a rule
$rule = ['invoiceAddress.name' => 'required',];
or just a
$validator = \Validator::make($request->all(), [
'invoiceAddress.name' => 'required',
]);
now, inside custom validation language file validation.php, am I able to nest attributes somehow? like:
'required' => ':attribute is mandatory',
'attributes' => [
'invoiceAddress' => [
'name' => 'blahblah'
],
],
If I try to nest the attribute the way above, i get
ErrorException
mb_strtoupper() expects parameter 1 to be string, array given
because I am using a field (as above)
['name' => 'blahblah']
I am trying to get custom messages using the file and the :attribute directive (as mentioned in the code above).
I am basically trying to do this How to set custom attribute labels for nested inputs in Laravel but i get the mentioned error...
Thank you in advance...
A Note On Nested Attributes
If your HTTP request contains "nested" parameters, you may specify them in your validation rules using "dot" syntax:
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
]);
Reference: https://laravel.com/docs/5.3/validation#quick-writing-the-validation-logic (A Note On Nested Attributes Section)

Laravel 5 validation rules

previously I have used validation within a Request class e.g.
public function rules()
{
return [
'userName' => 'required', 'min:3',
'userEmail' => 'required|email',
'departmentId' => 'required',
'slug' => 'required',
];
}
But I now have another form but I can't see any options within the documentation that might help me.
Basically, lets say I have a form with the same fields as the validation above. The only time validation should fail is if ALL fields contain absolutely no data. So if I put something like "hi" within the slug input and submit, it should pass the validation.
Would something like this be possible?
Thanks
You can probably use the required_without_all validation rule.
http://laravel.com/docs/5.1/validation#rule-required-without-all
The field under validation must be present only when all of the other
specified fields are not present.
It would give you something like
public function rules()
{
return [
'userName' => 'required_without_all:userEmal,departmentId,slug','min:3',
'userEmail' => 'required_without_all:userName,departmentId,slug|email'
...
];
}
But it's not very handy if you have a lot of fields.
If you have to deal with many fields, creating a custom validator might be a better solution.
http://laravel.com/docs/5.1/validation#custom-validation-rules

Resources