php - 在表单验证之前设置实体参数

标签 php symfony symfony-forms

[设置]

  • Symfony 3
  • BoxEntity:[id,名称]
  • CandyEntity:[id,名称]

[问题]

目前,在创建新糖果时,我必须选择一个盒子作为父实体。
问题是,我希望这个选择能够自动化。
该盒子已在数据库中注册,并且 session 保存当前盒子参数以便轻松找到它。
但我不知道在数据发布后如何将其应用到糖果实体。

[文件]

AppBundle/Controller/CandyController.php

public function newAction(Request $request) {
    $$candy= new Candy();
    $form = $this->createForm('AppBundle\Form\CandyType', $conference);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($candy);
        $em->flush();

        return $this->redirectToRoute('candy_show', array('id' => $candy->getId()));
    }

    return $this->render('candy/new.html.twig', array(
        'candy' => $candy,
        'form' => $form->createView(),
    ));
}

AppBundle/Form/CandyType.php

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('nom')
            ->add('box'); //Remove from form, and set manually
}

我做了read this page ,但不知道如何正确地做到这一点。
如果有人愿意给我一个完整的例子来解决我的问题,我将不胜感激。

最佳答案

您有多种选择来执行您想要的操作。您可以在表单提交后设置该值:

public function newAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();

    $candy = new Candy();
    $box = $em->find('AppBundle\Entity\Box', $this->get('session')->get('boxId'));

    $form = $this->createForm('AppBundle\Form\CandyType', $candy);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        // add the box entity to the candy
        $candy->setBox($box);

        $em->persist($candy);
        $em->flush();

        return $this->redirectToRoute('candy_show', array('id' => $candy->getId()));
    }

    return $this->render('candy/new.html.twig', array(
        'candy' => $candy,
        'form' => $form->createView(),
    ));
}

您可以在将 Candy 实体传递给 createForm() 调用之前将其设置在 Candy 实体上,尽管在执行表单 handleRequest() 后它可能不会保留在实体上调用:

    $em = $this->getDoctrine()->getManager();

    $candy = new Candy();
    $box = $em->find('AppBundle\Entity\Box', $this->get('session')->get('boxId'));

    $candy->setBox($box);

    $form = $this->createForm('AppBundle\Form\CandyType', $candy);
    $form->handleRequest($request);

您可以按照您尝试的方式在表单事件中执行此操作。您想要做的是将实体管理器和 session 注入(inject)到您的表单中,并将您的表单视为服务:

public function CandyType extends AbstractType
{
    private $em;
    private $session;

    public function __construct(EntityManager $em, SessionInterface $session)
    {
        $this->session = $session;
        $this->em      = $em;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ... build the form

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function (FormEvent $event) {
                $form = $event->getForm();

                $candy = $event->getData();
                $box = $this->em->find('AppBundle\Entity\Box', $this->session->get('boxId');

                $candy->setBox($box);
            }
        );
    }
}

您可能需要在 POST_SET_DATAPOST_SUBMIT 事件上执行此操作,但我不确定。另外,我在 Controller 中使用了 $this->get('session') ,但根据您的 Symfony 版本 (> 3.3),您也可以将其作为服务注入(inject)到 Controller 中。

无论哪种方式,主要概念都是使用 Doctrine 使用 session 中存储的盒子 ID 从 session 本身获取 Box 实体,然后将其设置在 Candy 实体上。您甚至可以使用隐藏字段来实现相同的结果。正如我之前所说,有很多方法可以解决您的问题。

关于php - 在表单验证之前设置实体参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45900820/

相关文章:

php - APC Cache 仅使用 32M 内存

php - symfony 2 - 一对一映射

forms - 未定义的方法 Symfony\Component\Form\FormBuilder::createView()

symfony - 如何删除 symfony 形式的默认 ID 和名称?

php - 标准化阿拉伯语文本mysql

javascript - 如果没有要显示的数据,PHP 如何返回一个空的 json 数组

php - 如何从mysql到php对月份进行排序

php - symfony2 XLIFF 中的换行符 <br>

Symfony2 getter、setter、添加和删除

php - 如何在 symfony2 中为实体 ManyToOne 关系嵌入表单?