SwiftMailer Component
This is a component that does encapsulate but not hide swift mailer.
In addition, it adds some nifty features.
In short, this is just a delicious cake-ish swift Mailer.
In addition, it adds some nifty features.
In short, this is just a delicious cake-ish swift Mailer.
Component Class:
Download code
<?php
/*
* SwiftMailer Component By othman ouahbi.
* comments, bug reports are welcome crazylegs AT gmail DOT com
* @author othman ouahbi aka CraZyLeGs
* @version 0.1
* @license MIT
*/
class SwiftMailerComponent extends Object {
var $controller = false;
var $mailer = null;
var $connection = 'smtp'; // sendmail, native
var $smtp_host = null; // null auto detect
var $smtp_port = false; // false to let the mailer choose. default 25, 465 for ssl.
var $smtp_type = 'open'; // open, ssl, tls
var $username = null;
var $password = null;
var $layout = 'swift_email';
var $email_views_dir = 'swift_emails';
var $sendmail_cmd = false; // false: SWIFT_AUTO_DETECT, 'default': '/usr/sbin/sendmail -bs' etc..
function startup(& $controller) {
$this->controller = & $controller;
}
function connect() {
switch ($this->connection) {
case 'smtp' :
$this->connect_smtp();
break;
case 'sendmail' :
$this->connect_sendmail();
break;
case 'native' :
default :
$this->connect_native();
break;
}
return $this->mailer->isConnected();
}
function connect_native() {
vendor('Swift');
vendor('Swift/Connection/NativeMail');
$this->mailer = new Swift(new Swift_Connection_NativeMail());
}
function connect_sendmail() {
vendor('Swift');
vendor('Swift/Connection/SendMail');
if ($this->sendmail_cmd == false) {
$this->sendmail_cmd = SWIFT_AUTO_DETECT;
}
elseif ($this->sendmail_cmd == 'default') {
$this->sendmail_cmd = '/usr/sbin/sendmail -bs';
}
$this->mailer = new Swift(new Swift_Connection_SendMail($this->sendmail_cmd));
}
function connect_smtp() {
vendor('Swift');
vendor('Swift/Connection/SMTP');
// SWIFT_AUTO_DETECT
if (is_null($this->smtp_host)) {
$this->smtp_host = SWIFT_AUTO_DETECT;
}
if (is_null($this->smtp_port)) {
$this->smtp_port = SWIFT_AUTO_DETECT;
}
$ssl_types = array('open'=>SWIFT_OPEN,'ssl'=>SWIFT_SSL,'tls'=>SWIFT_TLS);
if(in_array($this->smtp_type, array ('open','ssl','tls')))
{
$ssl_type = $ssl_types[$this->smtp_type];
}else
{
$ssl_type = $ssl_types['open'];
}
$this->mailer = new Swift(new Swift_Connection_SMTP($this->smtp_host, $this->smtp_port, $ssl_type));
}
function auth() {
return ($this->mailer->authenticate($this->username, $this->password));
}
function errors() {
return $this->mailer->errors;
}
function transactions() {
return $this->mailer->transactions;
}
function close() {
$this->mailer->close();
}
/*
* description:
* Renders a body view located in the emails dir.
* if html, wraps it with a layout and embeds images that have the embed="swift" attribute
* strip tags if plain.
*/
function viewBody($name, $type = 'both', $return = false) {
switch ($type) {
case 'both' :
$plain = true;
$html = true;
break;
case 'html' :
$html = true;
break;
case 'plain' :
$plain = true;
break;
default :
return;
break;
}
if (isset ($html)) {
$name .= "_html";
$view = VIEWS . $this->email_views_dir . DS . $name . '.thtml';
$old_layout = $this->controller->layout;
ob_start();
$this->controller->render(null, $this->layout, $view);
$html_msg = ob_get_clean();
$html_msg = $this->replaceIMG($html_msg);
$this->controller->layout = $old_layout;
}
if (isset ($plain)) {
$view = VIEWS . $this->email_views_dir . DS . $name . '.thtml';
$old_layout = $this->controller->layout;
$this->controller->layout = '';
ob_start();
$this->controller->render(null, null, $view);
$plain_msg = strip_tags(ob_get_clean());
$this->controller->layout = $old_layout;
}
switch ($type) {
case 'both' :
if ($return) {
return array (
$plain_msg,
$html_msg
);
}
$this->mailer->addPart($html_msg, 'text/html');
$this->mailer->addPart($plain_msg, 'text/plain');
break;
case 'html' :
if ($return) {
return $html_msg;
}
$this->mailer->addPart($html_msg, 'text/html');
break;
case 'plain' :
if ($return) {
return $plain_msg;
}
$this->mailer->addPart($plain_msg, 'text/plain');
break;
}
}
function replaceIMG($msg) {
$matches = array ();
$files = array ();
if (preg_match_all('#<img.*src=\"(.*?)\".*?\/>#', $msg, $matches)) {
for ($i = 0; $i < count($matches[0]); $i++) {
$pos = strpos($matches[0][$i], 'embed="swift"');
if ($pos !== false) {
$file = substr($matches[1][$i], strrpos($matches[1][$i], '/') + 1);
if (array_key_exists($file, $files)) {
$replace = $files[$file];
} else {
$replace = $this->mailer->addImage(WWW_ROOT . 'img' . DS . $file);
$files[$file] = $replace;
}
$msg = str_replace($matches[1][$i], $replace, $msg);
}
}
}
return $msg;
}
/*
* description:
* Wraps the body with a layout, strips tags if not html
*/
function wrapBody($msg, $type = 'plain', $return = false) {
$view = VIEWS . $this->email_views_dir . DS . 'default.thtml';
$this->controller->set('swiftMailer_data', $msg);
ob_start();
$this->controller->render(null, $this->layout, $view);
$msg = ob_get_clean();
if ($type != 'html') {
$msg = strip_tags($msg);
}
if ($return) {
return $msg;
}
$this->mailer->addPart($msg, ($type == 'html') ? 'text/html' : 'text/plain');
}
// original idea Tommy0
function addTo($type, $address, $name = false) {
if (in_array($type, array (
'to',
'from',
'cc',
'bcc'
))) {
if (!$name) {
$val = $address;
} else {
$val = array (
$name,
$address
);
}
if ($type == 'from') {
$this-> $type = $val;
} else {
if (!isset ($this-> $type)) {
$this-> $type = array ();
}
array_push($this-> $type, $val);
}
}
}
// original idea Tommy0
function send($subject) {
if (!empty ($this->cc)) {
$this->mailer->addCc($this->cc);
}
if (!empty ($this->bcc)) {
$this->mailer->addBcc($this->bcc);
}
if (is_array($this->from)) {
$from = '"' . $this->from[0] . '" <' . $this->from[1] . '>';
} else {
$from = $this->from;
}
if (!empty ($this->username) && !$this->auth()) {
return false;
}
if ($this->mailer->send($this->to, $from, $subject)) {
$this->mailer->close();
return true;
}
return false;
}
function sendWrap($subject, $body, $type = 'plain') {
$this->wrapBody($body, $type);
return $this->send($subject);
}
function sendView($subject, $view, $type = 'plain') {
$this->viewBody($view, $type);
return $this->send($subject);
}
}
?>
Comments
Bug
1 Destination error when sending several mails
Thanks for the great component
Ive noticed that when in the same controller action, several mails have to be sent, it is needed to reset the 'to' (also cc, bcc or from) list, otherwise all recipients from previous mails will receive other mails.
I've inserted this code snippet to be able to reset the different lists from the controller action :
8<------------
function resetTo($type) {
if (in_array($type, array (
'to',
'from',
'cc',
'bcc',
'all'
))) {
if ($type == 'all') {
$this->resetTo('from');
$this->resetTo('to');
$this->resetTo('cc');
$this->resetTo('bcc');
} else {
if (isset ($this-> $type)) {
unset($this-> $type);
}
}
}
}
---------------------
For me it worked like a charm and until now, I've seen no side effect.
Best regards
Flow
Bug
2 typo
function connect_sendmail() {
vendor('Swift');
vendor('Swift/Connection/SendMail');
should be:
function connect_sendmail() {
vendor('Swift');
vendor('Swift/Connection/Sendmail');
Bug
3 view output
...
$view = VIEWS . $this->email_views_dir . DS . 'default.thtml';
...
$this->controller->render(null, $this->layout, $view);
It is not applied.
Comment
4 cake version
Bug
5 error
Fatal error: Call to undefined method Swift::isConnected() in E:xampphtdocsportfolioappcontrollerscomponentsswift_mailer.php on line 46
Question
6 Update for Swift 3.x
Comment
7 Update for Swift 3.x
Question
8 Any Update for Swift 3.x
as i am getting this error
Fatal error: Call to undefined method Swift::isConnected() in E:xampphtdocsportfolioappcontrollerscomponentsswift_mailer.php on line 46
thanks in Advance
Comment
9 3.x update
Comment
10 Use EasySwift with 3.x
Next, edit the component and change all occurrences of vendor('Swift') to vendor('EasySwift'). Also change all occurrences of new Swift() to new EasySwift().
Question
11 EasySwift with 3.x does not work
/ SwiftMailer
$this->SwiftMailer->connection = 'smtp';
$this->SwiftMailer->smtp_host = 'mail.gmx.net';
$this->SwiftMailer->smtp_port = 25;
$this->SwiftMailer->smtp_type = 'open';
$this->SwiftMailer->username = '<address>';
$this->SwiftMailer->password = '<password>';
if($this->SwiftMailer->connect())
{
$this->SwiftMailer->addTo('to',"xyz@web.de","Mr. XYZ");
$this->SwiftMailer->addTo('from',"abc@gmx.de","Mr. ABC");
//$this->SwiftMailer->sendView("Golfstartzeiten-Planer Password vergessen",'default');
//if(!$this->SwiftMailer->sendWrap("Golfstartzeiten-Planer Password vergessen",'default'))
if(!$this->SwiftMailer->send("Golfstartzeiten-Planer Password vergessen"))
{
echo "The mailer failed to Send. Errors:";
pr($this->SwiftMailer->errors());
}
echo "Log:";
pr($this->SwiftMailer->transactions());
}
else
{
echo "The mailer failed to connect. Errors:";
pr($this->SwiftMailer->errors());
}
This error is always shown:
The mailer failed to Send. Errors:
Array
(
)
//-------------------------------------------
Any Ideas here!
Comment
12 CakePHP SwiftMailer 3 Component