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']),
]);
Related
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",
]);
I have a input request that can be an integer or an array of integer values.
How can I check validation of that in Laravel? I'm using Laravel 5.5.I know that there is a simple array validation rules that checks an input is an array or not:
array
The field under validation must be a PHP array.
Is there any predefined validation rule or should I write a new one? if yes, How?
$input = $request->all();
//Check if input param is an array
if(is_array($input['item']))
{
//Array validator
$Validator = Validator::make($input,
[
'item' => 'required', //Array with key 'item' must exist
'item.*' => 'sometimes|integer', //All values should be integers
]);
}
else
{
//Integer validator
$Validator = Validator::make($input,
[
'item' => 'required|integer',
]);
}
Use sometimes it applies validation rule only if that input parameter exist. Hope this helps
I need to check input array of strings and raise warning if at least one of array elements is empty.
The following rule is used:
return Validator::make($data, [
'branches' => 'array',
'branches.*' => 'filled|max:255'
]);
However it seems filled rule doesn't work (while min:1 works fine).
Should it work with array elements or not?
UPDATE:
branches array is not mandatory, but if exists it should contain non empty elements.
UPDATE:
Finally found mistake in my validation rule.
It should look like
return Validator::make($data, [
'branches' => 'array',
'branches.*.*' => 'filled|max:255'
]);
since input array is array of arrays. Now filled rule works as expected with my input data.
Use required instead
return Validator::make($data, [
'branches' => 'required|array',
'branches.*' => 'required|max:255'
]);
From the documentation: https://laravel.com/docs/5.5/validation#available-validation-rules
required
The field under validation must be present in the input data and not
empty. A field is considered "empty" if one of the following
conditions are true:
The value is null.
The value is an empty string.
The value is an empty array or empty Countable object.
The value is an uploaded file with no path.
If you want to validate the array only if there is field data present use filled. You can combine this with present.
return Validator::make($data, [
'branches' => 'present|array',
'branches.*' => 'filled|max:255'
]);
filled
The field under validation must not be empty when it is present.
present
The field under validation must be present in the input data but can be empty.
Considering your comment you should try nullable
return Validator::make($data, [
'branches' => 'nullable|array',
'branches.*' => 'nullable|max:255'
]);
OR
You can use presentthis will ensure that array should be passed either with values or just an empty array
return Validator::make($data, [
'branches' => 'present|array',
'branches.*' => 'nullable|max:255'
]);
I am having a form where i am having title, body, answers[][answer] and options[][option].
I want atleast one answer must be selected for the given question, for example:
i have ABC question and having 5 options for that question,now atleast one answer must be checked or all for given question.
Efforts
protected $rules = [
'title' => 'required|unique:contents|max:255',
'body' => 'required|min:10',
'type' => 'required',
'belongsto' => 'sometimes|required',
'options.*.option' => 'required|max:100',
'answers.*.answer' => 'required',
];
But this is not working. i want atleast one answer must be selected.
Please help me.
The problem is that on $_POST an array filled with empty strings will be passed if no answer is selected.
$answers[0][0] = ''
$answers[0][1] = ''
$answers[0][2] = ''
Hence the following will not work since array count will be greater than zero due to the empty strings:
$validator = Validator::make($request->all(), [
'answers.*' => 'required'
]);
The easiest way to solve this is to create a custom Validator rule by using Laravel's Validator::extend function.
Validator::extendImplicit('arrayRequireMin', function($attribute, $values, $parameters)
{
$countFilled = count(array_filter($values));
return ($countFilled >= $parameters[0]);
});
And then call it in your Validation request:
$validator = Validator::make($request->all(), [
'answers.*' => 'arrayRequireMin:1'
]);
The magic happens in array_filter() which removes all empty attributes from the array. Now you can set any minimum number of answers required.
Validator::extendImplicit() vs Validator::extend()
For a rule to run even when an attribute is empty, the rule must imply that the attribute is required. To create such an "implicit" extension, use the Validator::extendImplicit() method:
Laravel's validation docs
Try this,
'answer.0' => 'required'
it will help you. I think.
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