【问题标题】:Symfony2.3: Validation errors not renderedSymfony2.3:未呈现验证错误
【发布时间】:2013-09-16 03:04:18
【问题描述】:

联系表单指定一组家庭的日期、类型和配送中心。 [家庭集被定义为该中心的最新家庭,并通过 ajax 呈现。] 类型实体是必需的,日期不得为将来。类型约束在 Contact 实体中指定;日期约束在自定义验证器中。如果违反了这些约束中的任何一个,则该表单在 Netbeans 调试中确认为无效。此外,错误消息出现在 Netbeans 中。然而,模板中都没有出现任何约束消息。将 form_errors 转储添加到模板中没有任何作用。我无法确定为什么没有消息出现。

联系实体sn-p:

namespace Mana\ClientBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Mana\ClientBundle\Validator\Constraints as ManaAssert;

/**
 * Contact
 *
 * @ORM\Table(name="contact", indexes={@ORM\Index(name="idx_contact_household_idx", columns={"household_id"}), @ORM\Index(name="idx_contact_type_idx", columns={"contact_type_id"}), @ORM\Index(name="idx_contact_center_idx", columns={"center_id"})})
 * @ORM\Entity(repositoryClass="Mana\ClientBundle\Entity\ContactRepository")
 * 
 */
class Contact
{
...
    /**
     * @var \Mana\ClientBundle\Entity\ContactType
     *
     * @ORM\ManyToOne(targetEntity="Mana\ClientBundle\Entity\ContactType", inversedBy="contacts")
     * @ORM\JoinColumn(name="contact_type_id", referencedColumnName="id")
     * @Assert\NotBlank(message="Type must be selected")
     */
    private $contactType;
...
    /**
     * @var \DateTime
     *
     * @ORM\Column(name="contact_date", type="date", nullable=true)
     * @ManaAssert\NotFutureDate
     */
    private $contactDate;

ContactController sn-p:

/**
 * @Route("/addContacts", name="contacts_add")
 * @Template("ManaClientBundle:Contact:testLatestContacts.html.twig")
 */
public function addContactsAction(Request $request) {
    $form = $this->createForm(new ContactType());
    $form->handleRequest($request);
    $message = "";
    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $households = $this->getRequest()->request->get('contact_household');
        $data = $form->getData();
        $contactDate = $data->getContactDate();
        $contactCenter = $data->getCenter();
        $contactType = $data->getContactType();
        $n = count($households);
        foreach ($households as $id) {
            $household = $em->getRepository('ManaClientBundle:Household')->find($id);
            $houseContacts = $household->getContacts();
            $nContacts = count($houseContacts);
            $first = ($nContacts > 0) ? 0 : 1;
            $county = $contactCenter->getCounty();
            $contact = new Contact();
            $contact->setContactDate($contactDate);
            $contact->setCenter($contactCenter);
            $contact->setContactType($contactType);
            $contact->setCounty($county);
            $contact->setFirst($first);
            $household->addContact($contact);
            $em->persist($household);
        }
        $em->flush();
        $center = $contactCenter->getCenter();
        $desc = $contactType->getContactDesc();
        $message = "$n $desc contacts added for $center";
    }
    return array(
        'form' => $form->createView(),
        'title' => 'Add contacts',
        'message' => $message,
    );
}

模板sn-p:

{{ form_errors(form.contactDate) }}
{{ form_errors(form.contactType) }}
<div class="width80">
    <form action="{{ path("contacts_add") }}" method="post">
        <div class="column1">
            <table>
                <tr>
                    <td><b>Date:</b> 
                    <td>{{ form_widget(form.contactDate) }}
                <tr>
                    <td><b>Type:</b> 
                    <td>{{ form_widget(form.contactType) }}
                <tr>
                    <td><b>Center:</b> 
                    <td>{{ form_widget(form.center)}}
            </table>

联系人类型:

namespace Mana\ClientBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityRepository;

class ContactType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('contactType', 'entity', array(
                    'class' => 'ManaClientBundle:ContactType',
                    'property' => 'contactDesc',
                    'empty_value' => 'Select contact type',
                    'error_bubbling' => true,
                    'attr' => array("class" => "smallform"),
                    'query_builder' => function(EntityRepository $er) {
                        return $er->createQueryBuilder('c')
                                ->orderBy('c.contactDesc', 'ASC');
                    },
                ))
            ->add('contactDate', 'date', array(
                'data' => date_create(),
                'format' => 'M/d/y',
                'label' => '<b>Date:</b> ',
                'years' => range(date('Y'), date('Y') - 5),
            ))
            ->add('center', 'entity', array(
                    'class' => 'ManaClientBundle:Center',
                    'property' => 'center',
                    'data' => "",
                    'empty_value' => 'Select distribution center',
                    'error_bubbling' => true,
                    'attr' => array("class" => "smallform"),
                    'query_builder' => function(EntityRepository $er) {
                        return $er->createQueryBuilder('c')
                                ->orderBy('c.center', 'ASC');
                    },
                ))
            ->add('household', 'choice', array(
                'mapped' => false,
                'expanded' => true,
                'multiple' => true,
            ))
            ->add('householdId','text',array(
                'mapped' => false,
            ))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Mana\ClientBundle\Entity\Contact',
            'cascade_validation' => true,
            'csrf_protection' => false,
            'required' => false,
            'error_bubbling' => TRUE,
            ));
    }

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

【问题讨论】:

  • 试试 $form->getErrorsAsString(),你应该会看到你的错误。如果您使用子表单类型,它们将不会显示在模板中。另一种可能是你没有渲染 csrf 令牌,你可以这样做 {{ form_end(form) }}。 form_end() - 呈现表单的结束标记和尚未呈现的任何字段。这对于渲染隐藏字段和利用自动 CSRF 保护非常有用。
  • @lackovic10: $form-&gt;getErrorsAsString() 在控制器中显示验证错误消息。证明它们存在;我希望它们在渲染模板中。 {{ form_end(form) }},在这种情况下,什么都没有。
  • 查看这篇文章:stackoverflow.com/questions/11208992/… 我认为您需要编写一个自定义函数来使用 $form->getErrors() 和 $form->getChildren() 获取错误,然后搜索错误每个孩子。您可以创建一个递归函数,然后您需要手动将错误传递给模板。这是迄今为止我找到的最好的解决方案..
  • 您也可以尝试为子表单类型启用 form_bubbling:symfony.com/doc/current/reference/forms/types/…
  • @lackovic10:感谢您的建议。我在上面的编辑中添加了表单类型 - 没有子表单(除非我误解了这个概念)。不确定如何最好地应用“使用 $form->getErrors() 和 $form->getChildren() 获取错误”。作为字符串的错误输出是“错误:必须选择类型contactType:没有错误contactDate:错误:日期可能不在未来”。奇怪的是它看到类型错误消息但在contactType 上没有错误!

标签: php validation symfony


【解决方案1】:

错误是由于包含代码

'error_bubbling' => true,

由于表单不是子表单,因此没有理由让该代码存在。它是来自应用程序早期版本的工件。

【讨论】:

    猜你喜欢
    • 2010-12-30
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 2013-06-19
    相关资源
    最近更新 更多