Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 将symfony表单实体类型保存到新实体中作为引用 我在做什么_Php_Forms_Symfony - Fatal编程技术网

Php 将symfony表单实体类型保存到新实体中作为引用 我在做什么

Php 将symfony表单实体类型保存到新实体中作为引用 我在做什么,php,forms,symfony,Php,Forms,Symfony,我正在从3个实体(form/element/option)动态生成一个表单,其中包含表单的元素和(如果适用)选项(考虑复选框/下拉框) Symfony表单的设计目的是设置字段以匹配实体,在实例化时,将该实体的值填充到表单中 但是,我希望填充表单的实体是用户提交实体的实体,但表单是从表单实体构建的。因此,我向自定义表单添加了功能,它从表单实体构建自身,但随后需要提交实体 $formClass = new FormType(); $formClass->setDataModel($formEn

我正在从3个实体(form/element/option)动态生成一个表单,其中包含表单的元素和(如果适用)选项(考虑复选框/下拉框)

Symfony表单的设计目的是设置字段以匹配实体,在实例化时,将该实体的值填充到表单中

但是,我希望填充表单的实体是用户提交实体的实体,但表单是从表单实体构建的。因此,我向自定义表单添加了功能,它从表单实体构建自身,但随后需要提交实体

$formClass = new FormType();
$formClass->setDataModel($formEntity);
$this->createForm($formClass, $submission, array());
什么是/不起作用的 我能够呈现清单元素,这些值是从“表单元素选项”实体中提取的,但是我希望将用户选择保存到“提交元素选项”实体中

对于他们所做的每个选择(选择的每个“表单元素选项”),我希望保存一个“提交元素选项”

清单元素的选项来自FormElementOption实体,但用户提交的内容将是SubmissionElementOption(它引用FormElementOption)

我正在使用问题底部的转换器转换实体,但是当提交之前不存在时-它尝试设置其父级
$subOption->setSubmissionElement($this->element)但不能

在表单
$form->getData()
(如果以前保存,则为实体)为空时,这将作为
$this->element
传递给转换器
如果为null,则新提交选项不能设置其父选项,因此会导致选项
setSubmissionElement
不能为null的错误


在“表单创建”视图中,您有:

[Form] hasMany [Element] hasMany [Option]
[Submission] hasMany [SubmissionElement] hasMany [SubmissionElementOption]
表格:

要素:

id  |  name  |  form_id  |  type
1   |  'a'   |  1        |  'checklist'
2   |  'b'   |  1        |  'checklist'
3   |  'c'   |  1        |  'text'
选项:

id  |  name    |  element_id
1   |  'a'     |  1
2   |  'b'     |  1
3   |  'c'     |  1
4   |  'd'     |  1
5   |  'a'     |  2

从您提交的表格中:

[Form] hasMany [Element] hasMany [Option]
[Submission] hasMany [SubmissionElement] hasMany [SubmissionElementOption]
提交:

id  |  user_id  |  form_id
1   |  1        |  1
提交要素:

id  |  submission_id  |  element_id
1   |  1              |  1
最后是提交元素选项:

id  | submission_element_id  |  option_id
1   | 1                      |  1
2   | 1                      |  2
3   | 1                      |  4

表单是使用FormElement实体中的数据构建的,保存时应返回FormSubmissionElement实体。所以我在这里设置了一个类:

public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
                'data_class' => '\AppBundle\Entity\FormSubmissionElement'
            ));
    }
为了呈现表单的元素,我将FormElement传递给构造函数。
FormChoiceType是扩展EntityType并将元素传递给数据转换器的简单类型

该表单在pre_post_数据事件侦听器中呈现元素:

$form = $event->getForm();
/** @var \AppBundle\Entity\FormSubmissionElement $data */
$data = $event->getData();
...

$submission_options = $data !== null ? $data->getOptions() : null;
$submission_element = $data;
$type = new FormChoiceType($submission_element, $submission_options);
$form->add($element_name, $type, array(
    'by_reference' => false,
    'class' => 'AppBundle:FormElementOption',
    'label' => $element->getLabel(),
    'multiple' => true,
    'expanded' => true,
    'choices' => $element->getMultiOptions(),
    'choice_label' => 'label',
    'mapped' => true,
    'disabled' => $disable_all || $element->isDisabled() ? true : false
));
可选转换器:

    public function __construct($element, $options)
    {
        $this->options = $options;
        $this->element = $element;
    }

    public function transform($options)
    {
        $data = array();

        if($options !== null) {
            foreach($options as $opt) {
                // TODO: Replace this with em->getReference vs EAGER FETCH ON ENTITY
                $data[] = $opt->getOption();
            }
        }


        return $data;
    }  

    public function reverseTransform($options)
    {
        $new = new ArrayCollection();
        foreach($options as $option) {
            $added = false;
            if($this->options !== null) {
                foreach ($this->options as $opt) {

                    // sub exists
                    if ($opt->getOption() != null && $opt->getOption()->getId() == $option->getId()) {
                        $new->add($opt);
                        $added = true;
                    }
                }
            }
            if(!$added) {
                $subOption = new FormSubmissionElementOption();
                $subOption->setOption($option);
                $subOption->setSubmissionElement($this->element);
                $new->add($subOption);
            }
        }
        if($this->element !== null && $this->element->getOptions() !== null) {
            foreach($this->element->getOptions() as $opt) {
                if(!$new->contains($opt)) {
                    $this->element->getOptions()->removeElement($opt);
                }
            }
        }


        return $new;
    }

谢谢你的否决票,没有任何评论,非常有帮助。我想知道你的问题是什么,你有什么问题。谢谢你,我刚刚尽我所能重写了最初的解释。希望这将有助于更好地理解这个问题。旧问题,但如果我理解正确,您正在尝试在数据库中使用表单模式。为此,您需要以下文档:如果您想找到现成的代码,您可能应该搜索使用json模式的项目。