Lesson 5 - Contact form
In the previous lesson, Wiring controllers and views, we wired a view to a controller and even added an error subpage to our website. In today's tutorial, we'll program a new feature from scratch using our MVC architecture. This time, it'll be a contact form. We won't go over any new principles today, the system's structure is complete.
Template
Let's create a new file in the "views" folder, name it contact.phtml, and add a bit of HTML code to it. The form will contain input fields for the visitor's email address (so we can reply to him/her). As for anti-spam, we'll make them enter the current year. We'll also add a text field for the message and a submit button.
<h1>Contact us</h1> <p>Contact us using the form below.</p> <form method="post" id="form-email"> Your email<br /> <input type="email" name="email" required="required" value="<?php if (isset($_POST['email'])) echo(htmlspecialchars($_POST['email'])); ?>" /><br /> Antispam - enter the current year<br /> <input type="text" name="abc" required="required" /><br /> <textarea name="message"><?php if (isset($_POST['message'])) echo(htmlspecialchars($_POST['message'])); ?></textarea><br /> <input type="submit" value="Send" /> </form>
The code is just plain HTML. Notice the use of HTML 5 validations. We should validate everything on the server-side as well, but we'll omit that for now. We've truly made the form as simple as possible. We even used <br > instead of labels to make the form layout. If the user has already sent some data and server denies them, the application should fill said data back into the form (that's what the echo() functions are there for). For more complex forms, it'd be better to use a library that generates, validates and fills in forms automatically. However, that's well beyond our skills at the moment. Once you have more experience, read through our PHP libraries course, where we'll create a form library that does all of that for us.
We'll add a bit of CSS to our style.css to style form inputs:
input[type="submit"] { background: #6FA4F8; color: white; padding: 5px 10px; border-radius: 10px; border: 0px; } input[type="submit"]:hover { background: #2976f8; color: #EEEEEE; cursor: pointer; } input[type="text"], input[type="email"], input[type="password"] { width: 250px; border-radius: 5px; border: 1px solid #aaaaaa; padding: 0.3em; } input[type="submit"] { padding: 10px 25px; display: block; margin: 0 auto; margin-top: 20px; font-weight: bold; } textarea { border-radius: 5px; border: 1px solid #aaaaaa; width: 483px; height: 90px; }
Model
Some logic is needed to send an email. Remember, we write all of the application logic into models. Newbies often tend to overuse controllers by using them for logical operations, when all they're supposed to do is wire things together. A controller's sole purpose is to process parameters given by the user and to call the logic on a model.
So let's create a model that sends emails to a given address. Add an EmailSender.php file to the "models" folder, which will contain the following bit of code:
class EmailSender { // Sends an HTML email. You can use basic HTML tags. You have to insert // new lines using <br /> or paragraphs. Uses the UTF-8 encoding. public function send($recipient, $subject, $message, $from) { $header = "From: " . $from; $header .= "\nMIME-Version: 1.0\n"; $header .= "Content-Type: text/html; charset=\"utf-8\"\n"; return mb_send_mail($recipient, $subject, $message, $header); } }
The class consists of a single method - send(), which takes a recipient, subject, message, and sender's address as parameters. Once all of that has been entered, we set a header and send the email using PHP's mb_send_mail() function. This functions wraps PHP's mail() function and adds UTF-8 encoding support.
Perhaps you noticed that the email is sent as HTML, if so, good eye! We'll send all emails in our CMS as HTML since it gives us the option to write both simple text or rich text emails. Keep in mind that you'ss have to write <br /> as opposed to "\n".
Controller
Last of all, we'll create the aforementioned "man in the middle", the ContactController. Here's its entire source code, which we'll dissect right away:
<?php class ContactController extends Controller { public function process($params) { $this->head = array( 'title' => 'Contact form', 'description' => 'Contact us using our email form.' ); if (isset($_POST["email"])) { if ($_POST['abc'] == date("Y")) { $emailSender = new EmailSender(); $emailSender->send("[email protected]", "Email from your website", $_POST['message'], $_POST['email']); } } $this->view = 'contact'; } }
The controller extends our abstract Controller, so it implements the process() method. In said method, we set some information in the head and checked whether the form has been submitted. If it has, we validate the entered year. If the answer was entered correctly, we create an EmailSender (model) instance and pass the given parameters to it. In a nutshell, the logic will be performed by the model, which is called by the controller. Last of all, we'll set the view to "contact". Don't forget to replace the admin@address.com with your own email.
Try it out, open the "contact" URL. You should see something like this:

Although the principle behind composing the page is probably clear to you all, better safe than sorry. The router determines, based on the first URL parameter ("contact"), that we're calling the ContactController and it passes control over to it. If the form has already been sent, the ContactController will create an EmailSender instance and pass the user data to it. The model sends emails with the given data. Last of all, the controller renders its template.
If you don't have a configured SMTP server on localhost, the email won't be
delivered to you, so you'll have to test it on your production server or take my
word for it
Flash messages
It'd be great if we could also display messages to the user about the email sending status. This would be extremely useful because all sorts of things could go wrong, e.g. invalid email address, faulty server configuration or invalid anti-spam. We could easily add a variable to the template and assign text to it using the EmailController. However, we'll need the same functionality for lots of other controllers. For this reason, we'll integrate flash messages in our CMS in the next, Creating the database and PHP SQL drivers, lesson.
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 290x (12.17 kB)
Application includes source codes in language PHP