Расширение Yii для отправки email

Выкладываем свои наработки
Ответить
kraut
Сообщения: 27
Зарегистрирован: 2013.07.11, 09:03
Откуда: Москва

Расширение Yii для отправки email

Сообщение kraut »

Описание:
Для Yii существует несколько расширений для отправки почты. Основные ( http://www.yiiframework.com/extension/mail/, http://www.yiiframework.com/extension/mailer/ ) представляют собой обертки для отправки через популярные библиотеки Swift и Php-mailer. Предлагаемое еще одно расширение отличается архитектурным решением. Письмо описывается объектом, проходящим через одно или несколько поведений yii behaviors. Сами поведения конфигурируются в yii конфиге. В расширение входят несколько заготовок: для Swift Mailer и PhpMailer, для записи отправляемых писем в файлы; для сохранения в памяти (для тестирования). В случае необходимости легко расширить или написать свое специфическое поведение. Интерфейсы расширения разработаны из предположения, что для описания отправляемых с сайта писем, удобно использовать шаблоны, наподобие стандартных Yii представлений. А такие свойства писем как тема, layout письма, вложения и другие свойства удобно описывать прямо в шаблоне.

Ссылки:
https://github.com/kraut-dps/dpsMailer/
http://www.yiiframework.com/extension/dpsmailer

Установка:
Для работы расширения достаточно скопировать папку dpsmailer в папку проекта protected/extensions.

Варианты использования:

Отправка письма:

Код: Выделить всё

Yii::app()->dpsMailer->sendByView(
    array( 'to@example.com' => 'получатель' ), // определяем кому отправляется письмо
    'emailTpl', // view шаблона письма
    array(
        'sUsername' => 'Участник',
        'sLogoPicPath' => '/path/to/logo.gif',
        'sFilePath' => '/path/to/attachment.txt',
    )
);
 
Шаблон письма /path/to/protected/views/mail/emailTpl.php:

Код: Выделить всё

<? /** @var dpsEmailController $this */
$this->setSubject( 'Тема письма' ); // указываем тему
$this->setLayout( 'emailLayoutTpl' ); // какой макет
$this->attach( $sFilePath ); // приложим файлик
?>
Привет <?= $sUsername ?>!

Макет письма /path/to/protected/views/mail/emailLayoutTpl.php:

Код: Выделить всё

<? /** @var dpsEmailController $this */ ?>
<img src="<?= $this->embed( $sLogoPicPath ) ?>"/>

<?= $content ?>
Пример настройки:

Код: Выделить всё

...
‘components’ =>
    ...,
'dpsMailer' => array(
        'class' => 'ext.dpsMailer.components.dpsMailer',
        'sViewPath' => '/path/to/protected/views/mail', // путь к шаблонам
        'aFrom' => array( 'no-reply@example.com' => 'Администрация' ), // от кого будут отправляться письма по умолчанию
        'aBehaviors' => array(
            'swift' => array(
                'class' => 'ext.dpsMailer.behaviors.dpsSwiftMailerBehavior',
                'sLibPath'=> '/path/to/lib/swift/Swift-5.0.0/lib', // путь к папке, c библиотекой swift http://swiftmailer.org/
                'sTransport' => 'Swift_SmtpTransport',
                'aOptions' => array(// настройки swift
                    'Host'            => 'smtp.gmail.com',
                    'Port'            => 465,
                    'Encryption'        => 'ssl',
                    'Username'        => '[username]',
                    'Password'        => '[password]',
                ),
            ),
        ),
),
...
 

PhpMailer Gmail:

Код: Выделить всё

...
'aBehaviors' => array(
    'phpMailer' => array(
        'class' => 'ext.dpsMailer.behaviors.dpsPhpMailerBehavior',
        'sLibPath'=> Yii::getPathOfAlias( 'application.xlib' ) . '/php-mailer.5.2.1',
        'aOptions' => array( // настройки php-mailer
            'Mailer'        => 'smtp',
            'Host'            => 'smtp.gmail.com',
            'CharSet'        => 'utf-8',
            'SMTPAuth'        => true,
            'SMTPSecure'        => 'ssl',
            'Port'            => 465,
            'Username'        => '[username]',
            'Password'        => '[password]',
        ),
    ),
),
...

Сохранение отправляемых писем в файл:

Код: Выделить всё

...
'aBehaviors' => array(
    'file' => array(
        'class' => 'ext.dpsMailer.behaviors.dpsFileMailerBehavior',
        'sDir' =>Yii::getPathOfAlias( 'application.runtime' ) . '/emails', // директория для eml писем
    ),
),
...

Сохранение отправляемых писем в памяти, для проверок в тестах:

Код: Выделить всё

...
'aBehaviors' => array(
    'memory' => array(
        'class' => 'ext.dpsMailer.behaviors.dpsMemoryMailerBehavior',
    ),
),
...

Получение последнего отправленного письма из тестов:

Код: Выделить всё

$oEmailEvent = Yii::app()->dpsMailer->getBehavior( 'memory' )->getLastEmail( 'to@example.com' );
Или последних отправленных писем:

Код: Выделить всё

$oEmailEvent = Yii::app()->dpsMailer->getBehavior( 'memory' )->getLastEmails();
Для функциональных тестов ( когда выполнение тестов и сами тесты это разные php процессы ) предназначено отдельное поведение:

Код: Выделить всё

...
'aBehaviors' => array(
    'cache' => array(
        'class' => 'ext.dpsMailer.behaviors.dpsCacheMailerBehavior',
    ),
),
... 
C помощью него последние отправленные письма можно сохранять в memcache.


Кейс динамического добавления поведения ( например для странички тестирования шаблонов в администраторской панели ):

Код: Выделить всё

// выключаем все поведения
Yii::app()->dpsMailer->setSendersEnable( array() );

// динамически добавляем поведение сохранения писем в памяти
Yii::app()->dpsMailer->attachBehavior( array(
    'preview' => array(
        'class' => 'ext.dpsMailer.behaviors.dpsMemoryMailerBehavior'
    ),
) );

// отправка тестового письма
...

// получаем объект с данными письма
$oEmailEvent = Yii::app()->dpsMailer->getBehavior( 'preview' )->getLastEmail(); 

Балансировка между отправщиками:

Код: Выделить всё

'components' => array(
        …,
        'dpsMailer' => array(
                …,
                'aBehaviors' => array(
                        'mailer1' =>  …,
                        'mailer2' =>  …,
                        'mailer3' =>  …,
                ),
                'cBalance' =>function( $aSenders, dpsEmailEvent $oEmailEvent ) {
                        // распределяем нагрузку ( располагая тут информацией о загрузке
                        // отправщиков, можно сделать полноценный балансировщик )
                        $iNum = mt_rand( 1, 3 );
                        $aSenders[ 'mailer1' ] = $iNum == 1;
                        $aSenders[ 'mailer2' ] = $iNum == 2;
                        $aSenders[ 'mailer3' ] = $iNum == 3;
                        return $aSenders;
                },
        ),
        …,
), 
Возможность отправлять письма из CConsoleApplication:

Код: Выделить всё

console.php:
return array(
        …
        'behaviors' => array( 'ext.dpsMailer.components.dpsRenderConsoleBehavior' ),
        'components' => array(
                …,
        ),
        …
);
 
Отправка письма с дополнительными параметрами:

Код: Выделить всё

// специальный объект для передачи дополнительных параметров
$oForceEmailEvent = new dpsEmailEvent();
$oForceEmailEvent->aCc = array( 'cc@example.com' => '' );

Yii::app()->dpsMailer->sendByView(
    array( 'to@example.com' => 'получатель' ), // определяем кому отправляется письмо
    'emailTpl', // ник шаблона письма
    array( 'sUsername' => 'Участник' ), // параметры для вставки в шаблон
    $oForceEmailEvent // объект с дополнительными параметрами
); 
Растишка
Сообщения: 2
Зарегистрирован: 2014.10.26, 11:40

Re: Расширение Yii для отправки email

Сообщение Растишка »

Весь измучился! Как в контроллере при отправке письма sendByView изменить установленные по-умолчанию 'aFrom' и 'aOptions', чтобы письмо уходило с другого ящика
Растишка
Сообщения: 2
Зарегистрирован: 2014.10.26, 11:40

Re: Расширение Yii для отправки email

Сообщение Растишка »

Для тех, кто ломает голову и не знает как поступить для переключения ящика для отправки письма:

В main.php конфига оставляем:

Код: Выделить всё

 'dpsMailer' => array('class' => 'ext.dpsmailer.components.dpsMailer')
В контроллере перед вызовом sendByView:

Код: Выделить всё

Yii::app()->dpsMailer->aFrom=array("$mail" => $title); //адрес => текст от кого
Yii::app()->dpsMailer->sViewPath = "protected/views/mail/"; // путь к шаблонам

//присваивам необходимые логин-пароль

$username='username';
$password=123456789;
$host=smtp.domain.ru;


Yii::app()->dpsMailer->attachBehavior("swift",array(
                                            'class' => 'ext.dpsmailer.behaviors.dpsSwiftMailerBehavior',
                                            'sLibPath'=> '/swift/lib',
                                            'sTransport' => 'Swift_SmtpTransport',
                                            'aOptions' => array(
                                                'Host'          => $host,
                                                'Port'          => 465,
                                                'Encryption'    => 'ssl',
                                                'Username'      => $username,
                                                'Password'      => '$password',
                                            )));

Yii::app()->dpsMailer->sendByView(
                            array( "example@mail.com" => "Получатель"), 
                            "шаблон письма", );
вот смотрю и не понимаю, почему сразу не получалось?
Ответить