Laminas validator chain, it works as all the conditions must satisfied then pass, how to make it one condiction satisfied then pass?

What the real requirement is that condition1 or condition2, one of then satisifed, then pass.

But I found the validator chain is the relationship and not or

class CommentMainForm extends Form implements InputFilterProviderInterface
{
    public function init() : void
    {
        $this->add([
            'name' => 'id',
            'type' => Hidden::class,
        ]);

        $this->add([
            'name' => 'threadid',
            'type' => Hidden::class,
        ]);

        $this->add([
            'name' => 'parentid',
            'type' => Hidden::class,
        ]);

        $this->add([
            'name' => 'content',
            'type' => Hidden::class,
        ]);

        $this->add([
            'name' => 'time',
            'type' => Hidden::class,
        ]);

        $this->add([
            'name' => 'formhash',
            'type' => Hidden::class,
        ]);
    }

    public function getInputFilterSpecification() : array
    {
        return [
            [
                'name' => 'id',
                'required' => true,
                'filters' => [
                    ['name' => ToInt::class],
                ],
            ],
            [
                'name' => 'threadid',
                'required' => true,
                'filters' => [
                    ['name' => ToInt::class],
                ],
                'validators' => [
                    [
                        'name' => NotEmpty::class,
                        'options' => ['message' => 'threadid不能为空'],
                    ],
                    [
                        'name' => RecordExists::class,
                        'options' => [
                            'table' => 'thread_main',
                            'field' => 'id',
                            'message' => '帖子不存在',
                        ],
                    ],
                ],
            ],
            [
                'name' => 'parentid',
                'required' => true,
                'filters' => [
                    ['name' => ToInt::class],
                ],
                'validators' => [
                    [
                        'name' => NotEmpty::class,
                        'options' => ['message' => 'parentid不能为空'],
                    ],
                    [
                        'name' => RecordExists::class,
                        'options' => [
                            'table' => 'comment_main',
                            'field' => 'id',
                            'exclude' => [
                                'field' => 'id',
                                'value' => 0,
                            ],
                            'message' => '被回复的评论不存在',
                        ],
                    ],
                ],
            ],
            [
                'name' => 'content',
                'required' => true,
                'filters' => [
                    ['name' => StringTrim::class],
                ],
                'validators' => [
                    [
                        'name' => StringLength::class,
                        'options' => [
                            'encoding' => 'UTF-8',
                            'min' => 6,
                            'max' => 1000, //先写1000试下
                            'message' => '长度6-1000',
                        ],
                    ],
                ],
            ],
            [
                'name' => 'time',
                'required' => true,
                'filters' => [
                    ['name' => ToInt::class],
                ],
                'validators' => [
                    [
                        'name' => NotEmpty::class,
                        'options' => ['message' => 'post时间戳不能为空'],
                    ],
                    [
                        'name' => Callback::class,
                        'options' => [
                            'callback' => function($value,$context){
                                $time = time();
                                $value = (int) $value;
                                if ($value >= $time + 600 || $value < $time - 600)
                                {
                                    return false;
                                }
                                else
                                {
                                    return true;
                                }
                            },
                            'message' => 'post时间戳不对',
                        ],
                    ],
                ],
            ],
            [
                'name' => 'formhash',
                'required' => true,
                'filters' => [
                    ['name' => StripTags::class],
                    ['name' => StringTrim::class],
                ],
                'validators' => [
                    [
                        'name' => NotEmpty::class,
                        'options' => ['message' => 'formhash不能为空'],
                    ],
                    [
                        'name' => FormHashValidator::class,
                        'options' => [
                            'sence' => 'commentpost',
                            'message' => 'formhash计算错误',
                        ],
                    ]
                ],
            ],
        ];
    }
}

as you can see parentid, it can be 0 or a table id(primary key), both ok for me.
I use a exclude option to resolve this problem here.

But let’s think it futher, If not a RecordExists::class validator. I want just to satisfied one of the contion it will pass. how?

I would write a custom validator - called ZeroOrRecordExists or something - to handle the OR logic…

final class ZeroOrRecordExists extends AbstractValidator
{
    private RecordExists $recordExistsValidator;

    public function __construct($options = null)
    {
        $this->recordExistsValidator = new RecordExists($options);
    }

    public function isValid($value) 
    {
        return ($value === 0 || $this->recordExistsValidator->isValid($value);
    }

    public function getMessages()
    {
        return $this->recordExistsValidator->getMessages();
    }
}

Just an idea, and there are probably more methods you’ll need to proxy (err… setOptions() is one), but that’s the idea. (I’ve got a ton of NullOr... ones for a similar purpose).

Ok, thank you! That seems good.