如何允许管理员实时向表单添加额外的未映射字段(Symfony3)

时间:2017-12-28 12:37:15

标签: php forms multi-tenant symfony-3.3

我有一个Symfony3项目,可以帮助多个管理员/租户为其用户创建自定义表单。 TenantData是包含Salutation,firstname和lastname字段的主要实体。基于此实体,租户/管理员可以创建表单TenantDataType。以下是TenantDataType的样子:

<?php

namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Entity\TenantData;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class TenantDataType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder->add('firstname', TextType::class, array());
        $builder->add('lastname', TextType::class, array());
        $builder->add('title', ChoiceType::class, array(
            'choices' => array(
                'Ms' => true,
                'Mr' => false,
            ),
        ));
        $builder->add('save', SubmitType::class, array('label' => 'Submit'));
    }

    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(array(
            'data_class' => TenantData::class,
            'csrf_protection' => true,
            'allow_extra_fields' => true
        ));
    }

}

现在我希望管理员能够添加额外的字段,而无需在TenantData实体中添加额外的列。我知道的一种方法是创建一个MetaData表,其中包含label,datatype,isrequired和ismultiple字段。基于此实体,我可以使用名称MetaDataType创建新表单。这样管理员就可以使用此表单来创建额外的字段。这基本上意味着MetaData表的每条记录都包含额外字段的详细信息。问题是如何使用这些记录实时呈现管理员/租户添加的额外字段。由于我在渲染表单时创建了TenantData的新实例,并且当时没有TenantData id可以获取相关的MetaData行。我需要建立什么样的关系才能获得所需的功能。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

让我们假设您的formBuilder如上所示进行了一些修改:

<强> TenantDataType

 <?php

    namespace AppBundle\Form\Type;

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    use AppBundle\Entity\TenantData;
    use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
    use Symfony\Component\Form\Extension\Core\Type\TextType;
    use Symfony\Component\Form\Extension\Core\Type\SubmitType;

    class TenantDataType extends AbstractType {

        public function buildForm(FormBuilderInterface $builder, array $options) {

            $builder->add('firstname', TextType::class, array());
            $builder->add('lastname', TextType::class, array());
             if(isset($option['userRole'] && $option['userRole']=="ADMIN_ROLE" ){
             $builder->add('your_admin_field', TextType::class, array());
              }  

            $builder->add('title', ChoiceType::class, array(
                'choices' => array(
                    'Ms' => true,
                    'Mr' => false,
                ),
            ));
            $builder->add('save', SubmitType::class, array('label' => 'Submit'));
        }

        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => TenantData::class,
                'csrf_protection' => true,
                'allow_extra_fields' => true
            ));
        }

    }

让我们假设租户用户有:TENANT_ROLE

和admin有:ADMIN_ROLE

<强>控制器

$user_role= // get the user role here . (TENANT_ROLE/ADMIN_ROLE)
    $form = $this->createForm(TenantDataType ::class, $tenantObject, array(
        'userRole' => $user_role,
    );

如果要从addEventListener访问$ options数组:

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    $user_role = $event->getForm()->getConfig()->getOptions()['userRole'];
}