In this article, we are going to discuss about How we can create a contact form in Symfony with SwiftMailer. Symfony provides an architecture, components and tools for developers to build complex web applications faster. Choosing symfony allows you to release your applications earlier, host and scale them without problem, and maintain them over time with no surprise.
Swift Mailer is a component based library for sending e-mails from PHP applications. Swift Mailer supports PHP 7.0 to PHP 8.1 included (proc_* functions must be available). Swift Mailer does not work when used with function overloading as implemented by mbstring when mbstring.func_overload is set to 2.
At the end of this article, we will be created a contact form in Symfony using Form Builder and connected with SwiftMailer bundle. So that, the visitor could receive acknowledgement that the messages has been successfully sent.
Step 1: Create Contact Entity with Doctrine
First of all we need to create and configure the database. Database related information and credentials are available in Application Access details panel. Add these to the app/config/parameters.ymlparameters: database_host: localhost database_port: <PORT> database_name: <DB_NAME> database_user: <DB_user_name> database_password: <DB_password>
Next, we need to create a contact entity with Doctrine. To use Doctrine, open SSH terminal and go to your Symfony project:
- cd application/{your_app_folder}/public_html
Now run the following command to start the entity generator:
- php bin/console doctrine:generate:entity
For the contact form I need four fields: name, email, subject, message. You can add more fields as per your requirements. The entity name will be Contact and the shortcut name will be AppBundle:Contact. Annotation will be Yaml, so just press the Enter key on this.
Now go to src/AppBundle/Entity. You will see a Contact.php file in which Doctrine has created a new method for every field. I will use these methods to set values in the Controller:
- <?php
- namespace AppBundle\Entity;
- use Doctrine\ORM\Mapping as ORM
- /**
- * Contact
- *
- * @ORM\Table(name="contact")
- * @ORM\Entity(repositoryClass="AppBundle\Repository\ContactRepository")
- */
- class Contact
- {
- /**
- * @var int
- *
- * @ORM\Column(name="id", type="integer")
- * @ORM\Id
- * @ORM\GeneratedValue(strategy="AUTO")
- */
- private $id;
- /**
- * @var string
- *
- * @ORM\Column(name="name", type="string", length=255)
- */
- private $name;
- /**
- * @var string
- *
- * @ORM\Column(name="email", type="string", length=255)
- */
- private $email;
- /**
- * @var string
- *
- * @ORM\Column(name="subject", type="string", length=255)
- */
- private $subject;
- /**
- * @var string
- *
- * @ORM\Column(name="message", type="string", length=255)
- */
- private $message;
- /**
- * Get id
- *
- * @return int
- */
- public function getId()
- {
- return $this->id;
- }
- /**
- * Set name
- *
- * @param string $name
- *
- * @return Contact
- */
- public function setName($name)
- {
- $this->name = $name;
- return $this;
- }
- /**
- * Get name
- *
- * @return string
- */
- public function getName()
- {
- return $this->name;
- }
- /**
- * Set email
- *
- * @param string $email
- *
- * @return Contact
- */
- public function setEmail($email)
- {
- $this->email = $email;
- return $this;
- }
- /**
- * Get email
- *
- * @return string
- */
- public function getEmail()
- {
- return $this->email;
- }
- /**
- * Set subject
- *
- * @param string $subject
- *
- * @return Contact
- */
- public function setSubject($subject)
- {
- $this->subject = $subject;
- return $this;
- }
- /**
- * Get subject
- *
- * @return string
- */
- public function getSubject()
- {
- return $this->subject;
- }
- /**
- * Set message
- *
- * @param string $message
- *
- * @return Contact
- */
- public function setMessage($message)
- {
- $this->message = $message;
- return $this;
- }
- /**
- * Get message
- *
- * @return string
- */
- public function getMessage()
- {
- return $this->message;
- }
- }
Next, we will work on the Controller and the form View.
Step 2: Create the Form in DefaultController.php
The next step is to create a form in the controller. You can also create a form in the Twig view. However, in this article, I will initialize the form fields using the Symfony’s form builder, and then show the form Widget in the View.
Open DefaultController.php and add the following namesapaces and the entity (created earlier):- namespace AppBundle\Controller;
- use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
- use Symfony\Bundle\FrameworkBundle\Controller\Controller;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\Form\Extension\Core\Type\TextType;
- use Symfony\Component\Form\Extension\Core\Type\TextareaType;
- use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
- use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
- use Symfony\Component\Form\Extension\Core\Type\SubmitType;
- use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
- use AppBundle\Entity\Contact;
Now in the createAction() method, create an entity object and pass it to the form builder. The form contains the input fields (as discussed earlier).
- class DefaultController extends Controller
- {
- /**
- * @Route("/form", name="homepage")
- */
- public function createAction(Request $request)
- {
- $contact = new Contact;
- # Add form fields
- $form = $this->createFormBuilder($contact)
- ->add('name', TextType::class, array('label'=> 'name', 'attr' => array('class' => 'form-control', 'style' => 'margin-bottom:15px')))
- ->add('email', TextType::class, array('label'=> 'email','attr' => array('class' => 'form-control', 'style' => 'margin-bottom:15px')))
- ->add('subject', TextType::class, array('label'=> 'subject','attr' => array('class' => 'form-control', 'style' => 'margin-bottom:15px')))
- ->add('message', TextareaType::class, array('label'=> 'message','attr' => array('class' => 'form-control')))
- ->add('Save', SubmitType::class, array('label'=> 'submit', 'attr' => array('class' => 'btn btn-primary', 'style' => 'margin-top:15px')))
- ->getForm();
- # Handle form response
- $form->handleRequest($request);
Step 3: Create View for the Contact Form
To view this form on the Twig template, create a file form.html.twig in app/Resources/views/default and add the form widget to it.
- {% block body %}
- <div class="container">
- <div class="row">
- <div class="col-sm-4">
- <h2 class=page-header>Contact Form in Symfony</h2>
- {{form_start(form)}}
- {{form_widget(form)}}
- {{form_end(form)}}
- </div>
- </div>
- </div>
- {% endblock %}
I have added bootstrap classes to the code. I will now add the bootstrap CDN to base template to make the classes work.
Open the base.html.twig from app/Resources/views and add the CDN links to it.
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8" />
- <title>{% block title %}Welcome!{% endblock %}</title>
- {% block stylesheets %}{% endblock %}
- <link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
- <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
- </head>
- <body>
- <div class="alert alert-success">
- {% set flashbag_notices = app.session.flashbag.get('notice') %}
- {% if flashbag_notices is not empty %}
- <div class="flash-notice">
- {% for notice in flashbag_notices %}
- {{notice}}
- {% endfor %}
- </div>
- {% endif %}
- {% block body %}{% endblock %}
- </div>
- {% block javascripts %}{% endblock %}
- </body>
- </html>
Now I need to extend form.html.twig with base.html.twig by simply adding the following line at the top.
- {% extends 'base.html.twig' %}
At this point, if you hit the /form Route, you will get the following Form:
Step 4: Save Values in the Database
Next, we will save the values in database. We have already created the form in the DefaultController class. First, we will save the values in variables and then pass these variables to the related methods in the entity. Finally, we will save the variables through the persist() method.
- # check if form is submitted
- if($form->isSubmitted() && $form->isValid()){
- $name = $form['name']->getData();
- $email = $form['email']->getData();
- $subject = $form['subject']->getData();
- $message = $form['message']->getData();
- # set form data
- $contact->setName($name);
- $contact->setEmail($email);
- $contact->setSubject($subject);
- $contact->setMessage($message);
- # finally add data in database
- $sn = $this->getDoctrine()->getManager();
- $sn -> persist($contact);
- $sn -> flush();
Now, when the form is submitted, the values will be available in the database.
Step 5: Send Acknowledgement to the User
It is important to tell the user that their message has been successfully delivered to the website. Many websites send an email that provides all user-submitted data in a proper format.
For this purpose, I will use SwiftMailer, a bundle that comes preinstalled in Symfony 3. To use it, you just need to configure it. To do the necessary changes, open app/config/parameters.yml under parameters
- mailer_transport: gmail
- mailer_host: smtp.gmail.com
- mailer_user: <SMTP_USERNAME>
- mailer_password: <SMTP_PASSWORD>
- secret: Itmaybeanything
- encryption: tls
Now in the config.yml, add the following code to get the values:
- # Swiftmailer Configuration
- swiftmailer:
- transport: "%mailer_transport%"
- host: "%mailer_host%"
- username: "%mailer_user%"
- password: "%mailer_password%"
- spool: { type: memory }
The configuration process is over. Now, open DefaultController.php and add the code for SwiftMailer. I will use the same data variables in this code:
- $message = \Swift_Message::newInstance()
- ->setSubject($subject)
- ->setFrom('shahroznawaz156@gmail.com')
- ->setTo($email)
- ->setBody($this->renderView('default/sendemail.html.twig',array('name' => $name)),'text/html');
- $this->get('mailer')->send($message);
Notice that you can also send email templates. In this code snippet, I sent the email template I created (sendemail.html.twig) in the views/default. This template has a simple test message.
- {# app/Resources/views/Emails/sendemail.html.twig #}
- <h3>You did it</h3>
- Hi {{ name }}! Your Message is successfully Submitted.
- We will get back to you soon!
- Thanks!
Now, when you submit the form, you will get an acknowledgment email in your inbox.
If you have a query or would like to contribute to the discussion, do leave a comment.
0 comments:
Post a Comment