2012-09-23 5 views
5

Sto utilizzando i moduli Symfony2 per convalidare le richieste POST e PUT a un'API. Il modulo gestisce il binding dei dati della richiesta all'entità sottostante e quindi la convalida dell'entità. Tutto funziona abbastanza bene tranne che per la raccolta di errori. Sto usando FOSRestBundle e sto lanciando un Symfony \ Component \ HttpKernel \ Exception \ HttpException con un codice di stato 400 e un messaggio contenente i messaggi di errore del modulo se la validazione fallisce. FOSRestBundle gestisce la conversione di questa in una risposta JSON. Il metodo di controllo che devo svolgere tutto questo è simile al seguente (tutti i campi bolla loro errori fino alla forma):Ottieni tutti gli errori insieme ai campi a cui è collegato l'errore.

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)); 
    } 
} 

Il problema che ho è che quando raccolgo gli errori a livello di modulo attraverso $ form- > getErrors() Posso solo accedere al messaggio di errore e non al nome del campo a cui è collegato l'errore. Questo è un problema particolare quando un parametro POST o PUT corrisponde a un ID per un'entità correlata. Se viene inviato un valore non valido, i messaggi di errore per questo sono semplicemente 'Questo valore non è valido', il che non è molto buono in questo contesto. Idealmente mi piacerebbe fare una delle seguenti operazioni:

  • Per ogni errore entrare in possesso del nome del campo a cui è collegato in modo che possa formattare il messaggio qualcosa come "nomecampo: messaggio di errore"
  • Se questo è non è possibile personalizzare il messaggio di errore per un tipo di entità non valido in modo che venga visualizzato qualcosa di meglio di "Questo valore non è valido"?

risposta

5

È possibile utilizzare il metodo getErrorsAsString come esempio per ottenere la funzionalità desiderata. Inoltre è necessario impostare l'opzione invalid_message nel campo modulo per modificare il messaggio This value is invalid.

+0

Grazie. In qualche modo mi sono perso l'opzione invalid_message nei documenti. Proprio quello di cui avevo bisogno. – Jeremy

+5

Avviso: getErrorsAsString è obsoleto e verrà rimosso in 3.0 – wdev

+0

A partire dalla 3.0 è più semplice: $ form-> getErrors (true, false); per ottenere errori figlio – Chopchop

9

Utilizzare questa funzione per ottenere tutti i messaggi di errore dopo il modulo vincolante.

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

e per 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

avevo bisogno di una soluzione per ottenere un array associativo di tutti gli errori di tutte le forme nidificate con la chiave formattato in modo che rappresenta l'ID del documento dell'elemento campo modulo corrispondente:

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; 
    } 
} 
Problemi correlati