Ad

Check Existence Of Nested Value In Laravel Form Request Validation

I've got the following validation rules:

[
    MenuItem::MENU_ITEM_NAME        => 'required|unique:menu_items,name',
    MenuItem::MENU_ITEM_DESCRIPTION => 'nullable',
    MenuItem::MENU_ITEM_CATEGORY    => 'required|exists:categories,id',
    MenuItem::MENU_ITEM_SIDE        => 'nullable|boolean',
    MenuItem::MENU_ITEM_SIDE_ONLY   => 'nullable|boolean',
    MenuItem::MENU_ITEM_IMAGE       => 'nullable',
    MenuItem::MENU_ITEM_AVAILABLE   => 'nullable|boolean',
    MenuItem::MENU_ITEM_ACTIVE      => 'nullable|boolean',
    MenuItem::MENU_ITEM_PRICING     => 'required',
]

they work fine until this test case that I need to implement:

Pricing aka MenuItem::MENU_ITEM_PRICING is an array of arrays. I need to check that when MenuItem::MENU_ITEM_SIDE is passed as true then the pricing array must contain a subarray with the some values for that specific item.

Ex:

[
    MenuItem::MENU_ITEM_SIDE => false,
    MenuItem::MENU_ITEM_PRICING => []
]

the previous example is valid. But:

[
    MenuItem::MENU_ITEM_SIDE => true,
    MenuItem::MENU_ITEM_PRICING => []
]

is invalid, it should be:

[
    MenuItem::MENU_ITEM_SIDE => false,
    MenuItem::MENU_ITEM_PRICING => [['sideprice' => 2.20]]
]

How can I check (within my FormRequest class) that if MenuItem::MENU_ITEM_SIDE == true then MenuItem::MENU_ITEM_PRICING should contain a subarray with a key named sideprice?

Ad

Answer

You may add after hooks to your form request, just override withValidator method like this:

/**
 * Configure the validator instance.
 *
 * @param  \Illuminate\Validation\Validator  $validator
 * @return void
 */
public function withValidator($validator)
{
    // Check using `sometimes` method
    $validator->sometimes("{MenuItem::MENU_ITEM_PRICING}.*.sideprice", 'required', function ($input) {
        return $input->${MenuItem::MENU_ITEM_SID};
    });

    // Or check using `after` method
    $validator->after(function ($validator) {
        if ($this->input(MenuItem::MENU_ITEM_SID, false)
            && ! \Illuminate\Support\Arr::has($this->input(MenuItem::MENU_ITEM_PRICING, []), '*.sideprice')) {
            $validator->errors()->add('field', 'Something is wrong with this field!');
        }
    });
}

Note: I haven't fully tested this, but it gives you the idea.

Ad
source: stackoverflow.com
Ad