Posts Tagged ‘component’

CakePHP Email component

Tuesday, October 20th, 2009

This is quite a simple component that integrates PHPMailer with CakePHP. Save the following code to /app/controllers/components/email.php

<?php 

App::import('Vendor', 'PhpMailer', array('file' => 'phpmailer' . DS . 'class.phpmailer.php'));

/*
    Depends on "unhtml"
*/

class EmailComponent extends PHPMailer
{
	// phpmailer
	var $Mailer = 'sendmail'; // choose 'sendmail', 'mail', 'smtp'
	var $unhtml_bin = '/usr/bin/unhtml';

	// component
	var $controller;

	function startup( &$controller )
	{
		$this->controller = &$controller;
	}

	function renderBody($view)
	{
		// render the view and use its output to set the body text of the email
		$this->Body = $this->controller->render('emails/' . $view, 'email');

		// reset the output of the controller
		$this->controller->output = '';

		// create plain text version of the email
		//
		// create temporary files
		$htmlfile = tempnam(TMP, 'htmlfile');
		$textfile = tempnam(TMP, 'textfile');

		// write html to temporary file
		file_put_contents($htmlfile, $this->Body);

		// convert the html file to plain text
		$cmd = "cat $htmlfile | $this->unhtml_bin > $textfile";
		system($cmd);

		// set the plain text body of the email
		$this->AltBody = file_get_contents($textfile);

		// remove temporary files
		unlink($htmlfile);
		unlink($textfile);
	}
}

?>

In addition to that, make sure phpmailer is installed in /app/vendors/phpmailer. I just extracted the phpmailer archive in /app/vendors/ and created a symlink:

$ tar xzf PHPMailer_v5.0.2.tar.gz
$ ln -s PHPMailer_v5.0.2 phpmailer

Usage
In your controller code, make sure the component is included by adding it to the components array:

var $components = array('Email');

In app/views/layouts, create a new layout called email.ctp. It should contain something like:

<html>
<body>
<?php echo $content_for_layout; ?>
</body>
</html>

Let’s send some emails!
In controller snippet, the renderBody(‘test’) call will create a html email from the view in app/views/users/emails/test.ctp. Additionally, a plain text version will be generated using ‘unhtml’. Unhtml has a package in the Ubuntu / Debian repository.
The action works just like rendering a normal view. The $this->Email object is just an instance of PHPMailer and all PHPMailers’ methods and properties apply.

function testmail()
{
	// *Some notes*
	// Email methods:    http://phpmailer.worxware.com/index.php?pg=methods
	// Email properties: http://phpmailer.worxware.com/index.php?pg=properties
	//
	// Email configuration is done in /app/controllers/components/email.php

	$this->set(compact('some', 'vars'));

	// the email content is just a (html) view in app/views/{controller}/emails/testmail.ctp
	$this->Email->renderBody('test');

	// subject
	$this->Email->Subject = 'Test from example.com';

	// sender
	$this->Email->SetFrom('test@example.com', 'Test');

	// recipients
	$this->Email->AddAddress('joe@example.com', 'Joe');
	$this->Email->AddAddress('jane@example.com', 'Jane');

	// send!
	$this->Email->Send();
}