2012-09-23 2 views
5

Ich verwende Symfony2-Formulare, um POST- und PUT-Anfragen an eine API zu validieren. Das Formular behandelt das Binden der Anforderungsdaten an die zugrunde liegende Entität und dann das Validieren der Entität. Alles funktioniert ziemlich gut, außer dass man Fehler sammelt. Ich benutze das FOSRestBundle und werfe eine Symfony \ Component \ HttpKernel \ Exception \ HttpException mit einem 400 Statuscode und einer Nachricht, die die Formularfehlermeldungen enthält, wenn die Validierung fehlschlägt. Der FOSRestBundle übernimmt die Konvertierung in eine JSON-Antwort. Die Controller-Methode Ich habe all dies auszuführen sieht wie folgt aus (alle Felder Blase ihre Fehler in die Form nach oben):Erhalte alle Fehler zusammen mit Feldern, an die der Fehler angeschlossen ist

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

Das Problem ist, dass ich, wenn ich sammle die Form Level-Fehler durch $ form- > getErrors() Ich kann nur auf die Fehlermeldung und nicht auf den Namen des Feldes zugreifen, mit dem der Fehler verbunden ist. Dies ist ein besonderes Problem, wenn ein POST- oder PUT-Parameter einer ID für eine verwandte Entität entspricht. Wenn ein ungültiger Wert übergeben wird, lautet die Fehlermeldung dafür einfach "Dieser Wert ist nicht gültig", was in diesem Zusammenhang nicht sehr gut ist. Im Idealfall würde Ich mag eine der folgenden tun: Für jeden Fehler

  • hält die Feldnamen bekommt es verbunden ist, so dass ich die Meldung etwas formatiert werden kann, wie „Feldname: Fehlermeldung“
  • Wenn die nicht möglich ist es möglich, die Fehlermeldung für einen ungültigen Entitätstyp anzupassen, so dass etwas besser als 'Dieser Wert ist nicht gültig' angezeigt wird?

Antwort

5

Sie können die Methode getErrorsAsString als Beispiel nehmen, um die gewünschte Funktionalität zu erhalten. Sie müssen auch die Option invalid_message im Formularfeld festlegen, um die Nachricht This value is invalid zu ändern.

+0

Danke. Irgendwie hatte ich die Option invalid_message in den Dokumenten verpasst. Genau das, was ich brauchte. – Jeremy

+5

Warnung: Der getErrorsAsString ist veraltet und wird in 3.0 entfernt. – wdev

+0

Seit 3.0 ist es einfacher: $ form-> getErrors (true, false); um Kindfehler zu bekommen – Chopchop

9

Verwenden Sie diese Funktion, um alle Fehlermeldungen nach dem Bindungsformular zu erhalten.

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

und für 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

ich brauchte eine Lösung, die ein assoziatives Array aller Fehler aller verschachtelten Formen mit dem Schlüssel zu bekommen formated so es die Dokument-ID des entsprechenden Formularfeld Elements darstellt:

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; 
    } 
} 
Verwandte Themen