2012-09-23 14 views
5

Estoy utilizando formularios Symfony2 para validar las solicitudes POST y PUT a una API. El formulario maneja el enlace de los datos de solicitud a la entidad subyacente y luego valida la entidad. Todo funciona bastante bien, excepto por la recopilación de errores. Estoy usando FOSRestBundle y estoy lanzando un Symfony \ Component \ HttpKernel \ Exception \ HttpException con un código de estado 400 y un mensaje que contiene los mensajes de error de formulario si la validación falla. El FOSRestBundle se encarga de convertir esto en una respuesta JSON. El método de control que tengo para llevar a cabo todo esto se parece a lo siguiente (todos los campos de burbujas sus errores hasta la forma):Obtener todos los errores junto con los campos El error está conectado a

protected function validateEntity(AbstractType $type, $entity, Request $request) 
{ 
    $form = $this->createForm($type, $entity); 
    $form->bind($request); 
    if (! $form->isValid()) { 
     $message = ['Invalid parameters passed.']; 
     foreach ($form->getErrors() as $error) { 
      $message[] = $error->getMessage(); 
     } 
     throw new HttpException(Codes::HTTP_BAD_REQUEST, implode("\n", $message)); 
    } 
} 

El problema que tengo es que cuando recoja el nivel de formulario a través de errores $ form- > getErrors() Solo puedo acceder al mensaje de error y no al nombre del campo al que está conectado el error. Este es un problema particular cuando un parámetro POST o PUT corresponde a un id para una entidad relacionada. Si se envía un valor no válido, los mensajes de error son simplemente 'Este valor no es válido', que no es muy bueno en este contexto. Idealmente me gustaría hacer uno de los siguientes:

  • Por cada error hacerse con el nombre del campo que está conectado a por lo que puedo formatear el mensaje algo así como "nombre de campo: mensaje de error"
  • Si eso es No es posible personalizar el mensaje de error para un tipo de entidad no válida para que se muestre algo mejor que "Este valor no es válido".

Respuesta

5

Puede tomar el método getErrorsAsString como ejemplo para obtener la funcionalidad que desea. También debe establecer la opción invalid_message en el campo del formulario para cambiar el mensaje This value is invalid.

+0

Gracias. De alguna manera me había perdido la opción invalid_message en los documentos. Justo lo que necesitaba. – Jeremy

+5

Advertencia: el getErrorsAsString está en desuso y se eliminará en 3.0 – wdev

+0

Desde 3.0 es más simple: $ form-> getErrors (true, false); para obtener errores secundarios – Chopchop

9

Utilice esta función para obtener todos los mensajes de error después del formulario de enlace.

private function getErrorMessages(\Symfony\Component\Form\Form $form) { 
    $errors = array(); 
    foreach ($form->getErrors() as $key => $error) { 
     $template = $error->getMessageTemplate(); 
     $parameters = $error->getMessageParameters(); 

     foreach($parameters as $var => $value){ 
      $template = str_replace($var, $value, $template); 
     } 

     $errors[$key] = $template; 
    } 
    if ($form->hasChildren()) { 
     foreach ($form->getChildren() as $child) { 
      if (!$child->isValid()) { 
       $errors[$child->getName()] = $this->getErrorMessages($child); 
      } 
     } 
    } 
    return $errors; 
} 
11

y para Symfony> = 2,2

private function getErrorMessages(\Symfony\Component\Form\Form $form) { 
    $errors = array(); 
    foreach ($form->getErrors() as $key => $error) { 
     $template = $error->getMessageTemplate(); 
     $parameters = $error->getMessageParameters(); 

     foreach ($parameters as $var => $value) { 
      $template = str_replace($var, $value, $template); 
     } 

     $errors[$key] = $template; 
    } 
    if ($form->count()) { 
     foreach ($form as $child) { 
      if (!$child->isValid()) { 
       $errors[$child->getName()] = $this->getErrorMessages($child); 
      } 
     } 
    } 
    return $errors; 
} 
0

necesitaba una solución para obtener una matriz asociativa de todos los errores de todas las formas anidadas con la tecla formateado por lo que representa el ID de documento del elemento de campo de formulario correspondiente:

namespace Services; 

use Symfony\Component\Form\Form; 
use Symfony\Component\Form\FormErrorIterator; 

/** 
* Class for converting forms. 
*/ 
class FormConverter 
{ 
    /** 
    * Gets all errors of a form as an associative array with keys representing the dom id of the form element. 
    * 
    * @param Form $form 
    * @param bool $deep Whether to include errors of child forms as well 
    * @return array 
    */ 
    public function errorsToArray(Form $form, $deep = false) { 
     return $this->getErrors($form, $deep); 
    } 

    /** 
    * @param Form $form 
    * @param bool $deep 
    * @param Form|null $parentForm 
    * @return array 
    */ 
    private function getErrors(Form $form, $deep = false, Form $parentForm = null) { 
     $errors = []; 

     if ($deep) { 
      foreach ($form as $child) { 
       if ($child->isSubmitted() && $child->isValid()) { 
        continue; 
       } 

       $iterator = $child->getErrors(true, false); 

       if (0 === count($iterator)) { 
        continue; 
       } elseif ($iterator->hasChildren()) { 
        $childErrors = $this->getErrors($iterator->getChildren()->getForm(), true, $child); 
        foreach ($childErrors as $key => $childError) { 
         $errors[$form->getName() . '_' . $child->getName() . '_' .$key] = $childError; 
        } 
       } else { 
        foreach ($iterator as $error) { 
         $errors[$form->getName() . '_' . $child->getName()][] = $error->getMessage(); 
        } 
       } 
      } 
     } else { 
      $errorMessages = $this->getErrorMessages($form->getErrors(false)); 
      if (count($errorMessages) > 0) { 
       $formName = $parentForm instanceof Form ? $parentForm->getName() . '_' . $form->getName() : $form->getName(); 
       $errors[$formName] = $errorMessages; 
      } 
     } 

     return $errors; 
    } 

    /** 
    * @param FormErrorIterator $formErrors 
    * @return array 
    */ 
    private function getErrorMessages(FormErrorIterator $formErrors) { 
     $errorMessages = []; 
     foreach ($formErrors as $formError) { 
      $errorMessages[] = $formError->getMessage(); 
     } 

     return $errorMessages; 
    } 
} 
Cuestiones relacionadas