使用Symfony2验证嵌入表单


Validation of embedded forms with Symfony2

我有一个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),只得到了对象的名称(responsible1或responsible2)和消息[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"或"responsible 2"验证所有字段时,我必须在上面的代码中添加一些内容来验证对象。

我需要得到所有这些错误都是无效的字段在两个窗体。我读了一些东西,想通过代码添加'cascade_validation' => truevalidation_group@Assert'Valid(),但我尝试了一下,但没有成功。如果有人能向我解释一些值得的东西,我感谢你,因为我对这一切都是新手。

下面的例子将表单和子表单错误平铺到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;
    }
}