Adding SwiftMailer to a Simple Website Using Silex and Twig
In our last tutorial we looked at how to make a very simple website using Silex and Twig. If you haven’t yet took a look I encourage you to do so as this tutorial will make a lot more sense if you have already followed the previous one.
As always there is a demo available. I have just updated the demo from the previous tutorial.
As with the previous tutorial the source pack is available. It includes the previous tutorial files updated to include the changes needed to make the contact form work using Swiftmailer.
Composer Changes
First up, if you used composer to install Silex last time, you will need to update your composer file to include the Swiftmailer package. To do that you need to add:
1 |
"swiftmailer/swiftmailer": ">=4.1.2,<4.2-dev" |
To your composer.json
file. The whole file should look like this:
1 2 3 4 5 6 7 8 |
{ "require": { "silex/silex": "~1.1", "twig/twig": ">=1.8,<2.0-dev", "symfony/twig-bridge": "~2.3", "swiftmailer/swiftmailer": ">=4.1.2,<4.2-dev" } } |
Once you’ve added that line just run composer update
in your project folder & it should grab Swiftmailer for you.
If you have downloaded the Fat source package of Silex, instead of using Composer, then there is no need to worry. Just follow along & everything should work as expected.
Adding Swiftmailer
To add Swiftmailer is pretty simple. Open up your index.php
file we used in the last tutorial & under the line where we register the URL Generator we are going to register the Swiftmailer service.
1 |
$app->register(new Silex\Provider\SwiftmailerServiceProvider()); |
To keep things simple we are just going to use the default ESMTP setup and use the Google SMTP server to send our mail. To do that add the following directly under the line you just added.
1 2 3 4 5 6 7 8 |
$app['swiftmailer.options'] = array( 'host' => 'smtp.google.com', 'port' => 465, 'username' => 'mygmail@gmail.com', 'password' => 'mygmailpassword', 'encryption' => 'ssl', 'auth_mode' => 'login' ); |
Replace the username & password with your gmail or Google Apps email & password.
Adding Swiftmailer’s POST Route
Now we need to add in the route for Swiftmailer. Since it will be receiving the values from a form we can just have the mail sent by adding in a POST route for the contact page. So, under your current /contact
route, add in this new one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$app->post('/contact', function() use ($app) { $request = $app['request']; $message = \Swift_Message::newInstance() ->setSubject('Llama Feedback') ->setFrom(array($request->get('email') => $request->get('name'))) ->setTo(array('feedback@lilyandlarryllamafarmers.com')) ->setBody($request->get('message')); $app['mailer']->send($message); return $app['twig']->render('pages/contact.twig', array('sent' => true)); }); |
This route works exactly like the others, but this one only listens and runs when it receives a POST request from the server. All we are doing is grabbing the request, which holds the data from our sent form, and then passing it to the SwiftMailer message. Then we send it out and render out the contact page again but with one difference, we send an extra variable.
Adding A Sent Message
We need to tell the user that their feedback has been sent, that is why we sent an extra variable through when rendering the contact page via POST.
Open up your contact.twig
file and replace the contact form with the following.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{% if sent is defined %} <p>Thank you for getting in touch. If a response is required we will get back to you as soon as we can.</p> {% else %} <p>Contact us using the form below and we'll get back in touch with you when we aren't shearing our luscious Llamas.</p> <form role="form" method="post" action="{{ path('contact') }}"> <div class="form-group"> <label for="name">Name</label> <input type="name" class="form-control" id="name" name="name" placeholder="Enter Name"> </div> <div class="form-group"> <label for="email">Email address</label> <input type="email" class="form-control" id="email" name="email" placeholder="Enter email"> </div> <div class="form-group"> <label for="message">Message</label> <textarea name="message" id="message" class="form-control" rows="3" placeholder="Enter Your Message"></textarea> </div> <div class="form-group"> <button type="submit" class="btn btn-default">Send It</button> </div> </form> {% endif %} |
All we do here is check to see if our sent
variable was defined. If not, we show the form. If it is, we show a message.
Homework
That’s all there is to it. You should now have a working contact form that will send an email using the Google SMTP servers. There are some more things we can do though and we’ll take a look at them in the final part of these tutorials.
Silex Form Service
Build our form with a CSRF token using the Silex form service.
Silex Validation
Add in Validation using the Silex Validation Service to validate all input before sending our email. This will help prevent the error received if you try to send the form with no email address inserted.
Relocate Silex Files
Relocate the entire Silex folder to outside of the web accessible to help with security issues.
Contact Active Link
A small oversight eagle-eyed readers may have noticed is that the navigation link for Contact doesn’t stay marked as active when you are shown the ‘Thank you’ page after submitting the form. You may also notice that it does in the demo. This is something I purposely left out to see if you could figure out how it was done. Worry not though, I’ll reveal the secret in the final part with everything else.
Please feel free to try these out yourself and see how far you can get, I love trying things out. Failing is all part of the experience and will teach you more than success in most cases.
We’ll go through how to add these final features in the final part of this tutorial. Look out for it very soon.
As always, if you have any questions please get in touch via the comments.
6 Comments
Ciccio
You forgot to mention the .htaccess 😉 If not you get 404 error when you change page!
With this rule I fixed it:
Paul Robinson
Hi Ciccio,
Thanks for posting. I purposely left it out on this part as I mentioned it in the first part (linked at the start of the tutorial). I personally use Nginx so I didn’t want to post any Server Side config as it can vary quite a lot depending on your setup.
Thanks for posting that though, I’m considering adding a section onto the end to show some of the common setups as I think you might be right in that missing it out is a mistake.
Thanks again.
Thomas Los
Tip, for the gmail stmp to work, enable “Allow less secure apps:” in https://myaccount.google.com/security?pli=1#connectedapps otherwise you will get errors from swiftmailer.
For the rest, thanks for your tutorial, it helps -a lot- in understanding silex :-).
IZ
Hi Paul,
again many thanks for this 3-part tutorial, I really learned a lot with it and it was exactly what I was looking for to get started with silex (ie. something clear, not too short and not too long at the same time) ! 🙂
I noticed the same problem with the URL to the first part (at the beginning of this article) so I wanted to mention it to you (I saw that you already corrected the 2 other URLs in the 3rd part, glad I could help… 😉 )
I also wanted to mention that you don’t mention the adding of the namespaces (for the Request and Response from the Symfony HttpFoundation Component) and in the next part of the tutorial, you wrote that those 2 should already be in the file, which can be a bit confusing.
I also have a question regarding this. Why do we need to add the Response class while we don’t explicitely use it in our code?
Anyway thank you again for this nice tutorial. Take good care!
Paul Robinson
Hi IZ,
Thanks for pointing that out. I did change them both when you first mentioned it, but didn’t hit the update button on this one so it never went live. *Doh*
Ah, I see what you mean. Sorry about that. I’ll alter the wording as those are two namespaces you are probably going to need when dealing with any forms or sending responses to the browser.
The Response namespace is added as it can be used to send responses to the browser. I did originally use it at an earlier stage when building the tutorial, but I decided to remove that section but never removed the namespace. So technically you could take it out if you wish.
Hope that helps answer your question & thank you again for reading.
baudelot philippe
Not so easy now with google.
We have to use smtp.gmail.com and allow connection with less secure apps
https://www.google.com/settings/u/1/security/lesssecureapps?pageId=none
Thanks for all
Philippe