Stop ACTA

Using EmailComponent in CakePHP 1.2

Posted in CakePHP on 28.05.2008.

It seems like people still have problems with EmailComponent, so here's a short tutorial.

There really isn't much to it. For starters, let's assume you have a CommentsController and you want to send a notification each time someone leaves a comment on your site.

The first thing you need to do is include the EmailComponent. Like this:

class CommentsController extends AppController
{
    var $components = array('Email');
}

Now, to send an email, you need two things: email templates (for content) and layouts. Basically, email layout has the same purpose as regular layout - to wrap your content. And templates are where your content will go. Enough of theory, this is how it looks like in practice.

This example assumes you're sending an email in both HTML and plain text format.

Location of your layouts and templates are as follows:

  • ~/app/views/layouts/email/html/default.ctp
  • ~/app/views/layouts/email/text/default.ctp
  • ~/app/views/elements/email/html/new_comment.ctp
  • ~/app/views/elements/email/text/new_comment.ctp

How do you use them? Here's a brief example of the layout:

// ~/app/views/layouts/email/html/default.ctp
<?php echo $content_for_layout; ?>
<br />
-- Hello, this is my email signature

...and the template:

// ~/app/views/elements/email/html/new_comment.ctp
<p>Dear <?php echo $email_user['name']; ?>,
<br /><br />
Thou shalt clicketh: "<?php echo $email_article['Article']['title']; ?>".
</p>
// etc..

Now, all that remains is to glue all that up with your controller, setting up EmailComponent properties and variables. Setting variables for email templates works the same as setting variables for your view.

$this->Email->reset();
$this->Email->sendAs = 'both'; // both = html + plain text
$this->Email->to = '"'.$user['name'].'" <' . $user['email'] . '>';
$this->Email->from = '<noreply@'.env('HTTP_HOST').'>';
$this->Email->replyTo = '<noreply@'.env('HTTP_HOST').'>';
$this->Email->return = '<noreply@'.env('HTTP_HOST').'>';
$this->Email->subject = 'your amazing subject here';
$this->Email->template = 'new_comment';
// of course, if you have multiple layouts, you can change that too
//$this->Email->layout = 'my_bleeding_layout';
// this would require you to have my_bleeding_layout:
// ~/app/views/layouts/email/html/my_bleeding_layout.ctp
// ~/app/views/layouts/email/text/my_bleeding_layout.ctp

// set some variables for your templates
$this->set('email_user', $user);
$this->set('email_comment', $comment);
$this->set('email_article', $article);

// uncomment this to debug EmailComponent instead of sending
//$this->Email->_debug = true;
$this->Email->send();

That's all there is to it. When I started messing with EmailComponent it was quite new and I had to figure out all of this on my own. But now when you look at it, it's quite simple.

Like most of things in Cake, as long as you stick to the API reference and The Cookbook, you can accomplish nearly everything on your own. Documentation has really made a huge progress.

Happy baking!

Article comments — View · Add


Page 1 of 3
1 · 2 · 3

Wilco :: 06.03.2009 07:51:10
When I use this class with your example code, instead of the regular mail() function, the HTML is added in Microsoft Outlook 2003 as an attachment.

Do you have any idea, why it's not displayed directly?

Thanks in advance
lecterror :: 06.03.2009 08:14:55
Well, I can't say that I do. Knowing Microsoft, it's probably a faulty MIME parser.

Did you try opening your generated mail in Thunderbird or GMail? If they are doing it wrong too, then we have a problem.

If not, Microsoft has a problem..
Wilco :: 09.03.2009 02:33:47
I finally found the problem!

It turned out that the MailComponent did not added the 'MIME-Version' to the headers of the email.

So I edited this in the cake-core.
lecterror :: 09.03.2009 03:11:38
Excellent!

If you have the time, help the cake devs and file a patch+test case on cake trac, I'm sure they'll appreciate it.

Cheers!
roberto :: 30.11.2009 12:42:19
Do you know if there is a way using EmailComponent in CakePHP to parse a raw email into something readable?