Lucas Courot

How to create a contact form using Symfony2

Posted on by

Symfony2 has a very powerful form component, I will try to show you how you can use it to build a contact form for your website.

First of all, let's create a ContactType.php file. It will be used to render the form in your view and to validate the user data.

// src/LC/WebsiteBundle/Form/Type/ContactType.php
<?php

namespace LC\WebsiteBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Collection;

class ContactType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text', array(
                'attr' => array(
                    'placeholder' => 'What\'s your name?',
                    'pattern'     => '.{2,}' //minlength
                )
            ))
            ->add('email', 'email', array(
                'attr' => array(
                    'placeholder' => 'So I can get back to you.'
                )
            ))
            ->add('subject', 'text', array(
                'attr' => array(
                    'placeholder' => 'The subject of your message.',
                    'pattern'     => '.{3,}' //minlength
                )
            ))
            ->add('message', 'textarea', array(
                'attr' => array(
                    'cols' => 90,
                    'rows' => 10,
                    'placeholder' => 'And your message to me...'
                )
            ));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $collectionConstraint = new Collection(array(
            'name' => array(
                new NotBlank(array('message' => 'Name should not be blank.')),
                new Length(array('min' => 2))
            ),
            'email' => array(
                new NotBlank(array('message' => 'Email should not be blank.')),
                new Email(array('message' => 'Invalid email address.'))
            ),
            'subject' => array(
                new NotBlank(array('message' => 'Subject should not be blank.')),
                new Length(array('min' => 3))
            ),
            'message' => array(
                new NotBlank(array('message' => 'Message should not be blank.')),
                new Length(array('min' => 5))
            )
        ));

        $resolver->setDefaults(array(
            'constraints' => $collectionConstraint
        ));
    }

    public function getName()
    {
        return 'contact';
    }
}

Then, go to your controller and add a new action.

// src/LC/WebsiteBundle/Controller/DefaultController.php
/**
 * @Route("/contact", _name="contact")
 * @Template()
 */
public function contactAction(Request $request)
{
    $form = $this->createForm(new ContactType());

    if ($request->isMethod('POST')) {
        $form->bind($request);

        if ($form->isValid()) {
            $message = \Swift_Message::newInstance()
                ->setSubject($form->get('subject')->getData())
                ->setFrom($form->get('email')->getData())
                ->setTo('contact@example.com')
                ->setBody(
                    $this->renderView(
                        'LCWebsiteBundle:Mail:contact.html.twig',
                        array(
                            'ip' => $request->getClientIp(),
                            'name' => $form->get('name')->getData(),
                            'message' => $form->get('message')->getData()
                        )
                    )
                );

            $this->get('mailer')->send($message);

            $request->getSession()->getFlashBag()->add('success', 'Your email has been sent! Thanks!');

            return $this->redirect($this->generateUrl('contact'));
        }
    }

    return array(
        'form' => $form->createView()
    );
}

As you can see, we

  • are creating the form from the ContactType
  • are binding the form to the use request in case the http request is sent using the POST method
  • are validating the form
  • are creating the Swift message from the view by passing it the variables
  • are sending the constructed message using the mailer service
  • are adding a success flash
  • are redirecting the user to the url of our choice
  • are rendering the contact view

Now all you have to do is to create a new template for your email

# src/LC/WebsiteBundle/Resources/views/Mail/contact.html.twig
New message from {{ name }}
Sent from courot.com/contact
IP: {{ ip }}

{{ message|raw }}

Don't forget to render the flashes from your flashbag and to render your form in the contact view.

You can see this form in action on this contact page.

See the other articles published in Symfony .