Search code examples
phpvalidationyii2rules

Yii2 how to handle required field one of two for two different models


I have two forms to validate for phone number and email where input fields I am generating with \kidzen\dynamicform\DynamicFormWidget

Phone number form rules:

<?php


namespace common\models\form;


    class Telephone extends someExtend
    {
        /**
         * @inheritdoc
         */
        public function rules()
        {
            return [
                ['value', 'trim'],
                [['value'], 'required'],
                [['value'], 'string', 'max' => 26],
                [['value'], 'match', 'pattern' => "/^\\+?\\d{1,4}?[-.\\s]?\\(?\\d{1,3}?\\)?[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,4}[-.\\s]?\\d{1,9}$/" ,
                    'message' => \Yii::t('models', 'Invalid Phone Number Format')]
            ];
        }
    }

Email rules:

<?php


namespace common\models\form;


class Email extends someExtend
{
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            ['value', 'trim'],
            [['value'], 'required'],
            [['value'], 'string', 'max' => 512],
            [['value'], 'match', 'pattern' => "/^[a-z0-9!#$%&'*+\\/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+\\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/",
                'message' => \Yii::t('models', 'Invalid Email Format')]
        ];
    }
}

they are a part of bigger form

<?php

namespace common\models\form;

/*  some uses */
/**
 * @property Email[] $sender_email
 * @property Telephone[] $sender_telephone
 */
class UpdateContentsForm extends Model
{
    public array $sender_email = [];
    public array $sender_telephone = [];

    public function __construct($config = [])
    {
        parent::__construct($config);
    }

    public function attributeLabels()
    {
        return [
            'sender_telephone' => Yii::t('models', 'Sender Telephone'),
            'sender_email' => Yii::t('models', 'Sender Email'),
        ];
    }

    public function rules()
    {
        return [
            // Rules for other fields in this form model
        ];
    }

On submit I call UpdateContentsForm. How can I validate that one of those two is required if in UpdateContentsForm they both are arrays from 1 - 3 elements?

If you need some more information, please feel free to ask and I will modify information shortly.


Solution

  • You must use 'when' property of the validator

    public function rules()
            {
                return [
                    ...,
                    [['value'], 'required', 'when' => function($model) {
                        // make the validation
                        if ($isValid) {
                            return true; // run the required validation
                        }
                        return false; // dont run the required validation
                    }],
                ];
            }