2014-07-03 15 views
19

Desidero creare un servizio web a cui invio un modulo e, in caso di errori, restituisce un elenco codificato jason che indica quale campo è errato.come restituire errori di modulo codificati json in symfony

momento ho solo un elenco di messaggi di errore, ma non un id HTML o un nome dei campi con errori

Ecco il mio codice corrente

public function saveAction(Request $request) 
{ 
    $em = $this->getDoctrine()->getManager(); 

    $form = $this->createForm(new TaskType(), new Task()); 

    $form->handleRequest($request); 

    $task = $form->getData(); 

    if ($form->isValid()) { 

     $em->persist($task); 
     $em->flush(); 

     $array = array('status' => 201, 'msg' => 'Task Created'); 

    } else { 

     $errors = $form->getErrors(true, true); 

     $errorCollection = array(); 
     foreach($errors as $error){ 
       $errorCollection[] = $error->getMessage(); 
     } 

     $array = array('status' => 400, 'errorMsg' => 'Bad Request', 'errorReport' => $errorCollection); // data to return via JSON 
    } 

    $response = new Response(json_encode($array)); 
    $response->headers->set('Content-Type', 'application/json'); 

    return $response; 
} 

questo mi darà una risposta come

{ 
"status":400, 
"errorMsg":"Bad Request", 
"errorReport":{ 
     "Task cannot be blank", 
     "Task date needs to be within the month" 
    } 
} 

ma quello che voglio veramente è qualcosa di simile

{ 
"status":400, 
"errorMsg":"Bad Request", 
"errorReport":{ 
     "taskfield" : "Task cannot be blank", 
     "taskdatefield" : "Task date needs to be within the month" 
    } 
} 

Come posso ottenere quello?

risposta

14

ho finalmente trovato la soluzione a questo problema here, aveva bisogno solo una piccola correzione per rispettare le ultime modifiche di symfony e ha funzionato come un fascino:

La correzione consiste nella sostituzione linea 33

if (count($child->getIterator()) > 0) { 

con

if (count($child->getIterator()) > 0 && ($child instanceof \Symfony\Component\Form\Form)) { 

perché, con l'introduzione in symfony della Forma \ Button, un tipo non corrispondente avverrà in funzione Serialize che è expe cting sempre un'istanza di Form \ Form.

È possibile registrare come un servizio:

services: 
form_serializer: 
    class:  Wooshii\SiteBundle\FormErrorsSerializer 

e quindi utilizzarlo come l'autore suggerisce:

$errors = $this->get('form_serializer')->serializeFormErrors($form, true, true); 
1

PHP ha array associativi, nel frattempo JS ha 2 diverse strutture di dati: oggetti e matrici.

Il JSON che si vuole ottenere non è legale e dovrebbe essere:

{ 
"status":400, 
"errorMsg":"Bad Request", 
"errorReport": { 
     "taskfield" : "Task cannot be blank", 
     "taskdatefield" : "Task date needs to be within the month" 
    } 
} 

quindi si consiglia di fare qualcosa di simile per costruire la vostra collezione:

$errorCollection = array(); 
foreach($errors as $error){ 
    $errorCollection[$error->getId()] = $error->getMessage(); 
} 

(supponendo che il getId () metodo esistono sugli oggetti $ di errore)

+1

per id o nome del campo intendo qualcosa che posso usare per indirizzare il campo in forma ... come un id HTML o nome del campo. – SimonQuest

+0

Se la tua iterazione con foreach ($ errori come $ chiave => $ errore), non è $ chiave quello che stai cercando? – Delapouite

+0

no, sarebbe semplicemente un indice numerico ... Ho bisogno di qualcosa che colpisca l'elemento html – SimonQuest

15

sto usando questo, funziona bene tranquilla:

/** 
* List all errors of a given bound form. 
* 
* @param Form $form 
* 
* @return array 
*/ 
protected function getFormErrors(Form $form) 
{ 
    $errors = array(); 

    // Global 
    foreach ($form->getErrors() as $error) { 
     $errors[$form->getName()][] = $error->getMessage(); 
    } 

    // Fields 
    foreach ($form as $child /** @var Form $child */) { 
     if (!$child->isValid()) { 
      foreach ($child->getErrors() as $error) { 
       $errors[$child->getName()][] = $error->getMessage(); 
      } 
     } 
    } 

    return $errors; 
} 
+0

Purtroppo questo non ha funzionato per me, almeno non come volevo. Grazie mille per aver risposto – SimonQuest

+0

Che cosa non funziona? – COil

+1

non attraversa correttamente la struttura del modulo se non è semplice e non restituisce i campi di input ids/nomi. Forse la mia spiegazione del problema non era abbastanza chiara. Prova la soluzione che ho trovato, capirai. – SimonQuest

4

Questo fa il trucco per me

$errors = []; 
foreach ($form->getErrors(true, true) as $formError) { 
    $errors[] = $formError->getMessage(); 
} 
Problemi correlati