使用数组而不是实体生成symfony表单?

时间:2016-05-09 14:28:23

标签: arrays forms symfony

我正在尝试生成一个我认为只需要两个实体的表单。然而,我设法让它工作的唯一方法是使用三个。我可以使用的表单,但它非常慢,因为每个实体的数据库中都有很多记录。我应该采用哪种更聪明的方式处理这个问题?

我想要实现的是数据库中每个 customer 实体的嵌套InvoiceType表单。然后,管理员用户应该能够勾选/取消他们想要为其生成一批发票的客户。看起来应该是这样的:

| Generate Invoice? | Customer   | Amount   | Date       | Notes     |
|-------------------|------------|----------|------------|-----------|
| ☑                |  Customer1 | 100.00   | 2016-05-08 |-----------|
| ☐                |  Customer2 | 105.55   | 2016-05-09 |-----------|

目前,我通过使用三个实体来实现它。我创建了一个 Invoicebatch 实体,以便识别 Invoice 属于哪个批次(如果有的话)。但是,由于我需要为数据库中的每个 Customer 创建一个新的Invoice对象,我将(我认为)每个Customer对象加载到我的控制器中的表单对象中:

public function batchInvoicesAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $customers = $em->getRepository('AppBundle:Customer')->findAll();
    $batch = new InvoiceBatch();
    foreach ($customers as $customer) {
        $invoice = new Invoice();
        $invoice->setCustomerId($customer);
        $invoice->setSelected(True);
        $invoice->setCreatedate(new \Datetime());
        $invoice->setAmount($customer->getDefaultinvoiceamount());
        $invoice->setinvoicebatchid($batch);
        $batch->addInvoiceId($invoice);
    }
    $form = $this->createForm(InvoiceBatchType::class, $batch);
    $form->handleRequest($request);

    if ($form->isSubmitted() && ($form->isValid())) {
        $batchform = $form->getData();
        foreach ($batchform->getInvoiceids() as $invoiceform) {
            if ($invoiceform->getSelected() == False) {
                $batchform->removeInvoiceId($invoiceform);
            } else {
                $em->persist($invoiceform);
            }
        }
        $em->persist($batchform);
        $em->flush();
        return $this->redirectToRoute('view_monthly_invoices');
    }
    return $this->render('invoices/new.batch.invoice.html.twig')
}

我的InvoiceBatchType如下:

class InvoiceBatchType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('batchevent', TextType::class, array(
            ))
            ->add('invoice_ids', CollectionType::class, array(
                'entry_type' => InvoiceForBulkType::class,
            ))
        ;
    }

我的InvoiceForBulkType是:

class InvoiceForBulkType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('selected', CheckboxType::class, array(
                'label'    => ' ',
                'required' => false,
            ))
            ->add('customer_id', EntityType::class, array(
                    'class' => 'AppBundle:Customer',
                    'choice_label' => 'FullName',
                    'label'=>'Customer',
                    'disabled'=>true,
                )
            )
            ->add('amount', TextType::class, array(
                'label' => 'Amount',
            ))

            ->add('invoicedate', DateType::class, array(
                'widget' => 'single_text',
                'data' => new \DateTime('now'),
                'format' => 'dd/MMM/yyyy',
                'label' => 'Date of invoice',
                'attr'=> array(
                    'class'=>'datepicker',
                )
            ))

            ->add('description', TextType::class, array(
                'required'=>false,
            ))
        ;
    }
}

我原以为可以将客户名称加载为数组,因为我只想在每一行上显示客户名称(即没有下拉列表或其他表单元素)。我已尝试过几次尝试,但没有运气,所以我认为$customer对象需要包含在Symfony的后台进程中我不知道(我之间有OneToMany个关联kbd>客户和发票)。

1 个答案:

答案 0 :(得分:1)

我设法让这个工作到最后 - 问题是我不知道在Symfony表单中传递实体的选项。我试图总结下面的理论/逻辑,希望它能帮助其他任何努力摆脱Symfony形式的人:

阅读了Symfony Form documentation我错误地认为只有EntityTypeCollectionType可以处理接收实体作为输入。因此,我的InvoiceForBatchType导致了问题 - 它将所有 Customers 加载到每个 Invoice 中。

我对Symfony表格缺少的关键概念是:

  

如果您要传递的是您希望能够访问的实体,那么使用EntityType(除非您想填充下拉列表/收音机/刻度线)。而是创建一个新文件来定义嵌套的FormType

在我的案例中,这是一个简单的解决方法:

1.将 InvoiceForBulkType 更新为:
class InvoiceForBulkType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            /* ... */

            ->add('customer_id', CustomerForInvoiceType::class)

            /* ... */
        ;
    }
}
2.创建 CustomerForInvoiceType
class CustomerForInvoice extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('fullname', TextType::class, array(
            ))
        ;
    }

    /* ... */
}
相关问题