如何在Symfony2中使用一堆不相关的实体创建表单?

时间:2014-12-16 21:27:40

标签: php forms symfony

我正在开发一个日志解析器,它使用数据库表将日志事件“转换”为人类可读的等价物以进行报告。

例如,“start_application_minecraft”等日志条目将转换为“Started Minecraft”

我正在尝试创建一个用于添加/更新显示文本的Web界面,但我无法弄清楚如何将它们放入 Symfony表单对象

我有一个LogEvent实体(包含IDTextDisplayText的属性),我创建了一个与这些属性相对应的表单类型。

它可以一次修改一个事件,但我希望将它们全部放在一个页面上,只需一个提交按钮即可更新所有内容。问题是我在嵌入表单上找到的所有文档都涉及相关的实体(例如包含多个产品的类别),但在我的情况下,我需要处理的所有实体都是完全不相关的。设置它的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

您可以创建表单类型,将所有实体添加为子项。如果您将“数据”设为数组,则可以使用任意数量的表单项。

答案 1 :(得分:1)

使用Symfony'Collection'表单字段类型并使用Doctrine查找所需的LogEvent实体并将其传递给Collection。

示例:http://symfony.com/doc/current/cookbook/form/form_collections.html

参考:http://symfony.com/doc/current/reference/forms/types/collection.html

所以,首先你要创建你的LogEvent表单类型:

class LogEventType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('text');
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'My\Bundle\Entity\LogEvent',
        ));
    }

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

然后创建包含LogEvent实体集合的表单类型:

class MultiLogEventType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add(
            'logEvents', 'collection', array('type' => new LogEventType())
        );
    }

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

然后在您的Controller中,创建表单并将日志事件传递给它:

public function indexAction()
{
    // replace findAll() with a more restrictive query if you need to
    $logEvents = $this->getDoctrine()->getManager()
        ->getRepository('MyBundle:LogEvent')->findAll();

    $form = $this->createForm(
        new MultiLogEventType(),
        array('logEvents' => $logEvents)
    );

    return array('form' => $form->createView());
}

然后在您的编辑操作中,您可以遍历日志事件并执行您需要的任何操作:

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

    $editForm = $this->createForm(new MultiLogEventType());
    $editForm->handleRequest($request);

    if ($editForm->isValid())
    {
        foreach ($logEvents as $logEvent) {
            // perform any logic you need to here
            // (ex: removing the log event; $em->remove($logEvent);)
        }
        $em->flush();
    }

    return $this->redirect($this->generateUrl('log_event_edit'));
}