Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

johnvoncolln's avatar

Validating Array Item with Rule Class

What I'm trying to do with the Rule is basically require the image_name field if the userProduct associated with the lineItem being validated has a true boolean for the attribute is_template_product...

BUT, how do I access the lineItem model within the callback of the rule?

$rules = [
    //
    'line_items.*.image_name' => [
        'nullable',
        'required_with:line_items.*.image_url',
        'alpha_dash',
        Rule::requiredIf(function() {
            //lineItem->userProduct->is_template_product
        })
]
];
0 likes
2 replies
kevinbui's avatar
kevinbui
Best Answer
Level 41

I have just solved a somewhat similar problem with validation. I think when we need to apply a COMPLEX validation rule that involves MULTIPLE attributes in the same request, an after hook can be implemented:

class YourRequest extends FormRequest
{
    public function withValidator($validator)
    {
        $validator->after(function ($validator) {
            foreach ($this->input('line_items') as $index => $lineItem) {
                if ($lineItem->userProduct->is_template_product && ! Arr::get($lineItem, 'image_name')) {
                    $validator->errors()->add("line_items.{$index}.image_name", 'Image name is required.');
                }    
            }
        });
    }

    public function rules()
    {
        return [
            // ...
        ];
    }
}
johnvoncolln's avatar

I finally got around to looking into hooks and I got my validation working. Here's what I did in case it might help someone in the future:

$validator = Validator::make($item, $rules, $messages);

$validator->after(function($validator) use ($item) {
    foreach ($item['line_items'] as $index => $lineItem) {
        $userProduct = UserProduct::where('user_sku', $lineItem['sku'])->first();
        if ($userProduct->is_template_product) {
            if (!array_key_exists('image_name', $lineItem) && !array_key_exists('image_url', $lineItem)) {
                $validator->errors()->add("line_items.{$index}", 'The image_name or image_url is required when using a template product.');
            }
        }
    }
});

$validator->validate();

Because I was validating in a POPO and validating an array, not a request, I had to change a few things up...

I wanted to validate that if the userProduct (that lineItem represents) has the is_template_product flag as true, AND both image_name and image_url are not present, throw an error for the line item

Please or to participate in this conversation.