Brief Overview of the new EmailComponent
It's often more practical (read: maintainable) to use the built in components and much as I like SwiftMailer, I thought it best that I investigated Cake's core EmailComponent.
Big Note: The examples below are not intented for production servers, but just to give an idea of the files/code snippets needed to send email.
First create your email layouts. Create a default.ctp in the following directories:
The text layout (not a template):
This is a dummy controller for demonstration purposes only:
Pretty easy so far. Note: by default Cake EmailComponent uses the built in php mail() function, so if you are having problems, please ensure you can use that function successfully directly from a php script.
The mail function used by $this->Email->send() can be set via $this->Email->delivery to 'mail' or 'smtp', but I have only tested 'mail' (the default).
Create the following template in views/elements/email/text/test.ctp:
And the function for the dummy controller:
Nothing very new here, just set view variables as you would normally (they are shared across all views). If you expect to have lots of email templates (elements), then you can organize them within sub-directories of view/elements/email/text and view/elements/email/html then prefix 'mydir/' to the $this->Email->template value. e.g.: $this->Email->template = 'mydir/test'.
Create the following template in views/elements/email/text/test2.ctp:
Example function for our dummy Mailer controller:
That's all there is to it. Cake's EmailComponent is also able to handle attachments, but that is for a later date.
The last function did not work until I had 'fixed' a few things in email.php. See https://trac.cakephp.org/ticket/1851 if you want to play now.
First create your email layouts. Create a default.ctp in the following directories:
views/layouts/email/text/
views/layouts/email/html/
The text layout (not a template):
View Template:
<?php echo $content_for_layout; ?>
and the html layout:View Template:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body>
<?php echo $content_for_layout; ?>
</body>
</html>
This is a dummy controller for demonstration purposes only:
Controller Class:
<?php
class MailerController extends AppController {
var $name = 'Mailer';
//Not using a model
var $uses = '';
//The built in Cake Mailer
var $components = array('Email');
}
?>
Simple text Message
To send a simple text message (useful for alerts etc), you do not need templates. Example function for the dummy Mailer controller:Controller Class:
<?php
/**
* Send a text string as email body
*/
function sendSimpleMail() {
$this->Email->to = 'yourlogin@localhost';
$this->Email->subject = 'Cake test simple email';
$this->Email->replyTo = 'noreply@example.com';
$this->Email->from = 'Cake Test Account <noreply@example.com>';
//Set the body of the mail as we send it.
//Note: the text can be an array, each element will appear as a
//seperate line in the message body.
if ( $this->Email->send('Here is the body of the email') ) {
$this->Session->setFlash('Simple email sent');
} else {
$this->Session->setFlash('Simple email not sent');
}
$this->redirect('/');
}
?>
This can be called from http://localhost/mailer/sendSimpleMail - if all is OK, you should receive an email just by visiting the URL.Pretty easy so far. Note: by default Cake EmailComponent uses the built in php mail() function, so if you are having problems, please ensure you can use that function successfully directly from a php script.
The mail function used by $this->Email->send() can be set via $this->Email->delivery to 'mail' or 'smtp', but I have only tested 'mail' (the default).
Text Message from a Template
Templates for emails are stored by default in views/element/email/text or views/elements/email/htmlCreate the following template in views/elements/email/text/test.ctp:
View Template:
Here is the template body text.
<?php echo $someValue; ?>
And the function for the dummy controller:
Controller Class:
<?php
/**
* Use a layout for the message body
* Create the following files:
* views/elements/email/text/test.ctp
*
* containing: the layout you want for your email
*
*/
function sendTemplateMail() {
$this->Email->to = 'yourlogin@localhost';
$this->Email->subject = 'Cake test template email';
$this->Email->replyTo = 'noreply@example.com';
$this->Email->from = 'Cake Test Account <noreply@example.com>';
$this->Email->template = 'test';
//Set view variables as normal
$this->set('someValue', 'Cake tastes good today');
//Do not pass any args to send()
if ( $this->Email->send() ) {
$this->Session->setFlash('Template email sent');
} else {
$this->Session->setFlash('Template email not sent');
}
$this->redirect('/');
}
?>
Nothing very new here, just set view variables as you would normally (they are shared across all views). If you expect to have lots of email templates (elements), then you can organize them within sub-directories of view/elements/email/text and view/elements/email/html then prefix 'mydir/' to the $this->Email->template value. e.g.: $this->Email->template = 'mydir/test'.
Html Message from a template
Cake's Mail component supports 'text', 'html' or 'both' styles of email. The default is (quite rightly) 'text' and can be changed via $this->Email->sendAs().Create the following template in views/elements/email/text/test2.ctp:
View Template:
Here is the template body text for test2.
<?php echo $someValue; ?>
and views/elements/email/html/test2.ctp:View Template:
<h2>
Here is the template body text.
</h2>
<p><em><?php echo $someValue; ?></em></p>
Example function for our dummy Mailer controller:
Controller Class:
<?php
/**
* Use a layout for the message body
* Create the following files:
* views/elements/email/html/test2.ctp
* views/element/email/text/test2.ctp
*
* containing: the layouts you want for your email
*
*/
function sendTemplateHtmlMail() {
$this->Email->to = 'yourlogin@localhost';
$this->Email->subject = 'Cake test template email';
$this->Email->replyTo = 'noreply@example.com';
$this->Email->from = 'Cake Test Account <noreply@example.com>';
$this->Email->template = 'test2';
//Send as 'html', 'text' or 'both' (default is 'text')
$this->Email->sendAs = 'both';
//Set view variables as normal
$this->set('someValue', 'Cake and cream is good for you');
//Do not pass any args to send()
if ( $this->Email->send() ) {
$this->Session->setFlash('Template html email sent');
} else {
$this->Session->setFlash('Template html email not sent');
}
// $this->redirect('/');
}
?>
That's all there is to it. Cake's EmailComponent is also able to handle attachments, but that is for a later date.
The last function did not work until I had 'fixed' a few things in email.php. See https://trac.cakephp.org/ticket/1851 if you want to play now.








$this->Email->send() always returns false !!!!
Any ideas? Thanks in advance
$this->Email->delivery = 'smtp';
otherwise you may have the same problem many people seem to having - emails not sending to certain addresses.
Embedding your display images for HTML, and using the "cid:" syntax to reference them, is a great way for your emails to be more tolerant of spam filters. But the EmailComponent isn't setting the Content-ID header for attachments, so the images don't render in all clients (e.g., MS Outlook works, but GMail doesn't). With a small change to email.php you can fix this easily though.
I've opened a ticket (https://trac.cakephp.org/ticket/6358) to track this; check it out for details.
The mail sending doesnt work while sending mail in sendAs = 'both'
I removed the @ to see what mail() is complaining about.
Warning (2): mail() [function.mail]: Bad parameters to mail() function, mail not sent. [CORE/cake/libs/controller/components/email.php, line 656]
I have posted the mail data which is being sent to cakebin. The url is http://bin.cakephp.org/view/26733214thanks
- Jesse
http://www.jessefreeman.com http://www.flashartofwar.com
** EDIT: Nevermind, this was actually a reverse DNS issue with my server. If you find that you are having issues sending to certain email addresses you can check your reverse dns for your server here: http://postmaster.info.aol.com/tools/rdns.html **
@Rob: what are you using for line breaks? I've been using \\n in my mail content and it seems to translate correctly.
i just wanna say thank you for the tut, i've tried it and everything worked as you have described!!
if anyone has questions, please ask and i will try to help out.
Joren
it's like i have a choice.. two line breaks or none.. :(
I've downloaded cake_1.2.0.5146alpha.zip yesterday, replaced the cake folder of the cake_1.1.14.4797 installation. All's well except that the email component doesn't send mail.
What I've done:
1. There's a default.ctp in app/views/layouts/email/html and app/views/layouts/email/text.
2. Created the mailcontroller:
class MailerController extends AppController {
var $name = 'Mailer';
var $uses = '';
var $components = array( 'Email' );
function sendSimpleMail() {
$this->Email->to = 'romano@iblis.demon.nl';
$this->Email->subject = 'Cake test simple email';
$this->Email->replyTo = 'noreply@adomain.com';
$this->Email->from = 'Cake Test Account
$this->Email->template = null;
if ( $this->Email->send('Here is the body of the email') ) {
// $this->Session->setFlash('Simple email sent');
// exit( 'ja' );
}
else {
// $this->Session->setFlash('Simple email not sent');
// exit( 'nee' );
}
$this->redirect('/');
}
}
Called the action via the url.
Any ideas where I might find the solution to this problem?
Best regards,
Romano
Ciao,
Romano
As far as I'm aware (i.e. my apps still work), nothing has changed wrt layouts and templates. The text and html layouts (for all mails) are still located in views/layouts/email/* and the individual templates (for each mail) are in views/elements/email/*
~GreyCells
Notice: Undefined variable: aVariable in /blah/blah/user/htdocs/create/app/views/elements/email/text/invite.ctp on line 3
To get over this you can use $this->Email->Controller->set() instead.
Huey
In the tutorial you warn that:
"The examples below are not intented for production servers"
and: "This is a dummy controller for demonstration purposes only."
What's wrong with using this code for a production server? Besides continuing to tailor the code to our own application, is there something wrong with using the example code as is? Could you list the things you would recommend shoring up before releasing this code into the wild?
Many thanks!
Robin
Many thanks!
Robin
Which sort of answers Huey/Jeff's question. I'm not a big fan of captcha's etc because of accessability issues, although they do have their place. There is a lot you can do to mitigate the risk if you implement a simple IP address based throttling system and use Cake's security component.
Robin - Why use SwiftMailer? Well, it's a mature, feature complete library that allows you to very easily do things such as attachments etc. I'm sure Cake's mail component will match the features and stability soon, but don't forget 1.2 is still in heavy development.
~GreyCells
See: https://trac.cakephp.org/ticket/2105
~GreyCells
Comments are closed for articles over a year old