2012-09-23 5 views
5

Używam formularzy Symfony2 do sprawdzania poprawności żądań POST i PUT do API. Formularz obsługuje powiązanie danych żądania z jednostką podstawową, a następnie walidację jednostki. Wszystko działa całkiem dobrze, z wyjątkiem zbierania błędów. Używam FOSRestBundle i wyrzucam Symfony \ Component \ HttpKernel \ Exception \ HttpException z kodem statusu 400 i wiadomością zawierającą komunikaty o błędach formularza, jeśli sprawdzanie poprawności nie powiedzie się. FOSRestBundle obsługuje konwertowanie tego na odpowiedź JSON. Metoda kontroler muszę wykonać to wszystko wygląda następująco (wszystkie pola bańki swoje błędy do formularza):Otrzymuj wszystkie błędy wraz z polami, w których błąd jest podłączony do

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

Mam problem jest, że kiedy zbierać błędów poprzez formularz na poziomie $ form- > getErrors() Mam dostęp tylko do komunikatu o błędzie, a nie do nazwy pola, do którego podłączony jest błąd. Jest to szczególny problem, gdy parametr POST lub PUT odpowiada identyfikatorowi powiązanej jednostki. W przypadku podania nieprawidłowej wartości komunikaty o błędach są po prostu "Ta wartość nie jest poprawna", co w tym kontekście nie jest zbyt dobre. Idealnie chciałabym zrobić jedną z następujących czynności:

  • Dla każdego błędu zdobyć nazwy pola jest on podłączony do tak, że mogę sformatować wiadomość coś jak „nazwa_pola: Komunikat o błędzie”
  • Jeśli to nie jest możliwe, czy można dostosować komunikat o błędzie dla nieprawidłowego typu jednostki, aby wyświetlało się coś lepszego niż "Ta wartość jest nieprawidłowa"?

Odpowiedz

5

Jako przykład można użyć metody getErrorsAsString, aby uzyskać pożądaną funkcjonalność. Również musisz ustawić opcję invalid_message w polu formularza, aby zmienić komunikat This value is invalid.

+0

dziękuję. W jakiś sposób przegapiłem opcję invalid_message w dokumentach. Dokładnie to, czego potrzebowałem. – Jeremy

+5

Ostrzeżenie: getErrorsAsString jest przestarzałe i zostanie usunięte w 3.0 – wdev

+0

Od wersji 3.0 jest prostsze: $ form-> getErrors (true, false); aby uzyskać błędy dziecka – Chopchop

9

Użyj tej funkcji, aby uzyskać wszystkie komunikaty o błędach po wygaśnięciu formularza.

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

i 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

Potrzebowałem rozwiązanie, aby uzyskać tablicę asocjacyjną wszystkich błędów wszystkich zagnieżdżonych formularzy z kluczem formatowany więc reprezentuje identyfikator dokumentu odpowiedniego elementu pól formularza:

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; 
    } 
} 
Powiązane problemy