Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 : How to get form validation errors after binding the request to the form

Tags:

symfony

People also ask

How to get form error in symfony?

As of Symfony 2.5, you can use $form->getErrors(true) to get an array of all the errors in your form. Yay! We can iterate over $form (a Form object) to get all of its fields. And again, remember that each field ( $formField here), is also a Form object, which is why we can call Form::getErrors() on each.

What is err validation?

A validation error occurs when you have validation/response checking turned on for one of the questions and the respondent fails to answer the question correctly (for numeric formatting , required response).


You have two possible ways of doing it:

  • do not redirect user upon error and display {{ form_errors(form) }} within template file
  • access error array as $form->getErrors()

Symfony 2.3 / 2.4:

This function get's all the errors. The ones on the form like "The CSRF token is invalid. Please try to resubmit the form." as well as additional errors on the form children which have no error bubbling.

private function getErrorMessages(\Symfony\Component\Form\Form $form) {
    $errors = array();

    foreach ($form->getErrors() as $key => $error) {
        if ($form->isRoot()) {
            $errors['#'][] = $error->getMessage();
        } else {
            $errors[] = $error->getMessage();
        }
    }

    foreach ($form->all() as $child) {
        if (!$child->isValid()) {
            $errors[$child->getName()] = $this->getErrorMessages($child);
        }
    }

    return $errors;
}

To get all errors as a string:

$string = var_export($this->getErrorMessages($form), true);

Symfony 2.5 / 3.0:

$string = (string) $form->getErrors(true, false);

Docs:
https://github.com/symfony/symfony/blob/master/UPGRADE-2.5.md#form https://github.com/symfony/symfony/blob/master/UPGRADE-3.0.md#form (at the bottom: The method Form::getErrorsAsString() was removed)


Below is the solution that worked for me. This function is in a controller and will return a structured array of all the error messages and the field that caused them.

Symfony 2.0:

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

Symfony 2.1 and newer:

private function getErrorMessages(\Symfony\Component\Form\Form $form) {      
    $errors = array();

    if ($form->hasChildren()) {
        foreach ($form->getChildren() as $child) {
            if (!$child->isValid()) {
                $errors[$child->getName()] = $this->getErrorMessages($child);
            }
        }
    } else {
        foreach ($form->getErrors() as $key => $error) {
            $errors[] = $error->getMessage();
        }   
    }

    return $errors;
}

Use the Validator to get the errors for a specific entity

if( $form->isValid() )
{
    // ...
}
else
{
    // get a ConstraintViolationList
    $errors = $this->get('validator')->validate( $user );

    $result = '';

    // iterate on it
    foreach( $errors as $error )
    {
        // Do stuff with:
        //   $error->getPropertyPath() : the field that caused the error
        //   $error->getMessage() : the error message
    }
}

API reference:

  • ConstraintViolationList
  • ConstraintViolation

To get proper (translatable) messages, currently using SF 2.6.3, here is my final function (as none of above's seem to work anymore):

 private function getErrorMessages(\Symfony\Component\Form\Form $form) {      
    $errors = array();
    foreach ($form->getErrors(true, false) as $error) {
        // My personnal need was to get translatable messages
        // $errors[] = $this->trans($error->current()->getMessage());
        $errors[] = $error->current()->getMessage();
    }

    return $errors;
}

as the Form::getErrors() method now returns an instance of FormErrorIterator, unless you switch the second argument ($flatten) to true. (It will then return a FormError instance, and you will have to call the getMessage() method directly, without the current() method:

 private function getErrorMessages(\Symfony\Component\Form\Form $form) {      
    $errors = array();
    foreach ($form->getErrors(true, true) as $error) {
        // My personnal need was to get translatable messages
        // $errors[] = $this->trans($error->getMessage());
        $errors[] = $error->getMessage();
    }

    return $errors;
}

)

The most important thing is actually to set the first argument to true in order to get the errors. Leaving the second argument ($flatten) to his default value (true) will return FormError instances, while it will return FormErrorIterator instances when set to false.


For my flash messages I was happy with $form->getErrorsAsString()

Edit (from Benji_X80): For SF3 use $form->getErrors(true, false);