Reputation: 5267
I want to validate an array of input data using a Form Request in Laravel. The array looks like this:
[
'issues' =>
[
'type' => 'prio_1',
'note' => 'This is some text'
],
[
'type' => 'prio_2',
'note' => 'This is some other text'
]
[
'type' => 'prio_1',
'note' => 'This is yet some other text',
'deleted' => true
]
]
I want to validate that the the type
field is distinct
in this array, taking into account that the third array entry is deleted
and thus needs to be ignored for this rule.
Using
["issues.*.type" => 'required|distinct']
does not work of course as this rule cannot be parameterised to ignore the rule in case an array property has a certain value.
Filtering the input to leave out the deleted entries is not an option either, as the index replacing the *
in the response needs to match the original index in the request.
Is there a way to extend the distinct
rule (using a custom validator) to allow for this kind of validation? Or any other way to allow for this?
Upvotes: 0
Views: 2519
Reputation: 35200
You could use a closure and a collection to check to see if there are duplicated (excluding "deleted" items):
public function rules()
{
return [
"issues.*.type" => [
'required', function ($attr, $value, $fail) {
$count = collect($this->input('issues'))
->reject(function ($item) {
return isset($item['deleted']) && $item['deleted'];
})
->filter(function ($item) use ($value) {
return $item['type'] === $value;
})
->count();
if ($count > 1) {
$fail(__('validation.distinct'));
}
},
],
];
}
To make things more efficient you could also just count the values before and just check to see if the count is more than one:
public function rules()
{
$duplicateTypes = collect($this->input('issues'))
->reject(function ($item) {
return isset($item['deleted']) && $item['deleted'];
})
->groupBy('type')
->map->count();
return [
"issues.*.type" => [
'required', function ($attr, $value, $fail) use($duplicateTypes) {
if ($duplicateTypes[$value] > 1) {
$fail(__('validation.distinct'));
}
},
],
];
}
Upvotes: 2