Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2: my form returns false from isValid() but empty array for getErrors() from unique constraint condition

I have a Customer entity that only has a unique Email field to it. I am trying to edit a customer's email and the validation works fine. However I have this in my controller:

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

The var_dump returns an empty array but the validator sets a unique error and the $editForm->isValid() returns false. Is there a way to check for that specific error in the controller during validation, also can you explain why it returns an empty error array? Basically, I would like to provide the "merge" option if that error comes up.

EDIT: here is the 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';
    }
}

And the twig template:

{% 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 %}

Here is my 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: ~
like image 337
Boris_bulletdodger Avatar asked Jul 15 '13 16:07

Boris_bulletdodger


2 Answers

For debug purposes you can use $form->getErrorsAsString() instead of $form->getErrors() if you use Symfony 2.*

Quoted from this answer:

$form->getErrorsAsString() should only be used to debug the form...it will contain the errors of each child elements which is not the case of $form->getErrors().


UPDATE 1:

"With more recent Symfony versions, you must use $form->getErrors(true, false); instead. First param corresponds to deep and second to flatten" (see the comment by @Roubi)

like image 177
Denes Papp Avatar answered Sep 19 '22 16:09

Denes Papp


Ok, found an answer here:

Symfony2 invalid form without errors

It turns out each form child has it's own separate errors. When doing a var_dump of

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

I get:

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

I am still wondering how to determine that the error is because of a unique conflict without parsing the error message string.

like image 24
Boris_bulletdodger Avatar answered Sep 21 '22 16:09

Boris_bulletdodger