Symfony2 - 如何根据db的动态参数创建表单? (EAV)

时间:2011-09-06 07:38:46

标签: forms symfony entity-attribute-value

我想基于存储在DB中的动态参数创建表单。 所以我创建了一个名为Parameter的实体来定义参数名称,该实体应该显示为表单字段标签。

/**
 * @ORM\Entity
 */
class Parameter
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\Column(type="string", length="255")
     * @Assert\NotBlank()
     */
    protected $name; 
    /**
     * @ORM\OneToMany(targetEntity="ParameterValue", mappedBy="parameter")
     */
    protected $values;

特定对象(公司对象)的参数值即将存储在ParameterValue表格中。

/**
 * @ORM\Entity
 */
class ParameterValue
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\ManyToOne(targetEntity="Parameter", inversedBy="values")
     * @ORM\JoinColumn(name="parameter_id", referencedColumnName="id", nullable=false)
     */
    protected $parameter;
    /**
     * @ORM\ManyToOne(targetEntity="Company", inversedBy="parameters")
     * @ORM\JoinColumn(name="company_id", referencedColumnName="id", nullable=false)
     */
    protected $company;

当然,公司实体包含参数属性,该属性仅存储已为公司指定的参数。

/**
 * @ORM\Entity
 */
class Company
{    
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\Column(type="string", length="255")
     */
    protected $name;
    /**
     * @ORM\OneToMany(targetEntity="ParameterValue", mappedBy="hotel")
     */
    protected $parameters;

如何创建从DB动态获取所有参数的Form,创建具有特定标签的文本字段(label = Parameter-> getName())并获取已与公司关联的参数的ParameterValues(用于编辑操作) ?

我已经创建了获取ParameterValues的'collection'字段,但问题是我获得的表单包含已用于公司但没有其他参数的参数字段。当然我无法获得标签,因为集合字段类型是ParameterType而不是参数。

1 个答案:

答案 0 :(得分:14)

我最近不得不做类似的事情。我将分享我的经验并尝试纳入您的观点。您可能需要修改一些以满足您的需要。

我的公司实体与您的公司实体相似。我希望每个公司都存储有动态数量的参数和值,并使用symfony2表单框架在表单中编辑这些参数和值。

我首先创建了一个名为CompanyParameter的实体。添加命名空间并保存在捆绑包中的某个位置。

    class CompanyParameter {    
        protected $data;    
        public function __construct($parameters,$edit=false)
        {
               if ($edit==false) {
                foreach ($parameters as $k => $value) {
                        $name = $value->getId();
                        $this->data[$name] = array("label"=>$value->getName(),"value"=>"");
                        $this->{$name} = "";                    
                }
                } else {
                foreach ($parameters as $k => $value) {
                        $name = $value->getParameterid();
                        $pvalue = $value->getValue();
                        $this->data[$name] = array("label"=>$value->getName(),"value"=>$pvalue);
                        $this->{$name} = $pvalue;                    
                }
}
        }    
        public function get() { return $this->data; }    
    }

使用类创建一个新变量并将参数发送给它。

$parameters = $em->getRepository("YourBundle:Parameter")->findAll();
$companyparameter = new CompanyParameter($parameters);

您现在拥有一个包含您要管理的所有动态参数的实体。 (如果要加载带有已存储值的CompanyParameter以进行编辑,只需向CompanyParameter发送一个ParameterValue实体数组,并在构造函数中设置$ edit = true。

创建一个如http://symfony.com/doc/current/book/forms.html#creating-form-classes所述的CompanyParameterFormType 确保data_class指向CompanyParameter

在您的控制器中创建一个新表单:

$form = $this->createForm(new CompanyParameterTypeBundle(), $companyparameter);

在CompanyParameterFormType中:

    public function buildForm(FormBuilder $builder, array $options)
    {
        $data = $options["data"]->get();      
        foreach ($data as $k => $value) {
             $builder->add($k,"text",array("label"=>$value["label"]));
        }           
    }

如果我们要$ form-> createView(),我们现在有一个表格,其中包含两个字段“公司名称”和“CEO”。

填写表格并将表格的提交发送回同一行动。

在post和$ form-> bindRequest($ this-> getRequest())的操作检查中。

CompanyParameter现在包含属于当前公司的参数的所有值。要保留这些数据:

$data = $companyparameter->get();
$counter = 0;
foreach($data as $k => $value) {
$parameter = new ParameterValue();
$parameter->setCompany($company);
$parameter->setParameter($parameters[$counter]);
$parameter->setValue($value["value"]);
$em->persist($parameter);
$counter++;
}

如果您正在编辑参数

$data = $companyparameter->get();
foreach ($parameters as $k => $value) {
$value->setValue($data[$value->getParameterid()]["value"]);
$em->persist($value);
}

希望这会有所帮助。我第一次发帖并且我不习惯“解释”代码,所以请记住。