Hawklan
Hawklan

Reputation: 33

Symfony 3 Form Validation: check for existing database entry

I am currently doing my first Symfony project and struggling a bit with a special function I want to implement.
I have a form where people have to enter a license key alongside other data to activate a certain service.
When the form is submitted I need to validate all the data and one part of the validation is to check if the given license key is valid (exists in a database of license keys).

My form sits in a separate form class and looks like this (stripped down to the important parts):

<?php

namespace AppBundle\Form;

use AppBundle\Entity;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints as Constraint;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

class Activation extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Entity\Customer::class,
            'translation_domain' => 'forms'
        ]);
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('activationCode', Type\TextType::class, [
                'mapped' => false,
                'constraints' => [new Constraint\Callback(
                    function ($object, ExecutionContextInterface $context, $payload) {

                    }
                )]
            ])
            ->add('firstName', Type\TextType::class)
            ->add('lastName', Type\TextType::class)
            ->add('email', Type\RepeatedType::class, [
                'type' => Type\EmailType::class,
                'invalid_message' => 'The E-Mail fields must match.',
                'first_options' => ['label' => 'E-Mail'],
                'second_options' => ['label' => 'Repeat E-Mail'],
            ])
            ->add('activate', Type\SubmitType::class);
    }

}

As you can see my first idea was to use a Callback Constraint and do the check in a Closure.
Is that an adequate way to do it?
If so how can I get access to the database/doctrine entity manager from inside that closure?
Or would you recommend a completely different approach?

Upvotes: 2

Views: 2807

Answers (1)

Joe
Joe

Reputation: 2436

You can write your own custom constraint and validator class for this use case.

https://symfony.com/doc/current/validation/custom_constraint.html

The validator is a service so you can inject any other service as you have the need for. (i.E. entityManager). This way your form doesn't have to deal with the validation logic itself.

Upvotes: 1

Related Questions