将约束传递给 symfony 集合类型

Passing constraints to symfony collection type

Symfony 2.8。我使用带有自定义条目的集合作为表单,并传递了一些约束。现在我的代码看起来像:

FirstFormType.php:

class FirstFormType extends AbstractFormType
{
    /** @inheritdoc */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('rates', CollectionType::class, [
                'entry_type'   => new SecondFormType([new LessThanOrEqual(300)]),
                'allow_add'    => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'constraints'  => [
                    new NotBlank(),
                    new Count(['min' => 1]),
                ],
            ])
        ;
    }
}

SecondFormType.php:

class SecondFormType extends AbstractFormType
{
    /** @var array */
    private $constraints;

    /** @param array $constraints */
    public function __construct(array $constraints = [])
    {
        $this->constraints = $constraints;
    }

    /** @inheritdoc */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('amount', NumberType::class, [
                'scale'       => 2,
                'constraints' => array_merge($this->constraints, [new CustomConstraint()]),
            ])
        ;
    }
}

我还有 ThirdFormType,它与 FirstFormType 相同,但有其他限制传递给 SecondFormType。但是我想把new SecondFormType([...])换成FQCN,我觉得可以更正确的继承约束。你知道我该怎么做吗?

从表单类型迁移此类构造函数参数的推荐方法是为它们创建表单选项,如下所示:

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefault('amount_constraints', array());
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('amount', NumberType::class, [
            'scale' => 2,
            'constraints' => array_merge($options['amount_constraints'], [new CustomConstraint()]),
        ])
    ;
}

那么,您的新选项的用法如下所示:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('rates', CollectionType::class, [
            'entry_type'   => SecondFormType::class,
            'entry_options' => [
                'amount_constraints' => [new LessThanOrEqual(300)], 
            ],
            // ...
        ])
    ;
}