Symfony2表单中的额外字段,如何避免它们或修复此问题?

时间:2014-09-04 14:19:21

标签: php symfony symfony-forms

我有OrdersType.php Symfony2表单,其中包含以下代码:

class OrdersType extends AbstractType {

    /**
     * @var string
     */
    protected $register_type;

    public function __construct($register_type)
    {
        $this->register_type = $register_type;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
                ->add('nickname', 'text', array(
                    'required' => FALSE,
                    'label' => "Nickname/Seudónimo",
                    'trim' => TRUE,
                    'attr' => array(
                        'class' => 'nickname'
                    )
                ))
                ->add('email', 'email', array(
                    'required' => TRUE,
                    'label' => "Correo Electrónico",
                    'trim' => TRUE
                ))
                ->add('phone', 'text', array(
                    'required' => TRUE,
                    'label' => 'Números de teléfono (separados por "/")',
                    'trim' => TRUE
                ))
                ->add('fiscal_address', 'textarea', array(
                    'required' => TRUE,
                    'label' => 'Dirección'
                ))
                ->add('shipping_address', 'textarea', array(
                    'required' => TRUE,
                    'label' => 'Dirección de Envío'
                ))
                ->add('shipping_from', 'choice', array(
                    'label' => 'Compañía de Encomiendas',
                    'choices' => SFType::getChoices()
                ))
                ->add('payment_type', 'entity', array(
                    'class' => 'CommonBundle:PaymentType',
                    'property' => 'name',
                    'required' => TRUE,
                    'label' => 'Forma de Pago',
                    'empty_value' => '-- SELECCIONAR --'
                ))
                ->add('order_amount', 'number', array(
                    'label' => 'Monto',
                    'required' => TRUE,
                    'precision' => 2
                ))
                ->add('bank', 'entity', array(
                    'class' => 'CommonBundle:Bank',
                    'property' => 'name',
                    'required' => TRUE,
                    'label' => 'Banco',
                    'empty_value' => '-- SELECCIONAR --'
                ))
                ->add('transaction', 'text', array(
                    'required' => TRUE,
                    'label' => 'No. Transacción'
                ))
                ->add('comments', 'textarea', array(
                    'required' => FALSE,
                    'label' => 'Comentarios'
                ))
                ->add('secure', 'checkbox', array(
                    'label' => FALSE,
                    'required' => FALSE,
                    'value' => 1,
                    'mapped' => FALSE
                ))
                ->add('suscribe_mail_list', 'checkbox', array(
                    'label' => FALSE,
                    'required' => FALSE,
                    'value' => 1,
                    'mapped' => FALSE
        ));

        if ($this->register_type[0] == "natural")
        {
            $builder->add('nat', new NaturalPersonType(), array(
                'mapped' => FALSE
            ));
        }
        elseif ($this->register_type[0] == "legal")
        {
            $builder->add('leg', new LegalPersonType(), array(
                'mapped' => FALSE
            ));
        }
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Tanane\FrontendBundle\Entity\Orders',
            'render_fieldset' => FALSE,
            'show_legend' => FALSE,
            'intention' => 'orders_form'
        ));
    }

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

然后在控制器我有这个:

public function saveAction(Request $request)
{
    $orders = $request->get('orders');
    $sameAddress = $request->get('same_address');

    ladybug_dump($orders);

    // NaturalPerson: 1 | LegalPerson: 2
    $person_type = $orders['nat'] ? 1 : 2;
    $register_type = $orders['nat'] ? array("nat") : array("leg");

    $entityOrder = new Orders();
    $formOrder = $this->createForm(new OrdersType($register_type), $entityOrder);

    $formOrder->handleRequest($request);

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

    if ($formOrder->isValid())
    {
        ....
    }
    else
    {
        $errors = $this->getFormErrors($formOrder);
    }

    return $this->render('FrontendBundle:Site:process.html.twig', array('message' => $message));
}

private function getFormErrors(\Symfony\Component\Form\Form $form)
{
    $errors = array();

    foreach ($form->getErrors() as $key => $error)
    {
        $errors[] = $error->getMessage();
    }

    foreach ($form->all() as $child)
    {
        if (!$child->isValid())
        {
            $errors[$child->getName()] = $this->getFormErrors($child);
        }
    }

    return $errors;
}

当我发送表单时,它会失败并显示以下消息:

  

此表单不应包含额外字段

但是我看不出有问题的字段会被添加到表单中,我怎么能看到它?有关这个常见问题的任何建议吗?

第一次测试

虽然我不需要表格集合,但我按照this doc的说明进行操作,并重写表格如下:

    if ($this->register_type[0] == "natural")
    {
        $builder->add('nat', 'collection', array(
            'type' => new NaturalPersonType(),
            'mapped' => FALSE
        ));
    }
    elseif ($this->register_type[0] == "legal")
    {
        $builder->add('leg', 'collection', array(
            'type' => new LegalPersonType(),
            'mapped' => FALSE
        ));
    }

通过这种方式,关于额外字段的主要错误消失了,但现在我无法渲染字段。我这样做:

{% for item in orderForm.nat %}
    {{ form_widget(item.description, {'attr':{'class':'form-control'}})}}
{% endfor %}

但这不会渲染任何字段。为什么呢?

2 个答案:

答案 0 :(得分:2)

将后期数据绑定到控制器中的表单后

$form->handleRequest

检查值:

$form->getExtraData();

应该有额外的字段

答案 1 :(得分:0)

最后我得到了错误的地方。该问题与mapped=>false无关,但是因为在处理信息持久化的方法中创建和处理表单时,我发送的其他值完全不同。请参阅以下解决问题的代码:

在Controller

创建表单的函数
public function orderAction($type)
{
    $order = new Orders();
    $orderForm = $this->createForm(new OrdersType(array($type)), $order, array('action' => $this->generateUrl('save_order')));

    $template = $type === "natural" ? "FrontendBundle:Natural:natural.html.twig" : "FrontendBundle:Legal:legal.html.twig";
    return $this->render($template, array('order' => $order, "orderForm" => $orderForm->createView()));
}

<强> BEFORE

public function saveAction(Request $request)
{
    $orders = $request->get('orders');
    $sameAddress = $request->get('same_address');

    $register_type = $orders['nat'] ? array("nat") : array("leg");
    $entityOrder = new Orders();
    $formOrder = $this->createForm(new OrdersType($register_type), $entityOrder);

    ...

}

<强> AFTER

public function saveAction(Request $request)
{
    $orders = $request->get('orders');
    $sameAddress = $request->get('same_address');

    $register_type = $orders['nat'] ? array("natural") : array("legal"); // this line fixes the error

    $entityOrder = new Orders();
    $formOrder = $this->createForm(new OrdersType($register_type), $entityOrder);

    ...

}

问题解决了,谢谢