Symfony2 - How to validate an email address in a controller

46,212

Solution 1

By using validateValue method of the Validator service

use Symfony\Component\Validator\Constraints\Email as EmailConstraint;
// ...

public function customAction()
{
    $email = 'value_to_validate';
    // ...

    $emailConstraint = new EmailConstraint();
    $emailConstraint->message = 'Your customized error message';

    $errors = $this->get('validator')->validateValue(
        $email,
        $emailConstraint 
    );

    // $errors is then empty if your email address is valid
    // it contains validation error message in case your email address is not valid
    // ...
}
// ...

Solution 2

I wrote a post about validating email address(es) (one or many) outside of forms

http://konradpodgorski.com/blog/2013/10/29/how-to-validate-emails-outside-of-form-with-symfony-validator-component/

It also covers a common bug where you validate against Email Constraint and forget about NotBlank

/**
 * Validates a single email address (or an array of email addresses)
 *
 * @param array|string $emails
 *
 * @return array
 */
public function validateEmails($emails){

    $errors = array();
    $emails = is_array($emails) ? $emails : array($emails);

    $validator = $this->container->get('validator');

    $constraints = array(
        new \Symfony\Component\Validator\Constraints\Email(),
        new \Symfony\Component\Validator\Constraints\NotBlank()
    );

    foreach ($emails as $email) {

        $error = $validator->validateValue($email, $constraints);

        if (count($error) > 0) {
            $errors[] = $error;
        }
    }

    return $errors;
}

I hope this helps

Solution 3

If you're creating the form in the controller itself and want to validate email in the action, then the code will look like this.

// add this above your class
use Symfony\Component\Validator\Constraints\Email;

public function saveAction(Request $request) 
{
    $form = $this->createFormBuilder()
        ->add('email', 'email')
        ->add('siteUrl', 'url')
        ->getForm();

    if ('POST' == $request->getMethod()) {
        $form->bindRequest($request);

        // the data is an *array* containing email and siteUrl
        $data = $form->getData();

        // do something with the data
        $email = $data['email'];

        $emailConstraint = new Email();
        $emailConstraint->message = 'Invalid email address';

        $errorList = $this->get('validator')->validateValue($email, $emailConstraint);
        if (count($errorList) == 0) {
            $data = array('success' => true);
        } else {
            $data = array('success' => false, 'error' => $errorList[0]->getMessage());
        }
   }

   return $this->render('AcmeDemoBundle:Default:update.html.twig', array(
       'form' => $form->createView()
   ));
}

I'm also new and learning it, any suggestions will be appreciated...

Solution 4

Why does no one mention that you can validate it with in FormBuilder instance using 'constraints' key ??? First of all, read documentation Using a Form without a Class

'constraints' =>[
    new Assert\Email([
        'message'=>'This is not the corect email format'
    ]),
    new Assert\NotBlank([
        'message' => 'This field can not be blank'
    ])
],

Works fine with symfony 3.1

Example:

namespace SomeBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Validator\Constraints as Assert;

class DefaultController extends Controller
{

    /**
     * @Route("kontakt", name="_kontakt")
     */
    public function userKontaktAction(Request $request) // access for all
    {

        $default = array('message' => 'Default input value');
        $form = $this->createFormBuilder($default)
        ->add('name', Type\TextType::class,[
            'label' => 'Nazwa firmy',
        ])
        ->add('email', Type\EmailType::class,[
            'label' => 'Email',
            'constraints' =>[
                new Assert\Email([
                    'message'=>'This is not the corect email format'
                ]),
                new Assert\NotBlank([
                    'message' => 'This field can not be blank'
                ])
            ],
        ])
        ->add('phone', Type\TextType::class,[
            'label' => 'Telefon',
        ])
        ->add('message', Type\TextareaType::class,[
            'label' => 'Wiadomość',
            'attr' => [
                'placeholder' => 'Napisz do nas ... '
            ],
        ])
        ->add('send', Type\SubmitType::class,[
            'label' => 'Wyślij',
        ])
        ->getForm();

        $form->handleRequest($request);

        if ($form->isValid()) {
            // data is an array with "name", "email", and "message" keys
            $data = $form->getData();
            // send email
            // redirect to prevent resubmision
            var_dump($data);
        }
        
        return $this->render('SomeBundle:Default:userKontakt.html.twig', [
            'form' => $form->createView()
        ]);
    }

}

Result: enter image description here

See the documentaion about available validation types. http://api.symfony.com/3.1/Symfony/Component/Validator/Constraints.html

If you want to check what are the available keys other than message, go to documentation at:

http://symfony.com/doc/current/reference/constraints/Email.html

or navigate to:

YourProject\vendor\symfony\symfony\src\Symfony\Component\Validator\Constraints\Email.php

from there, you will be able to see what else is available.

public $message = 'This value is not a valid email address.';

public $checkMX = false;

public $checkHost = false;

public $strict; "

Also note that I created and validated form inside the controller which is not a best practice and should only be used for forms, which you will never reuse anywhere else in your application.

Best practice is to create forms in a separated directory under YourBundle/Form. Move all the code to your new ContactType.php class. (don't forget to import FormBuilder class there as it will not extend your controller and will not have access to this class through '$this')

[inside ContactType class:]

namespace AdminBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Validator\Constraints as Assert;

[inside your controller:]

use YourBundle/Form/ContactType;
// use ...

//...
$presetData = []; //... preset form data here if you want to
$this->createForm('AdminBundle\Form\FormContactType', $presetData) // instead of 'createFormBuilder'
->getForm();
// render view and pass it to twig templet...
// or send the email/save data to database and redirect the form

Solution 5

My solution for symfony 3 was the following:

use Symfony\Component\Validator\Constraints\Email as EmailConstraint;

$email = '[email protected]';
// ... in the action then call
$emailConstraint = new EmailConstraint();

$errors = $this->get('validator')->validate(
    $email,
    $emailConstraint
);

$mailInvalid = count($errors) > 0;
Share:
46,212

Related videos on Youtube

Milos Cuculovic
Author by

Milos Cuculovic

Masters degree in Embedded and comunicant systems.

Updated on November 01, 2020

Comments

  • Milos Cuculovic
    Milos Cuculovic over 3 years

    There is an email validator in symfony that can be used in a form: http://symfony.com/doc/current/reference/constraints/Email.html

    My question is: How can I use this validator in my controlelr in order to validate an email address?

    This is possible by using the PHP preg_match for usere, but my question is if there is a possibility to use the Symfony already built in email validator.

    Thank you in advance.

  • Jevgenij Evll
    Jevgenij Evll about 9 years
    Note that validateValue is deprecated as of Symfony 2.5 and validate should be used instead.
  • Andrew Zhilin
    Andrew Zhilin over 7 years
    Validator service is deprecated since version 2.5, to be removed in 3.0. Validator\RecursiveValidator should be used instead
  • Andrew Zhilin
    Andrew Zhilin over 7 years
    Validator service is deprecated since version 2.5, to be removed in 3.0. Validator\RecursiveValidator should be used instead
  • Breith
    Breith over 7 years
    thanks, for check MX & Host, i added : new Assert\Email(['checkHost' => true, 'checkMX' => true])
  • Atan
    Atan over 6 years
    If you want the default but localized error messages you have to use the translator service to do so: foreach($errors as $error) $message = $translator->trans($error->getMessage(),[],'validators'); where $translator is of type TranslatorInterface