Sending E-Mail from CakePHP 2.x

A few years back I was working on a customer project in CakePHP 1.3. I must say I fell in love with CakePHP, it made life so easy, but the one aspect that I always had difficulty with was sending E-Mail. Well, sending E-Mail was no problem, applying HTML templates was a bit cumbersome.

I am currently working on a project which is based on CakePHP 2.3 and recently I have been working on features that need to be able to send E-Mail notifications. I was dreading looking into this, but as of CakePHP 2 the process has gotten a whole lot easier. There is still a little bit of configuration to be done, but it all works beautifully.

The CakePHP 2.x book is a little confusing to read, so here are the steps I took to get E-Mail up and running in my application.

Setup

First things first, you need to open app/Config/email.php.default and save it as email.php. In your new email config file, add a basic transport details (multiple transports can be created and used). In the example below, I have created a basic SMTP transport which sends email in both plain text and HTML by default.

//app/Config/email.php
class EmailConfig {
    
	public $smtp = array(
		'transport' => 'Smtp', //transport method
		'from' => array('noreply@denishogan.ie' => 'denishogan.ie'), //an array containing the "from" address and sender name
		'host' => 'mail.server.net',//add your SMTP mail server here
		'port' => 25, //port your outgoing mail should be sent via. 25 is normally fine for SMTP, but may be different for some mail services
		'username' => 'usernameForMyAccount',//the username for my account
		'password' => 'passwordForMyAccount',//the password for my account
        'emailFormat' => 'both'//you can select text, html (or both)
		'log' => false, //log the email headers and message
	);
    
}


In your Controller

Make sure that you are loading the CakeEmail class at the top of your controller. Then to send your E-Mail, simply specify recipients, a subject and the name of the view you wish to use to display your email.

In this case, I have added a few more details – I have chosen to override the default sender details as specified in the SMTP transport config. I am also passing in a few variables for use in the E-Mail views.

//in your controller.php
App::uses('CakeEmail', 'Network/Email'); // this should be placed before your Controller Class

class UsersController extends AppController {
    public function add() {
        if($this->request->is('post'))
        {
            //do something clever with the request data
            if($this->User->save($this->request->data))
            {
                $newUserID = $this->User->id; //get the id of the newly saved/inserted user.
                
                //send an email to say that the user data was saved
                //Start email functionality
                $recipients = array('recipient1@here.ie','recipient2@there.com');//multiple recipients can be defined in an array.
    			$from = array('denis@blah.ie' => 'Denis Hogan'); // Say who the email is from if you wish to override the settings in your transport config.
				$subject = "New User added to this wonderful CakePHP application: ".$this->request->data['User']['name']; //Set your subject line.
				$viewVars = array('user_id'=>$newUserID,'user_name'=> $this->request->data['User']['name']);//pass an array of variables to the email view if required - no need for this in static messages.
				$template = 'new_user_template';// specify the name of the email template you wish to use.
				$this->sendMail($recipients, $from, $subject, $viewVars, $template);
				//End email functionality
                
				$this->Session->setFlash(__('The User has been saved'), 'default', array('class' => 'message success'));// set a flash message to confirm that the user details were saved.
				$this->redirect(array('action' => 'index')); //redirect back to the index view.
            }
            else
            {
                //the user details could not be saved šŸ™ - display an error
                $this->Session->setFlash(__('The user details could not be saved. Please, try again.'));
            }
        }
        else
        {
            //The user has not submitted data, so display the add view - irrelevant in this example.
        }
    }
}


Plain Text & HTML Layouts

Ok, we are making progress. But there are a few more jobs to be done before we can send our mail. The first thing you need to do is to create both plain text and HTML layouts. You can find the defaults for both in app/View/Layouts/Email/ in their corresponding folders.

If you plan on using an array of different designs for sending email from your application (i.e. for sending out seasonal promotions, internal/external branding, etc.), you can create multiple templates here, each with bespoke CSS for the mail you wish to send.

For the purpose of this example, I am going to keep it simple and use the default layout (default.ctp).

Plain Text & HTML E-Mail Views

E-Mail view are different from layouts in that layouts allow you to define the look and feel of your (HTML) E-Mail (i.e. they contain the structural HTML and CSS). However Views allow you to format the content as you see fit.

As you saw in the snippet above, I chose to use an email view called “new_user_template” and passed in two variables, a user ID and a user name. I will need to create a view with a message in it to display this information. But ,because I am sending the email in both Plain Text and HTML formats, I will need to create a template for each format.

To do this, make your way to app/View/Emails/html and create a new file called new_user_template.ctp. In this file, you can format your E-Mail body content as you would like using HTML. You can access your variables as passed in the $viewVars variable in the controller (see above).

Here is an example of a HTML view that uses the variables passed in from the controller above.

<p>A new user has been created. The user's name is <b><?php echo $user_name; ?></b>.</p>
<p>You can view their details here: <a href="http://myxyzapp.com/users/view/<?php echo $user_id; ?>">http://myxyzapp.com/users/view/<?php echo $user_id; ?></a></p>


The plain text alternative is very similar – however it doesn’t contain any HTML.

A new user has been created. The user's name is <?php echo $user_name."\n"; ?>.
You can view their details by copying the following link into your browser: http://myxyzapp.com/users/view/<?php echo $user_id."\n"; ?>


And that’s all there is to it! I have only scratched the surface here, there is much more you can do on both the configuration and templating of emails.

 

 

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.