Reputation: 835
I'm trying to set up a test email in my controller that outputs the email as it would look, without actually sending the email. I am using CakePHP 2.1
At the top of my controller I have:
App::uses('CakeEmail', 'Network/Email');
And in my controller the method is:
$email = new CakeEmail('default');
$email->from(array('[email protected]' => 'My Site'));
$email->to('[email protected]');
$email->subject('About');
$email->send('My message');
In my email config I have set the $default to Debug mode:
public $default = array(
'transport' => 'Debug',
'from' => '[email protected]',
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
);
How can I output the email? I have scoured Google and have come back with nothing.
Upvotes: 3
Views: 8848
Reputation: 75
It is possible to view your email and what it will look like without actually sending it. It's a neat little trick I discovered and quite useful, although it might be a little "hacky":
The trick is to render your email including any data into a specific layout and template, and then display this structure before sending it with the Email component. I came up with the following function to test emails (debug them):
public function debugEmail() {
// set some data for your email
$data = 'foo';
$this->set(compact('data'));
// setup layout and a View instance
$this->layout = 'Emails/html/default';
$View = new View($this, false);
// render the email template including the layout into a variable
$html = $View->render('../Emails/html/cron/your_template');
// print the contents on screen (do NOT use pr() here!)
print_r($html);
exit;
}
The example utilizes the setting of the layout to the default html email layout and a template called your_template. It simple renders the email-template framed within the given layout into a variable and prints it on the screen. The browser will interprete the HTML and you will see how your email will look like.
Note: Some email-clients will display your html slightly different. You will need to use inline-styles (CSS) and do a cross-program check to verify that everything's in place. The function is mainly used to check if the given data is structured and displayed correctly within my emails.
Upvotes: 1
Reputation: 310
The send() method actually returns an array containing the headers and body of the email (each as a string). So if you're writing unit tests, you can search those strings to see if they contain what they should.
If you want to run the send command without sending an email, you can change the transport method to the "Debug" transport, which goes through the motions of formatting your email without actually sending it.
For example:
$email = new CakeEmail();
$email->transport('Debug');
$response = $email->send();
echo $response['headers']; // headers as string
echo $response['message']; // message body with attachments
Note, if you're sending HTML emails and/or using attachments, the body will contain those items in some sort of encoded form. If you're sending plain and HTML encoded emails some content will appear twice (once plain and again as HTML).
Like Drawrdesign, I'd plan to provide a preview of my email in the browser. There are two methods to consider:
I'll try to update my answer once I have implemented a solution.
Upvotes: 9
Reputation: 25698
Construct the CakeEmail with log enabled:
$Email = new CakeEmail(array('log' => true));
The following code is an excerpt of the CakeEmail classes send() method, it should be pretty self-explaining.
$contents = $this->transportClass()->send($this);
if (!empty($this->_config['log'])) {
$level = LOG_DEBUG;
if ($this->_config['log'] !== true) {
$level = $this->_config['log'];
}
CakeLog::write($level, PHP_EOL . $contents['headers'] . PHP_EOL . $contents['message']);
}
return $contents;
So your email will end up in that log file.
If you don't like that feel free to write your own transport class and log to database, session or simply debug() the output in your transport class, do as you like!
Upvotes: 5