Symfony2 表单选项解析

Symfony2 Form Option Resolution

我正在使用 FOSUserBundle 并尝试使用 is_admin 选项自定义用户注册表单 .我不知道为什么选项值没有从 createForm() 函数调用传递给 buildForm() 函数。

控制器中对应代码如下:

$has_admin_rights = $this->get('security.authorization_checker')
->isGranted('ROLE_SUPER_ADMIN');
/** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
/** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->createUser();
...
$form = $formFactory->createForm(
new RegistrationFormType(), $user, array('is_admin' => $has_admin_rights));

下面是自定义表单 class,理论上应该解析 is_admin 选项。但是似乎该选项未正确传递。

class RegistrationFormType extends AbstractType
{
      public function buildForm(FormBuilderInterface $builder, array $options)
{
    if($options['is_admin'] === true)
    {
        $builder->add('uniqueRole', 'choice', array(
            'choices' => array('ROLE_ADMIN' => 'user.role.admin',
                'ROLE_TEACHER' => 'user.role.teacher',
                'ROLE_STUDENT' => 'user.role.student'),
            'label' => 'form.label.role',
            'expanded' => false,
            'multiple' => false,
            'mapped' => false
            ));
        $builder->remove('plainPassword')->add('plainPassword', 'hidden', array('data' => 'defaultPwd'));
    } else {
        // Default value is indeed set, 
        // and options[is_admin] always equals to false
        if (array_key_exists("is_admin", $options)){
            echo 'Set!';
        } else {
            echo 'Not Set!';
        }
    }
    $builder->add('save', 'submit', array('label' => 'actions.add'));
}

protected function configureOptions(OptionsResolver $resolver)
{
    $resolver->setRequired(array(
        'is_admin'));
    $resolver->setDefaults(array(
        'is_admin' => false,
        'data_class' => 'VMB\UserBundle\Entity\User',
        'intention'  => 'registration',
    ));
}

// BC for SF < 2.7
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $this->configureOptions($resolver);
}

public function getParent()
{
    return 'fos_user_registration';
}

public function getName()
{
    return 'vmb_user_registration';
}
}

我也试过用这种方式将参数传递给构造函数

$form = $formFactory->createForm(new RegistrationFormType($has_admin_rights), $user);

然而,symfony2 appCache 在没有正确参数值的情况下初始化表单对象(返回到定义的 null 默认值)。 我做错了什么?

我认为这只是调用错误服务的问题。

您通过以下方式获得了FormFactory的实例:

$formFactory = $this->get('fos_user.registration.form.factory');

但这不是 Symfony 的 FormFactory。事实上,如果您查看它的来源 here,您会看到:

public function createForm()
{
    return $this->formFactory->createNamed($this->name, $this->type, null, array('validation_groups' => $this->validationGroups));
}

基本上,createForm 根本不需要任何参数。

因此,您应该使用 Symfony 自己的 form.factory (source):

$has_admin_rights = $this->get('security.authorization_checker')->isGranted('ROLE_SUPER_ADMIN');

/** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('form.factory');

/** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');

$user = $userManager->createUser();

$form = $formFactory
    ->createBuilder(new RegistrationFormType(), $user, array('is_admin' => $has_admin_rights))
    ->getForm();

希望这对您有所帮助...