在非对象上使用Expression约束

时间:2017-10-06 08:01:23

标签: symfony symfony-forms

我有一个类似的表格:

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,那么上游和下游不能是>到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.',
        ]),
    ],
])

但我无法使用它,因为它不是一个对象,价值给了我上游字段的价值(没关系),但我无法访问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只包含字段值。

我真的不想创建一个实体,因为我不会坚持它......而且我无法相信没有一个解决方案可以在没有创建实体的情况下进行检查。< / p>

2 个答案:

答案 0 :(得分:1)

我在上一个问题here

中回答

答案 1 :(得分:1)

我通过使用:

解决了它
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()
                        ;
                    }
                },
            ]),
        ],
    ]);
}