Search code examples
phpvalidationsymfonysymfony-2.3

Multiple Custom Validation Constraint in Symfony2


I created multiple validators using de oficial documentation and all of them works fine, but only when I use separately. In a bundle I defined this:

# Resources/config/validation.ynl
SF\SomeBundle\Entity\SomeEntity:
    properties:
        name:
            - NotBlank: ~
            - SF\UtilsBundle\Validator\Constraints\ContainsAlphanumeric: ~
            - SF\UtilsBundle\Validator\Constraints\MinLength: ~

ContainstAlphanumeric Class validator:

if (!preg_match('/^[a-z\d_]$/i', $value, $matches)) {
    $this->context->addViolation($constraint->message, array('%string%' => $value));
}

MinLength Class validator

$min = 5;
if( strlen($value) < $min )
{
    $this->context->addViolation($constraint->message, array('%string%' => $value, '%min_length%' => $min));
}

So, when I submit a form and the input has the value "q", the validator MinLength returns a length error, but if the same input has the value "qwerty", the validator ContainsAlphanumeric returns an illegal character message.

Any ideas?

Edit:

I changed Resources/config/validation.yml file to use the native SF2 Contraints length validator:

properties:
    name:
        - NotBlank: ~
        - Length: { min: 5, minMessage: "El nombre debe tener almenos {{ limit }} caracteres." }
        - SF\UtilsBundle\Validator\Constraints\ContainsAlphanumeric: ~

And I descover a new behaviour: Some errors are displayed in twig templates with

{{ form_errors(form) }}

and other errors using

{{ form_errors(form.some_field) }}

This is weird!


Solution

  • For problems not I discovered, the validators did not return errors for all fields of the form and as I said when I asked, some errors saw them with form_errors(form.widget) and others with form_errors(form) I solved my problem (but I don't know if this is the best way) using the Validation Service and returning the erros to twig.

    In the Action:

    $form = $this->createCreateForm($entity);
    $form->handleRequest($request);
    
    if ($form->isValid())
    {
        # Magic code :D
    }
    
    return array(
        'entity' => $entity,
        'form'   => $form->createView(),
        'errors' => $this->get('validator')->validate($form) # Here's the magic :D
    );
    

    And in twig template:

    {% if errors is defined %}
        <ul>
            {% for error in errors %}
                <li>
                    {{ error.message }}
                </li>
            {% endfor %}
        </ul>
    {% endif %}
    

    Thanks for help me :D

    PD: I decided not to use error_bubbling to not modify each form field.