Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all errors along with fields the error is connected to

I'm using Symfony2 forms to validate POST and PUT requests to an API. The form handles binding the request data to the underlying entity and then validating the entity. Everything is working pretty well except for collecting errors. I'm using the FOSRestBundle and am throwing a Symfony\Component\HttpKernel\Exception\HttpException with a 400 status code and a message containing the form error messages if validation fails. The FOSRestBundle handles converting this into a JSON response. The controller method I have to perform all of this looks like the following (all fields bubble their errors up to the form):

protected function validateEntity(AbstractType $type, $entity, Request $request)
{
    $form = $this->createForm($type, $entity);
    $form->bind($request);
    if (! $form->isValid()) {
        $message = ['Invalid parameters passed.'];
        foreach ($form->getErrors() as $error) {
            $message[] = $error->getMessage();
        }
        throw new HttpException(Codes::HTTP_BAD_REQUEST, implode("\n", $message));
    }
}

The problem I have is that when I collect the form level errors through $form->getErrors() I can only access the error message and not the name of the field that the error is connected to. This is a particular problem when a POST or PUT parameter corresponds to an id for a related entity. If an invalid value is submitted the error messages for that is simply 'This value is not valid', which is not very good in this context. Ideally I'd like to do either of the following:

  • For each error get hold of the field name it's connected to so that I can format the message something like "fieldname: error message"
  • If that's not possible is it possible to customise the error message for an invalid entity type so that something better than 'This value is not valid' is displayed?
like image 982
Jeremy Avatar asked Sep 23 '12 17:09

Jeremy


2 Answers

and for symfony >= 2.2

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->count()) {
        foreach ($form as $child) {
            if (!$child->isValid()) {
                $errors[$child->getName()] = $this->getErrorMessages($child);
            }
        }
    }
    return $errors;
}
like image 124
Daniel Espendiller Avatar answered Nov 15 '22 04:11

Daniel Espendiller


Use this function to get all error messages after binding form.

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;
}
like image 41
Julfiker Avatar answered Nov 15 '22 03:11

Julfiker