Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5: Request validate multidimensional array

I have forms that submit multidimensional arrays. Like:

slide[1][title]
slide[2][title]

Now I use a Request class to define my rules. How can I loop through all array items within this class. I tried:

public function rules()
{
    return [
        'id' => 'required',
        'slide' => 'array|min:1',
        'slide.*.title' => 'required|max:255',
        'slide.*.description' => 'required|max:255',
    ];
}

But it did not work.

like image 235
Alexej Avatar asked Aug 19 '15 09:08

Alexej


2 Answers

Laravel 5.5 or newer

You can use the same array validation syntax that is available in the Validator, so the code in the question now works:

public function rules()
{
    return [
        'id' => 'required',
        'slide' => 'array|min:1',
        'slide.*.title' => 'required|max:255',
        'slide.*.description' => 'required|max:255',
    ];

}

Laravel 5.4 or older

Disclaimer: This solution was posted in the question by Alexej. Since answers shouldn't be shared in the question body and the OP seems to be inactive, I repost his answer as a community wiki for future readers:

I've found the solution by getting the slide array and loop through it.

public function rules()
{
    $rules = [
        'id' => 'required',
        'slide' => 'array|min:1',
    ];
    foreach($this->request->get('slide') as $key => $val){
        $rules['slide.'.$key.'.title'] = 'required|max:255';
        $rules['slide.'.$key.'.description'] = 'required|max:255';
    }
    return $rules;
}
like image 116
3 revs, 2 users 98% Avatar answered Oct 23 '22 08:10

3 revs, 2 users 98%


There is a better way to do this now. I'm not sure the exact minimum version of Laravel that supports this but I'm running 5.5 and this approach works.

Assuming you have request data like:

index:0
is_required:1
type:select
name:favorite color
title:What is your favorite color?
meta[0][key]:subtitle
meta[0][value]:If you have multiple favorites, pick your favorite-favorite.
meta[1][key]:default_value
meta[1][value]:Pink
options[0][index]:0
options[0][value]:Red
options[1][index]:3
options[1][value]:Pink
options[2][index]:1
options[2][value]:Blue
options[3][index]:2
options[3][value]:Green

Your validation rules can look like:

return [
    'index' => 'required|integer|min:0',
    'is_required' => 'required|boolean',
    'type' => [
        'required',
        Rule::in($this->types_enum)
    ],
    'name' => 'required|string|max:64',
    'meta' => 'sometimes|array',
    'meta.*.key' => 'required|string|max:64',
    'meta.*.value' => 'required|string',
    'options' => 'sometimes|array',
    'options.*.index' => 'required|integer|min:0',
    'options.*.value' => 'required|string',
];

Note the trick is just to use the wildcard operator (*) with dot notation to represent the index value of the array item itself.

like image 1
Elly Post Avatar answered Oct 23 '22 09:10

Elly Post