对非对象使用表达式约束

Use Expression constrainst on non object

我有一个类似的表格:

class FeatureDynamicSequenceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('upstream', IntegerType::class, [
                'data' => 0,
                'constraints' => [
                    new LessThan([
                        'value' => 1000,
                    ]),
                ],
            ])
            ->add('downstream', IntegerType::class, [
                'data' => 0,
                'constraints' => [
                    new LessThan([
                        'value' => 1000,
                    ]),
                ],
            ])
            ->add('showUtr', CheckboxType::class,[
                'data' => true,
                'label' => 'Show UTR',
                'required' => false,
            ])
            ->add('showIntron', CheckboxType::class,[
                'data' => true,
                'required' => false,
            ])
        ;
    }
}

在这个表格中,我想添加一个 Constrainst 检查: 如果不勾选showUtr或ShowIntron,则upstream和downstreal不能>到0。

那我想要类似的东西:

->add('upstream', IntegerType::class, [
    'data' => 0,
    'constraints' => [
        new LessThan([
            'value' => 1000,
        ]),
        new Expression([
            'expression' => 'value > 0 && (this.showUtr || this.showIntron)',
            'message' => 'You cannot set upstream if you do not display UTRs and introns.',
        ]),
    ],
])

但是我不能使用它,因为它不是一个对象,value 给我上游字段的值(没关系),但是我无法访问 showUtr 或 showIntron 值...

编辑:尝试使用回调闭包

->add('upstream', IntegerType::class, [
    'data' => 0,
    'constraints' => [
        new LessThan([
            'value' => 1000,
        ]),
        new Callback([
            'callback' => function($data, ExecutionContextInterface $executionContectInterface) {
                dump($data);
                $executionContectInterface->addViolation('You cannot set upstream if you do not display UTRs and introns.');
            },

        ])
    ],
])

我有同样的问题,$data 只包含字段值。

我真的不想创建一个实体,因为我不坚持它...而且我无法相信没有创建实体就可以检查它的解决方案。

我在上一个问题中回答过here

我通过使用解决了它:

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'constraints' => [
            new Callback([
                'callback' => function($data, ExecutionContextInterface $executionContectInterface) {
                    if ($data['upstream'] > 0 && (!$data['showUtr'] || !$data['showIntron'])) {
                        $executionContectInterface->buildViolation('You cannot set upstream if you do not display UTRs and introns.')
                            ->atPath('[upstream]')
                            ->addViolation()
                        ;
                    }
                },
            ]),
        ],
    ]);
}

完整代码为:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('upstream', IntegerType::class, [
            'data' => 0,
            'constraints' => [
                new LessThan([
                    'value' => 1000,
                ]),
            ],
        ])
        ->add('downstream', IntegerType::class, [
            'data' => 0,
            'constraints' => [
                new LessThan([
                    'value' => 1000,
                ]),
            ],
        ])
        ->add('showUtr', CheckboxType::class, [
            'data' => true,
            'label' => 'Show UTR',
            'required' => false,
        ])
        ->add('showIntron', CheckboxType::class, [
            'data' => true,
            'required' => false,
        ])
    ;
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'constraints' => [
            new Callback([
                'callback' => function($data, ExecutionContextInterface $executionContectInterface) {
                    if ($data['upstream'] > 0 && (!$data['showUtr'] || !$data['showIntron'])) {
                        $executionContectInterface->buildViolation('You cannot set upstream if you do not display UTRs and introns.')
                            ->atPath('[upstream]')
                            ->addViolation()
                        ;
                    }
                },
            ]),
        ],
    ]);
}