SwiftMailer Component

This article is also available in the following languages:
By CraZyLeGs
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.

Component Class:

<?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(nullnull$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

  • Posted 05/07/08 10:45:21 AM
    I adjusted the component, so it works with SwiftMailer 3. You can find it at http://blog.aboutme.be/2008/05/07/cakephp-swiftmailer-3-component/
  • Posted 07/29/07 06:11:20 AM
    I made all changes. But with Swift 3.2.6 PHP5 it works not!

    / 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 = '
    ';
    $this->SwiftMailer->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!
  • Posted 06/17/07 04:53:12 PM
    This component works with 3.x with some minor changes. Follow the install instructions from the tutorial and additionally copy EasySwift.php in to app/vendors.

    Next, edit the component and change all occurrences of vendor('Swift') to vendor('EasySwift'). Also change all occurrences of new Swift() to new EasySwift().
  • Posted 06/05/07 08:10:20 AM
    Any update for Swift 3.x.x .i waiting for it

    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
  • Posted 04/21/07 03:17:41 PM
    Funny you should mention it, I wrote an update for it last night. A simple method of update would be to use EasySwift instead of the Swift library. The update I wrote doesn't use that since they stated they have no idea how long it will stay around. I'll post the component and such after I review my code and make sure it isn't crap. I'll also add support for attaching files.
  • Posted 04/21/07 12:23:45 PM
    Great component - very handy. Any plans for an update that will work with Swift 3.x.x? Thanks.

  • Posted 01/09/07 07:57:45 AM
    as far as i can tel there is a typo in the connect_sendmail function.

    function connect_sendmail() {
    vendor('Swift');
    vendor('Swift/Connection/SendMail');

    should be:

    function connect_sendmail() {
    vendor('Swift');
    vendor('Swift/Connection/Sendmail');
  • Posted 12/31/06 06:08:27 AM
    Hi !

    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
  • Posted 11/30/99 12:00:00 AM

    ...
    $view = VIEWS . $this->email_views_dir . DS . 'default.thtml';
    ...
    $this->controller->render(null, $this->layout, $view);

    It is not applied.
  • Posted 11/30/99 12:00:00 AM
    All i get is..

    Fatal error: Call to undefined method Swift::isConnected() in E:\xampp\htdocs\portfolio\app\controllers\components\swift_mailer.php on line 46

Comments are closed for articles over a year old