chindit
chindit

Reputation: 1009

Custom validator constraint in Symfony 3

I'm trying to create a custom validator constraint in Symfony 3.

I've, of course, followed the doc end ended with this:

#AppBundle\Validator\Constraint\Device.php

namespace AppBundle\Validator\Constraint;
/**
 * @Annotation
 */
class Device extends \Symfony\Component\Validator\Constraint
{
    public $message = 'Device "%device%" is not valid';
    public $shortMessage = 'Device ID is too short';
    public $chunkMessage = 'Device ID doesn\'t have a correct number of parts';
 }

Constraint

#AppBundle\Validator\DeviceValidator.php
namespace AppBundle\Validator;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class DeviceValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint) : void
{
    if (!$myconstraint) {
        //A lot of code here
        $this->context->buildViolation($constraint->shortMessage)->addViolation();
    }
}
}

And FormType

#AppBundle\Form\Type\LoginType.php

namespace AppBundle\Form\Type;

use AppBundle\Validator\Constraint\Device;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Length;

class LoginType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('username', TextType::class, ['required' => true, 'constraints' => [new Length(['min' => 3, 'minMessage' => 'Username is too short'])]])
        ->add('password', TextType::class, ['required' => true, 'constraints' => [new Length(['min' => 3, 'minMessage' => 'Password is too short'])]])
        ->add('device', TextType::class, ['required' => true, 'constraints' => [new Device()]]);
}
}

Form is created like this:

$loginForm = Forms::createFormFactoryBuilder()->addExtension(new HttpFoundationExtension())->getFormFactory()->create(LoginType::class);

But whatever I do, I got this response:

{ "code": 500, "message": "The option \"constraints\" does not exist. Defined options are: \"action\", \"attr\", \"auto_initialize\", \"block_name\", \"by_reference\", \"compound\", \"data\", \"data_class\", \"disabled\", \"empty_data\", \"error_bubbling\", \"inherit_data\", \"label\", \"label_attr\", \"label_format\", \"mapped\", \"method\", \"post_max_size_message\", \"property_path\", \"required\", \"translation_domain\", \"trim\", \"upload_max_size_message\"." }

According to doc, «constraint» is allowed where I put it and I really don't know why Symfony is crying here.

Any idea? Thanks a lot.

Upvotes: 1

Views: 2298

Answers (2)

michail_w
michail_w

Reputation: 4481

I think you're missing ValidatorExtension.

use Symfony\Component\Validator\Validation;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
$validator = Validation::createValidator();

$formFactory = Forms::createFormFactoryBuilder()
    ->addExtension(new HttpFoundationExtension())
    ->addExtension(new ValidatorExtension($validator))
    ->getFormFactory()
    ->create(LoginType::class);

Upvotes: 2

ehymel
ehymel

Reputation: 1391

Your namespace in AppBundle\Validator\Constraint\Device.php is not quite right. Remove the trailing "Constraint":

namespace AppBundle\Validator;

Upvotes: 1

Related Questions