如果规则是字段相关的,如何在ZF2 / Apigility中设置输入验证?

There is a class Item. It has an attribute type, that can be a, b, or c. For all the types there is a common minimal set of attributes / input fields: type and other ones. Every type has some further attributes:

default set of the common fields
  type
  ...
additional fields in case of type=a
  foo
additional fields in case of type=b
  bar
  baz
additional fields in case of type=c
  bar
  baz
  buz

Furthermore the validation rules for bar and bar are slightly different for the cases type=b and type=c.

How to set up the validation in a ZF2/Apigilty application depending on the value of a field (or multiple fields)? For this concrete case: How to set up the validation depending on the type?


UPDATE

The attribute type is an independent one. That means -- it should not become invalid, if the set of the additional fields (foo, bar etc.) doesn't match to it. (It's required and gets validated agains an array of the allowed values, that's it.)

So, it should work in the opposite direction:

IF (type == 'a') {
    proper "required" and validation rules the additional fields
} ELSEIF (type == 'b') {
    proper "required" and validation rules the additional fields
} ELSEIF (type == 'c') {
    proper "required" and validation rules the additional fields
}

You can write a ValidTypeInputFilter with your custom logic and attach a config that looks something similar like this:

array(
    'type' => array(
        'name' => 'type',
        'required' => true,
        'validators' => array(
            array(
                'name' => 'CustomTypeValidator'
            )
        )
    ),
    'qwer' => array(
        'name' => 'qwer',
        'required' => true,
        'filters' => array(
        )
        'validators' => array(
        )
    ),
    'asdf' => array(
        'name' => 'asdf',
        'required' => true,
        'filters' => array(
        )
        'validators' => array(
        )
    ),
    'yxcv' => array(
        'name' => 'yxcv',
        'required' => true,
        'filters' => array(
        )
        'validators' => array(
        )
    )
)

And your custom validator class:

<?php
namespace Application\Validator;

class CustomTypeValidator extends AbstractValidator{

    const INVALID_TYPE = 'invalid_type';    

    const NOT_ARRAY = 'not_an_array';    

    protected $messageTemplates = array(
        self::NOT_ARRAY => "Type must be an array",
        self::INVALID_TYPE => "Type must be a, b or c",
    );

    public function isValid($value)
    {
        $this->setValue($value);

        if (!is_array($value)) {
            $this->error(self::NOT_ARRAY);
            return false;
        }

        if(key($value) === 'a'){
            //... validate a
        }

        if(key($value) === 'b'){
            //... validate b
        }

        if(key($value) === 'c'){
            //... validate c
        }

        $this->error(self::INVALID_TYPE);
        return false;
    }
}

For validating a, b and c you can also write validator classes and instantiate and use them inside your custom type validator:

    if(key($value) === 'a'){
        $validator = new TypeAValidator():
        $valid = $validator->isValid($value['a']);
        return $valid;
    }