【问题标题】:Validation of embedded forms with Symfony2使用 Symfony2 验证嵌入式表单
【发布时间】:2015-12-06 21:13:31
【问题描述】:

我有一个 Parents 表单嵌入到另一个表单 Student 中,其中包含学生家长的数据。我需要验证嵌入的表单,因为在我的代码中只是验证另一个表单。

StudentType.php

  //...
  ->add('responsible1', new ParentsType(),array('label' => 'Mother'))
  ->add('responsible2', new ParentsType(),array('label'=> 'Father'))

 /**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'BackendBundle\Entity\Student'
    ));
}

实体父母

 //...
 /**
 * @ORM\OneToMany(targetEntity="Student", mappedBy="$responsible1")
 * @ORM\OneToMany(targetEntity="Student", mappedBy="$responsible2")
 */
 private $students;

实体学生

 //...
 /**
 * 
 * @ORM\ManyToOne(targetEntity="Parents", inversedBy="students", cascade={"persist"})
 */
 private $responsible1;

/**
 * 
 * @ORM\ManyToOne(targetEntity="Parents", inversedBy="students", cascade={"persist"})
 */
 private $responsible2;

在控制器中使用以下代码,我得到了主表单 (Student) 中所有无效字段的名称和错误消息,但我得到错误嵌入表单 (Parents),只需获取对象的名称(责任 1 或责任 2)和我得到的消息 [object Object]。

StudentController.php

protected function getErrorMessages(\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->getErrorMessages($child);
        }
    }

    return $errors;
}
/**
 * Creates a new Student entity.
 *
 */
public function createAction(Request $request)
{
// if request is XmlHttpRequest (AJAX) but not a POSt, throw an exception
if ($request->isXmlHttpRequest() && !$request->isMethod('POST')) {
    throw new HttpException('XMLHttpRequests/AJAX calls must be POSTed');
}

    $entity = new Student();
    $form = $this->createCreateForm($entity);
    $form->handleRequest($request);

    if ($form->isValid()) {

        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        if ($request->isXmlHttpRequest()) {
        return new JsonResponse(array('message' => 'Success!'), 200);
    }

        return $this->redirect($this->generateUrl('student_show', array('id' => $entity->getId())));
    }

     if ($request->isMethod('POST')) {
                    return new JsonResponse(array(
        'result' => 0,
        'message' => 'Invalid form',
        'data' => $this->getErrorMessages($form)),400);
    }

    return $this->render('BackendBundle:Student:new.html.twig', array(
        'entity' => $entity,
        'form'   => $form->createView(),
    ));
}

我用函数getErrorsAsString() 尝试了上面的代码来检查字符串中的错误,所以如果它们全部出现,所以我想我必须在上面的代码中添加一些东西来验证“responsible1”或“responsible2”中的对象" 验证所有字段。

我需要得到所有这些错误都是无效字段在两个表单上。我读了一些东西来添加 'cascade_validation' => truevalidation_group@Assert\Valid() 通过代码,但我试过了,但我没有得到它。如果有人可以向我解释一下这些值得,我感谢你,因为我对这一切都是新手。

【问题讨论】:

  • 您是否正在寻找一种方法来扁平化包括嵌套表单在内的错误消息?
  • 嗨@b.b3rn4rd,我需要验证一个表单并返回一个 JsonResponse 一个 Ajax 调用,然后在不刷新屏幕的情况下指示无效的表单字段。这是一个解决方案,但我无法得到嵌入表单的错误。
  • 有道理,我正在为 ajax 验证做类似的事情,发布了一个适合我的解决方案

标签: php forms validation symfony


【解决方案1】:

以下示例将表单和子表单错误转换为 assoc 数组,让我知道这是否是您想要实现的目标

<?php
namespace Example\Bundle\UtilityBundle\Form;
use Symfony\Component\Form\Form;
class FormErrors
{
    public function getArray(Form $form, $style = 'KO')
    {
        $method = sprintf('get%sErrors', $style);

        $messages = $this->$method($form->all());

        return $messages;
    }

    private function getKOErrors(Form $children)
    {
        $errors = array();

        /* @var $child \Symfony\Component\Form\Form */
        foreach ($children as $child) {
            $type = $child->getConfig()->getType()->getName();
            if ($child->count()  && ($type !== 'choice')) {
                $childErrors = $this->getKOErrors($child->all());
                if (sizeof($childErrors)) {
                    $errors = array_merge($errors, $childErrors);
                }
            } else {
                if (!$child->isValid()) {
                    // I need only one error message per field 
                    $errors[$child->getName()] = $child->getErrors()->current()->getMessage();
                }
            }
        }

        return $errors;
    }
}

【讨论】:

  • 嗨@b.b3rn4rd,使用您的代码,我可能会收到表单丢失的错误,但在我的情况下,表单被嵌入到主表单中两次。就我而言,我知道我有一张学生登记表,并且在我体内出现了父亲的登记表和母亲的其他数据(两者属于同一类型)。如果我得到任何字段是无效的,这两个表单都是第一个字段。您需要以某种方式区分获得的错误,例如责任1_name 或责任2_name。我希望我解释得很好,谢谢你的回答。
  • @Joseph,只需将第二个参数 $name 添加到 getKOErrors(Form $children, $name) 并连接 $errors[$name.'_'.$child-&gt;getName() ] 并且不要忘记在调用时传递它 -&gt;getName()
  • 现在一切正常,我相信我需要的是区分它们,非常感谢,帮了我很大的忙。
  • 不用担心,很高兴它有帮助
猜你喜欢
  • 1970-01-01
  • 2012-04-25
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多