根据FormType中的另一个选项值定义表单选项允许值

时间:2016-02-04 15:22:06

标签: symfony configuration symfony-forms options

在Symfony 2.8中,在自定义表单类型中,是否可以使setAllowedValues返回依赖于另一个选项的值的结果?就我所见,没有一种明显的方法可以访问闭包中的Options对象。

public function configureOptions(OptionsResolver $resolver) {
    $resolver->setRequired('option1');
    $resolver->setRequired('option2');

    $resolver->setAllowedValues('option2', function ($value) {
        return $based_on_set_restricted_by_option1; // <-- option2 values are allowed or denied depending on what option1 says
    }
}

我所拥有的解决方案最接近的想法是有一个选项,它是一个封装了option1和option2的字典,并在其上执行setAllowedValues,但现在重组这些选项并不容易。

1 个答案:

答案 0 :(得分:5)

symfony表单类型的方法configureOptions()可以做很多事情,因为它提供了一个OptionsResolver对象(依赖于它自己的组件see)来调整你的配置。

在这种情况下,您需要调用$resolver->setNormalizer()see),它完全符合您的要求,只要设置了其他设置并且可以调用,就需要选择。

当解析器规范化您的选项时,它会通过将所有选项的数组作为第一个参数传递来执行callable,并将选项的设置值作为第二个参数进行规范化:

// class CustomFormType extends \Symfony\Component\Form\Extension\Core\Type\AbstractType

use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefault('some_option', 'default value');

    // or many at once
    $resolver->setDefaults(array(
        'some_option' => 0,
        'range_condition' => null,
    );

    // what you need
    $someOptionNormalizer = function (Options $options, $someOption) {
        $rangeCondition = $options['range_condition'];

        if (in_array($rangeCondition, range(2, 5))) {
            if (in_array($someOption, range(6, 9))) {

                return $someOption;
            }

            throw new InvalidOptionsException(sprintf('When "range_condition" is inferior or equal to 5, "some_option" should be between 6 and 9, but "%d" given.', $someOption));
        }

        if (in_array($rangeCondition, range(10, 13))) {
            if (in_array($someOption, range(1000, 1005))) {

                return $someOption;
            }

            throw new InvalidOptionsException(sprintf('When "range_condition" is between 10 and 13, "some_option" should be between 1000 and 1005, but "%d" given.', $someOption));
        }
    };

    $resolver->setNormalizer('some_option', $someOptionNormalizer);

    // you can also do
    $resolver->setRequired('some_option');
    $resolver->setAllowedTypes('some_option', array('integer'));
    $resolver->setAllowedTypes('range_condition', array('null', 'integer'));
    $resolver->setAllowedValues('some_option', array_merge(range(6, 9), range(1000, 1005)));
    $resolver->setAllowedValues('range_condition', array_merge(range(2, 5), range(10, 13)));

    // ...

}