rename attribute item array in request validation laravel - php

I am working with the laravel validations in form request and this time I need to validate a data array something like this:
public function rules()
{
$rules = [
'products.*.quantity' => 'required|integer',
'products.*.dimension' => 'required|min:5|max:16',
'products.*.description' => 'required|min:5',
];
return $rules;
}
where products is the array where I have each of the items, this works however it gives me a message more or less like this: The products.1.quantity field is required.
I need to change the name of the attribute, I know it is possible to change the name inside the messages method giving a new value to products.*. quantity for example products.*. quantity => "quantity", however I would also like to specify the key of the item that is failing and at the end have a message like this:
The quantity in item 1 field is required.
then is it possible to achieve this?

Search for this file resources/lang/xx/validation.php and modify custom entry with your custom messages
'custom' => [
'products.*.quantity' => [
'required' => 'Your custom message',
]
]

Related

Using excludes_unless validation rule with arrays in Laravel

Laravel's exclude_unless,field,value rule doesn't seem to work in the instance where field is an array of values and value is contained within the field array.
Given the following:
$validator = Validator::make($request->all(), [
'some_array' => 'array',
'some_field' => 'exclude_unless:some_array,foo|alpha_num',
]);
Where some_array is equal to ['foo'], the validator will fail to exclude some_field. This seems to be because the comparison that lies beneath excludes_unless is in_array(['foo'], ['foo']) which returns false.
Is it possible to achieve the same logic of exclude_unless — excluding a field from validation if another field equals a certain value, but where the field being compared against is an array and we're checking that the value is in that array?
As long as you're using Laravel 8.55 or above, you could use Rule::when():
use Illuminate\Validation\Rule;
$someArray = $request->input('some_array', []);
$validator = Validator::make($request->all(), [
'some_array' => 'array',
'some_field' => Rule::when(!empty(array_intersect(['foo'], $someArray)), ['exclude']),
]);

Validate array of inputs in form in Laravel 5.7

My form has the same input field multiple times. My form field is as follows:
<input type='text' name='items[]'>
<input type='text' name='items[]'>
<input type='text' name='items[]'>
And request contains ($request['items'):
array:1 [▼
"items" => array:3 [▼
0 => "item one"
1 => "item two"
2 => "item three"
]
]
I want atleast one of the items to be filled. My current validation in the controller is
$validator = Validator::make($request->all(),[
'items.*' => 'required|array|size:1'
]);
It does not work. I tried with combination of size, required, nullable. Nothing works.
In fact, it's enough to use:
$validator = Validator::make($request->all(),[
'items' => 'required|array'
]);
The changes made:
use items instead of items.* - you want to set rule of general items, if you use items.* it means you apply rule to each sent element of array separately
removed size:1 because it would mean you want to have exactly one element sent (and you want at least one). You don't need it at all because you have required rule. You can read documentation for required rule and you can read in there that empty array would case that required rule will fail, so this required rule for array makes that array should have at least 1 element, so you don't need min:1 or size:1 at all
You can check it like this:
$validator = Validator::make($request->all(), [
"items" => "required|array|min:1",
"items.*" => "required|string|distinct|min:1",
]);
In the example above:
"items" must be an array with at least 1 elements.
Values in the "items" array must be distinct (unique) strings, at least 1 characters long.
You can use a custom rule with a closure.
https://laravel.com/docs/5.7/validation#custom-validation-rules
To check if an array has all null values check it with array_filter which returns false if they're all null.
So something like...
$request->validate([
'items' => [
// $attribute = 'items', $value = items array, $fail = error message as string
function($attribute, $value, $fail) {
if (!array_filter($value)) {
$fail($attribute.' is empty.');
}
},
]
]);
This will set the error message: 'items is empty."
Knowing you are using the latest version of Laravel, I really suggest looking into Form Request feature. That way you can decouple validation from your controller keeping it much cleaner.
Anyways as the answer above me suggested, it should be sufficient for you to go with:
'items' => 'required|array'
Just Do it normally as you always do:
$validator = Validator::make($request->all(),[
'items' => 'required'
]);
You should try this:
$validator = $request->validate([
"items" => "required|array|min:3",
"items.*" => "required|string|distinct|min:3",
]);

Adding a check for validator if field is not empty

I have a validator for users to update their profile, and on the same page the user can change their password. Although, I do not want to run a check if all the 3 fields (current password, new / confirmed) is empty.
Is there a way I can add in a custom check in the Validator::makeand check, or add to the validator and add the return with errors page?
$validator = Validator::make($request->all(), [
'first_name' => 'required|max:191',
'last_name' => 'required|max:191',
'email' => 'required|email|max:191'
]);
example 3 field are empty and wouldnt be a problem, although what if they're filled out... can I append to this for check
example
if ($request->new_password) {
$validator .= array('new_password' => 'required');
}
my last solution would be to have two validators... would that work?
You can accomplish this by adding sometimes to your rule list. sometimes runs validation checks against a field only if that field is present in the input array. As an exmaple,
$v = Validator::make($data, [
'email' => 'sometimes|required|email',
]);
For more rules options you can refer to Laravel Validator Documentation.

Validating a JSON array in Laravel

I have a controller which receives a following POST request:
{
"_token": "csrf token omitted",
"order": [1,2,3,4,5,6,7,8]
}
How can I use validators to ensure that elements in order are unique, and between 1 and 7? I have tried the following:
$this->validate($request, [
'order' => 'required|array',
'order.*' => 'unique|integer|between:1,7'
]);
The first clause is checked, the secound one passes even when the input is invalid.
Using distinct rule:
distinct
When working with arrays, the field under validation must not have any
duplicate values.
In your case, it could look like this:
$this->validate($request, [
'order' => 'required|array',
'order.*' => 'distinct|integer|between:1,7'
]);
The unique validator keyword is for checking a value's duplicates in database.
You should use custom validator for such situations.
See: https://laravel.com/docs/5.1/validation#custom-validation-rules

Form Validation messages Vs Language in Laravel 5

After reading the docs, I've understood the strucutre in resources/lang/xx/validation.php to add custom error messages.
'custom' => [
'name' => [
'required' => 'Please fill the name of the company'
]
],
My problem here is that after setting this up, I won't be able to use a field called name to another resource, for instance a Please fill out your name message. When overriding the method messages() inside the FormRequest, I'm able to be more specific in these messages, but then I lose the Language customization.
My question is: How can I go about setting up custom messages for different Form Requests and still keep the language system working in my favor?
Edit
To better explain what I want, here is a little bit of code.
class CompanyRequest extends Request {
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules() {
return [
'name' => 'required|max:20'
];
}
public function messages() {
// Here I have specific message for Company name field, but I'm
// stuck with one single language.
return [
'name.required' => 'Can you please fill the company name.',
'name.max' => 'The name of the company cannot be bigger than 20 characters'
];
}
}
Now the UserRequest
class UserRequest extends Request {
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules() {
return [
'name' => 'required|max:40',
'email' => 'required|email'
];
}
public function messages() {
// Here I have specific message for User name field, but I'm stuck
// with one single language.
return [
'name.required' => 'Please provide your full name',
'name.max' => 'If your name is bigger than 40 characters, consider using only first and last name.'
];
}
}
Now, this works perfectly, but I'm stuck with English. I can solve that with the resources/lang/en/validation.php file. Now, I'll erase the messages method and use the validation file instead.
'custom' => [
// Here I can have multiple validation files for different languages,
// but how would I go about to define the field name for other entities
// (such as the user message).
'name' => [
'required' => 'Please fill the name of the company',
'max' => 'The field cannot have more than 20 characters',
]
]
Now, how can I differ the messages for the field name for Company entity and the field name for User entity?
To wrap it up:
The Form Request provides me a way of overriding a messages() method that allow me to use the term name for multiple forms.
The Validation file provides me a way of using multiple languages (I can create a resources/lang/fr/validation.php, but I can only define the field "name" once. I cannot have different messages for a field name.

Categories