Yii 1.1: mailer

Mailer using PHPMailer
72 followers

EMailer is a simple wrapper for the PHPMailer library, which is bundled. You should keep an eye on this library, since it could be updated and the API could get broken.

Please read the source code comments for licensing information. Please read the phpmailer/LICENCE file for the PHPMailer license.

FAQ

  • Why should I use this extension instead of using the phpmailer directly?

Answer: this is encapsulated as a Yii extension, and you can modify the methods or extend the functionality as you'd like, instead of modifying the original source code :)

  • Why the license was GPL on the download page when the extension is released under LGPL?

Answer: my mistake. The license for this extension is and has always been LGPL.

  • My view has images on it, but when it is send as e-mail, no images are shown. Why?

You must place the images in a public HTTP server, since you're using the tag in your view.

File checksums

  • 847183726a2e59d8aa5968e2fa6f7597 mailer-2.2.tar.bz2
  • bef73d62003ab84399706c578294cccb mailer-2.2.zip

Resources

Documentation

Requirements

  • Yii 1.0 or above
  • PHPMailer (version 5.0 bundled)

Installation

  • Extract the release file under protected/extensions

Usage

As a normal component:

Usage example, using SMTP as the sending method, creating a component inside a controller:

<?php
$message = 'Hello World!';
$mailer = Yii::createComponent('application.extensions.mailer.EMailer');
$mailer->Host = <your smtp host>;
$mailer->IsSMTP();
$mailer->From = 'wei@example.com';
$mailer->AddReplyTo('wei@example.com');
$mailer->AddAddress('qiang@example.com');
$mailer->FromName = 'Wei Yard';
$mailer->CharSet = 'UTF-8';
$mailer->Subject = Yii::t('demo', 'Yii rulez!');
$mailer->Body = $message;
$mailer->Send();

As an application component:

In the configuration (notice the pathViews and pathLayouts parameters):

<?php
'components'=>array(
   'mailer' => array(
      'class' => 'application.extensions.mailer.EMailer',
      'pathViews' => 'application.views.email',
      'pathLayouts' => 'application.views.email.layouts'
   ),
   // ...
}

In the controller:

<?php
$message = 'Hello World!';
Yii::app()->mailer->Host = 'smtp.yiiframework.com';
Yii::app()->mailer->IsSMTP();
Yii::app()->mailer->From = 'wei@pradosoft.com';
Yii::app()->mailer->FromName = 'Wei';
Yii::app()->mailer->AddReplyTo('wei@pradosoft.com');
Yii::app()->mailer->AddAddress('qian@yiiframework.com');
Yii::app()->mailer->Subject = 'Yii rulez!';
Yii::app()->mailer->Body = $message;
Yii::app()->mailer->Send();

Since this is a wrapper, please see:

Change Log

20090529 2.2

  • Fixed bug (reported by ooaat)

20090516 2.1

  • Added pathViews and pathLayouts configuration parameters, to indicate a path aliases where the view and layout for getView are.
  • Added an empty init() method to make it work as an application component.

20090411 2.0

  • Updated PHPMailer to version 5.0
  • Included getView method.

Total 20 comments

#16974 report it
Nabi at 2014/04/17 09:31am
plz support from view in theme folder

this extension don't support from view in theme folder by default.

#16973 report it
Nabi at 2014/04/17 09:31am
protected must change to public

About these:

protected $pathViews = 'application.views.email';
   protected $pathLayouts = 'application.views.email.layouts';

I thinks must be "public" var for set custom values.

#16333 report it
kuya1284 at 2014/02/11 04:50pm
Cannot override default property values

If you are having trouble overriding the default property values by setting values in your main config, it's because this extension is using a constructor instead of using the init() method.

If you're having trouble, simply move everything within __construct() into init(), and delete the constructor. You'll also need to make $pathViews and $pathLayouts public.

I also modified my copy by adding a $libPath property so that I can specify my own path to PHPMailer. In my case, I downloaded the latest copy from Github and placed in the vendors directory. I then added the following to init() just before instantiating a new PHPMailer object:

Yii::import("{$this->libPath}.*");
require_once('class.phpmailer.php');

I hope this helps others who run into similar issues.

#15594 report it
Blizz at 2013/11/27 03:58am
Default Config

All you have to do is give the EMailer class a "public $defaultConfig = array()" or so. Instead of $this->_myMailer = new PHPMailer() in the constructor, just let Yii do the work:

$config = $this->defaultConfig;
$config['class'] = 'PHPMailer'; // You might want to add the aliased path if needed
$this->_myMailer = Yii::createComponent($config);

And you have your default configuration.

I actually have the default-config array as the "mailer" in my main configuration and every time I send out a mail I just do $mail = Yii::app()->mailer, set body and subject and send. Then a simple Yii::app()->setComponent('mailer', NULL); is enough to reset it for the next run. I don't need any previews so I just work with PHPMailer directly. No need for the extra layer.

#15593 report it
Bjorn at 2013/11/27 03:27am
Config

Nice and clean extension. And I like PHPmailer anyway. Only wish I could store some defaults in the config. My From, Fromname, isSMTP, Host, AddReplyTo etc. is always the same and I have to repeat this over and over again. Any thoughts on this?

#14823 report it
Esler Larius at 2013/09/12 08:10am
I keep getting the error that SMTP is already defined

I get the error

Cannot redeclare class SMTP in <b>/Developer/php/Mariana/protected/extensions/mailer/phpmailer/class.smtp.php</b> on line <b>49</b>

The code that i'm using is

Yii::app()->mailer->Host = $smtp->host;
Yii::app()->mailer->IsSMTP();
Yii::app()->mailer->SMTPAuth=true;
Yii::app()->mailer->From = $_POST["email"];
Yii::app()->mailer->Port = $smtp->port;
Yii::app()->mailer->Username = $smtp->email;
Yii::app()->mailer->Password = $smtp->password;
Yii::app()->mailer->FromName = $_POST["name"];
Yii::app()->mailer->AddReplyTo($_POST["email"]);
Yii::app()->mailer->AddAddress($smtp->email);
Yii::app()->mailer->Subject = utf8_decode($_POST["subject"]);
Yii::app()->mailer->Body =  utf8_decode($_POST["text"]);
echo Yii::app()->mailer->Send();
#14374 report it
Sebastian at 2013/08/07 04:55am
@undsoft

You can fix this yourself by checking if Yii::app()->controller is set, and if not, you just make a fake Controller:

$controller = new CController('ThisDoesNotMatter');

You can then use $controller->renderInternal instead of $controller->renderPartial.

#14360 report it
undsoft at 2013/08/06 05:57am
Reliance on controller

Right now component relies on current controller. Yii::app()->controller. This is not very good, because in console commands there is no controller and I would still like to send emails.

Please, fix this.

#12778 report it
andrwsv at 2013/04/11 01:17pm
i need know how i get error and mail server

I have two Questions : 1. how i send with server mail ? 2. how i get error when send mail for validate in my code and dont see error to my user. thanks

#12429 report it
Jose H. Milán at 2013/03/20 05:53am
Be carefull

I have had a really serious privacy issue (it is my fault) but it would be fine if you add to this brief some reminders.

If you use Emailer extension as a component and you use it in that way:

Yii::app()->mailer->AddAdress('someaddress@somedomain.com');
Yii::app()->mailer->Send();

REMEMBER! it is not a fresh object, so if you loop to send the same mail to several addresses you will (maybe) need to:

Yii::app()->mailer->ClearAddresses();
    Yii::app()->mailer->ClearCCs();
    Yii::app()->mailer->ClearBCCs();
    Yii::app()->mailer->ClearReplyTos();
    Yii::app()->mailer->ClearAllRecipients();
    Yii::app()->mailer->ClearAttachments();
    Yii::app()->mailer->ClearCustomHeaders();

Otherwise you will generate emails with "visible" addresses in the "To" field. I didn't realize about that because I was in a hurry and it was problematic.

Thanks, the extension is really useful.

#12180 report it
MaziTizeh at 2013/03/04 03:29pm
Hide Header

Hi, is there any way to hide the X-Originating-IP in header for security reason??

#11711 report it
Paul_Kish at 2013/01/29 03:08am
Works

Awesome used the wrapper very nice, for those who want to test smtp on Windows use this awesome dummy smtp application SMTP Tool

#11060 report it
Ziggi at 2012/12/12 07:48pm
Callbacks

PHPMailer 5.2.2 has new feature called "Callbacks".

The documentation says:

**NEW CALLBACK FUNCTION:**

We have had requests for a method to process the results of sending emails through PHPMailer. In this new release, we have implemented a callback function that passes the results of each email sent (to, cc, and/or bcc). We have provided an example that echos the results back to the screen. The callback function can be used for any purpose. With minor modifications, the callback function can be used to create CSV logs, post results to databases, etc.

Well, it is easy in PHPMailer but I have no idea how to use it within Yii framework with MetaYii extension wrapper. Anybody can advise, please?

UPDATE:

The solution is to place the callback function in an application helper component and then pass the result to controller as application parameter.

I hope this might be helpful.

#10877 report it
gallyamow at 2012/11/29 06:11am
Small fix

I think it would be more useful if:

Author change

protected $pathViews = 'application.views.email';
protected $pathLayouts = 'application.views.email.layouts';

to

public $pathViews = null;
public $pathLayouts = null;

and fix the method "getView" as follows

public function getView($view, $vars=array(), $layout=null)
{
    $viewFile=$view;
    if (!is_null($this->pathViews))
    {
        $viewFile=$this->pathViews.'.'.$view;
    }
 
    $body=Yii::app()->controller->renderPartial($viewFile, array_merge($vars, array('content'=>$this->_myMailer)), true);
    /* the rest of the program code */          
}

That fix allow you to set $pathViews and $pathLayouts attributes from the component config

'components'=>array(
    'mailer' => array(
    'class'=>'application.extensions.mailer.EMailer',
    'pathLayouts'=>'application.views.mail.layouts',
    'pathViews'=>'application.views.mail.view',
    ),
    ....

and pass the arbitrary view name to the method "getView"

Yii::app()->mailer->getView('application.modules.feedback.views.mail.admin_email_notification')
#10370 report it
Nabi at 2012/10/23 10:31am
Set a view

@prchakal, @briiC.lv and others somebody!

You can just use this for set view:

$mailer->getView('myview');

And if have a model use this:

$mailer->getView('myview', array('model'=>$model));
#9851 report it
GillesK at 2012/09/15 08:01am
Smtp login password

Hello, is it possible to put smtp server and credentials in config/main.php ?

#8967 report it
Sebastian at 2012/07/10 11:02am
EMailer->getView() stopped working

After updating from PHP 5.2 to 5.3, getView() in the EMailer-Class stopped working. I got an error message in

return call_user_func_array(array($this->_myMailer, $method), $params);

telling me, that parameter 1 needs to be a valid callback and there is no function "renderPartial" in EMailer class. After further investigation, I found that the error comes from invoking $mailer->getView(), the else-part which will be applied when the class is called without a Yii CController (e.g. from a cron job or console application). If any of you need it, here is the else part, where I only changed the $body- and the second return-statement.

else {
            $body = CController::renderInternal(Yii::getPathOfAlias($this->pathViews . '.' . $view) . '.php', array_merge($vars, array('content' => $this->_myMailer)), true);
            if ($layout === null) {
                return $body;
            } else {
                return CController::renderInternal(Yii::getPathOfAlias($this->pathLayouts . '.' . $layout) . '.php', array('content' => $body), true);
            }
        }
#8096 report it
somethingkindawierd at 2012/05/09 05:07pm
HTML Email

Just a note for anyone trying to send an html email, I had to call this method to get html to render correctly:

Yii::app()->mailer->IsHTML(true);
#7510 report it
jacksmirk at 2012/03/27 04:43am
RE:In the controller

It depends on what you are trying to achieve. For example, if you want to send an email when a client creates an order in your store you'd have to put your code in the actionCreate() of the OrderController class.

#7509 report it
kathy at 2012/03/27 02:39am
In the controller

Where should I put the code "in the controller"? Thank you. :)

Leave a comment

Please to leave your comment.

Create extension