2013-07-15 6 views
14

Ho un'entità cliente che dispone solo di un campo di posta elettronica univoco. Sto cercando di modificare l'email di un cliente e la convalida funziona correttamente. Tuttavia ho questo nel mio controller:Symfony2: il mio modulo restituisce false da isValid() ma l'array vuoto per getErrors() dalla condizione di vincolo univoco

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

    $entity = $em->getRepository('AcmeDemoBundle:Customer')->find($id); 

    if (!$entity) { 
     throw $this->createNotFoundException('Unable to find Customer entity.'); 
    } 


    $editForm = $this->createForm(new CustomerType(), $entity); 
    $editForm->bind($request); 
    if ($editForm->isValid()) { 
     $em->persist($entity); 
     $em->flush(); 

     return $this->redirect($this->generateUrl('ticket_result')); 
    } 
    var_dump($editForm->getErrors()); 

    return $this->render('AcmeDemoBundle:Customer:edit.html.twig', array(
       'entity' => $entity, 
       'edit_form' => $editForm->createView(), 
    )); 
} 

Il var_dump restituisce un array vuoto, ma il validatore imposta un errore di unico e le $editForm->isValid() restituisce false. C'è un modo per verificare quello specifico errore nel controller durante la convalida, puoi anche spiegare perché restituisce un array di errore vuoto? Fondamentalmente, vorrei fornire l'opzione "Unisci" se viene visualizzato questo errore.

EDIT: qui è la FormType:

namespace Acme\DemoBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class CustomerType extends AbstractType { 


    public function buildForm(FormBuilderInterface $builder, array $options) { 
     $builder 
       ->add('email', 'email', array('required'=>true)) 
     ; 

    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) { 
     $resolver->setDefaults(array(
      'data_class' => 'Acme\DemoBundle\Entity\Customer', 
      'cascade_validation' => true, 
     )); 
    } 

    public function getName() { 
     return 'acme_demobundle_customertype'; 
    } 
} 

E il modello ramoscello:

{% extends 'AcmeDemoBundle::layout.html.twig' %} 
{% block body -%} 
    <h1>Customer edit</h1> 



    <form action="{{ path('customer_update', { 'id': entity.id }) }}" method="post" {{ form_enctype(edit_form) }}> 
     <input type="hidden" name="_method" value="PUT" /> 
     {{ form_widget(edit_form) }} 
     <p> 
      <button type="submit">Edit</button> 
     </p> 
    </form> 

{% endblock %} 

Qui è la mia convalida:

Acme\DemoBundle\Entity\Customer: 
    constraints: 
     - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity: 
      fields: email 
      message: "A customer under that email address already exists" 

    properties: 
     email: 
      - Email: ~ 
+0

Il tipo di cliente ha qualche sottoforma? – nifr

+0

mostra il tuo modello, plz – Ziumin

+0

Ho aggiornato il post e aggiunto la convalida, modello e formtype –

risposta

4

Ok, trovato qui una risposta :

Symfony2 invalid form without errors

Si scopre che ogni modulo ha i propri errori separati. Quando si effettua una var_dump di

$editForm->getChildren()['email']->getErrors() 

ottengo:

array (size=1) 
    0 => 
    object(Symfony\Component\Form\FormError)[531] 
     private 'message' => string 'A customer under that email address already exists' (length=50) 
     protected 'messageTemplate' => string 'A customer under that email address already exists' (length=50) 
     protected 'messageParameters' => 
     array (size=0) 
      empty 
     protected 'messagePluralization' => null 

io non so ancora come determinare che l'errore è a causa di un conflitto unico, senza il parsing della stringa di messaggio di errore.

+3

'$ editForm-> getErrors (true)' restituirà gli errori di form dai bambini in modo ricorsivo (dal 2.5). – contrebis

1

È possibile utilizzare error_bubbling in ogni campo per indicare l'errore fino al modulo $.

In caso contrario, si può anche foreach attraverso gli errori

foreach ($children as $child) { 
      if ($child->hasErrors()) { 
       $vars = $child->createView()->getVars(); 
       $errors = $child->getErrors(); 
       foreach ($errors as $error) { 
        $this->allErrors[$vars["name"]][] = $this->convertFormErrorObjToString($error); 
       } 
      } 
} 
17

a scopo di debug è possibile utilizzare al posto di $form->getErrorsAsString()$form->getErrors() se si usa Symfony 2. *

Citato da this answer:

$form->getErrorsAsString() deve essere utilizzato solo per eseguire il debug del modulo ... esso conterrà gli errori di ogni elemento figlio che è n ot il caso di $ form-> getErrors().


UPDATE 1:

"Con le versioni più recenti Symfony, è necessario utilizzare $form->getErrors(true, false); invece Prima param corrisponde a deep e la seconda a flatten." (Si veda il commento di @Roubi)

+1

getErrorsAsString è obsoleto dalla versione 2.5, da rimuovere in 3.0. Usa invece getErrors()} e metti il ​​risultato su una stringa. –

+0

conterrà anche gli errori dei moduli figlio? –

+1

@ DénesPapp passa il parametro booleano opzionale a cascata attraverso qualsiasi forma figlio $ form-> getErrors (true); – ChristoKiwi

0

in Symfony 2.3, è possibile utilizzare questo:

if ($form->isValid()){ 
    # Code... 
} else { 
    foreach ($form->getIterator() as $key => $child) { 
     if ($child instanceof Form) { 
      foreach ($child->getErrors() as $error) { 
       $errors[$key] = $error->getMessage(); 
      } 
     } 
    } 
} 

questo modo si ottiene una matrice ($errors) con gli errori da parte dei bambini.

-1

Si potrebbe provare a utilizzare la funzione dump quando il modulo viene inviato e non valido. Io lo uso come questo

if($form->isSubmited() && $form->isValid()){ 
    //SAVE TO DATABASE AND DO YOUR STUFF 
}else if($form->isSubmited()){ 
    //SUBMITED BUT WITH ERRORS 
    dump($form->getErrors(true)); 
    die(); 

} 

notare che questo è solo per il debugging, Vi mostrerà il modulo, i dati in essa e tutti gli errori qualsiasi campo potrebbe avere. In modalità produzione è necessario restituire l'errore alla vista e mostrarli all'utente.

Problemi correlati