J'ai une entité client qui ne dispose que d'un champ Email unique. J'essaie de modifier le courrier électronique d'un client et la validation fonctionne bien. Cependant, j'ai ceci dans mon contrôleur:
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(),
));
}
Var_dump renvoie un tableau vide, mais le validateur définit une erreur unique et la fonction $editForm->isValid()
renvoie false. Existe-t-il un moyen de vérifier cette erreur spécifique dans le contrôleur lors de la validation, pouvez-vous également expliquer pourquoi il renvoie un tableau d'erreur vide? Fondamentalement, je voudrais fournir l'option "fusion" si cette erreur se produit.
MODIFIER: voici le type de formulaire:
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';
}
}
Et le modèle de brindille:
{% 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 %}
Voici ma validation:
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: ~
Ok, j'ai trouvé une réponse ici:
Symfony2 formulaire non valide sans erreur
Il s'avère que chaque enfant du formulaire a ses propres erreurs séparées. Quand on fait un var_dump de
$editForm->getChildren()['email']->getErrors()
Je reçois:
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
Je me demande toujours comment déterminer que l'erreur est due à un conflit unique sans analyser la chaîne de message d'erreur.
À des fins de débogage, vous pouvez utiliser $form->getErrorsAsString()
au lieu de $form->getErrors()
si vous utilisez Symfony 2. *
Cité de cette réponse :
$form->getErrorsAsString()
ne devrait être utilisé que pour déboguer le formulaire ... it contiendra les erreurs de chaque élément enfant ce qui n'est pas le cas de $ form-> getErrors ().
MISE À JOUR 1:
"Avec les versions Symfony les plus récentes, vous devez utiliser $form->getErrors(true, false);
. Le premier paramètre correspond à deep
et le second à flatten
" (voir le commentaire de @Roubi)
Vous pouvez utiliser error_bubbling sur chaque champ pour masquer l'erreur jusqu'à votre formulaire $.
Sinon, vous pouvez aussi éviter les erreurs
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);
}
}
}
Les solutions suivantes fonctionnent pour moi:
$ form-> getErrors (true)
Dans Symfony 2.3, vous pouvez utiliser celui-ci:
if ($form->isValid()){
# Code...
} else {
foreach ($form->getIterator() as $key => $child) {
if ($child instanceof Form) {
foreach ($child->getErrors() as $error) {
$errors[$key] = $error->getMessage();
}
}
}
}
Cela vous donnera un tableau ($errors
) avec les erreurs des enfants.
Vous pouvez essayer d'utiliser la fonction dump
lorsque le formulaire est soumis et n'est pas valide. Je l'utilise comme ça
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();
}
Notez que ceci est uniquement destiné au débogage, il vous montrera votre formulaire, les données qu'il contient et toutes les erreurs que tout champ pourrait avoir . En mode production, vous devez renvoyer l'erreur à la vue et la montrer à l'utilisateur.