Laravel Validation custom messages using nested attributes - laravel

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)

Related

Conditional Validation with dependency to other fields in import

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.

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 Custom Validation for multi-language application

I am using Laravel Standard Validation, but I want to customize it because I am using multi language in my application, so I have to customize the message.
$rule_validation = [
'phone' => 'required|max:20|min:6|regex:/^[0-9]+$/',
'agree_promo_code' => request('promo_code') ? 'accepted' : '',
'terms_of_services' => 'accepted',
'aware' => 'accepted'
];
Now I want to write customize validation message for agree_promo_code
I know to write message for phone, but having doubt in agree_promo_code, terms_of_services and aware.
Can anyone help me out to resolve this issue
But please keep in mind about the language. Thank you
You can pass second array to your validate function like
$this->validate($request,[
'phone' => 'required|max:20|min:6|regex:/^[0-9]+$/',
'agree_promo_code' => request('promo_code') ? 'accepted' : '',
'terms_of_services' => 'accepted',
'aware' => 'accepted'
],[
'phone.required' => trans('validation.phone'),
'agree_promo_code.accepted' => trans('validation.agree_promo_code'),
'terms_of_services.accepted' => trans('validation.terms_of_services'),
'aware.accepted' => trans('validation.aware'),
]);
and inside your resources/lang/{lang}/validation.php file ({lang} is your language directory).
you can do something like
return [
'phone' => 'Phone validation message',
'agree_promo_code' => 'agree_promo_code validation message',
'terms_of_services' => 'terms_of_services validation message',
];
So it will set your messages according to respective language.
As you set your Language files for respective language
you need to create validation.php file under respective language folder
and add custom message for each field for each type of validation applied
for example if you have name field and validation check is required
so in your language folder's validation file you will write as below
<?php
return [
'custom' => [
'name' => [
'required' => 'O campo nome é obrigatório.'
]
];
rest all language check will be handled by Laravel itself while displaying validation error messages as per your locale language selected for session

How to allow empty value for Laravel numeric validation

How to set not require numeric validation for Laravel5.2? I just used this Code but when i don't send value or select box haven't selected item I have error the val field most be numeric... I need if request hasn't bed input leave bed alone. leave bed validate ...
$this->validate($request, [
'provinces_id' => 'required|numeric',
'type' => 'required',
'bed' => 'numeric',
]);
If I understood you correctly, you're looking for sometimes rule:
'bed' => 'sometimes|numeric',
In some situations, you may wish to run validation checks against a field only if that field is present in the input array. To quickly accomplish this, add the sometimes rule to your rule list
In Laravel 6 or 5.8, you should use nullable. But sometimes keyword doesn't work on that versions.
Use sometimes instead of required in validation rules. It checks if only there is a value. Otherwise it treats parameter as optional.
You may need nullable – sometimes and
present didn't work for me when combined with integer|min:0 on a standard text input type - the integer error was always triggered.
A Note on Optional Fields
By default, Laravel includes the TrimStrings and ConvertEmptyStringsToNull middleware in your application's global middleware stack. These middleware are listed in the stack by the App\Http\Kernel class. Because of this, you will often need to mark your "optional" request fields as nullable if you do not want the validator to consider null values as invalid.
Tested with Laravel 6.0-dev
Full list of available rules
In laravel 5.5 or versions after it, we begin to use nullable instead of sometimes.
according to laravel documentation 8 you must to set nullable rule
for example:
$validated = $request->validate([
'firstName' => ['required','max:255'],
'lastName' => ['required','max:255'],
'branches' => ['required'],
'services' => ['required' , 'json'],
'contract' => ['required' , 'max:255'],
'FixSalary' => ['nullable','numeric' , 'max:90000000'],
'Percent' => ['nullable','numeric' , 'max:100'],
]);
in your case :
$this->validate($request, [
'provinces_id' => 'required|numeric',
'type' => 'required',
'bed' => 'nullable|numeric',
]);

Resources