Будем использовать это расширение: https://github.com/vernes/YiiMailer

Расширение YiiMailer основано на библиотеке PHPMailer, а также доработана для Yii следующими функциями:

  • Поддержка макетов
  • Возможность работы с представлениями Yii
  • Поддержка перевод (мультиязычность)
  • Возможность отправлять сообщения из веб-приложения и консоли
  • Возможность отправлять HTML сообщения с вложенными изображениями
  • Поддержка режима тестирования для сохранения сообщений электронной почты вместо отправки

Установка расширения YiiMailer в Yii

Для начала необходимо скачать расширение github или с сайта.

Скопировать содержимое архива (папка YiiMailer) в папку protected/extensions

Добавьте файл настроек, /protected/config/mail.php:

<?php

return array(
    'viewPath' => 'application.views.mail', //путь к папке с представлениями view
    'layoutPath' => 'application.views.layouts', //путь к папке с макетами layouts
    
    //путь к папке с изображениями (для отправки из консоли)
    'baseDirPath' => 'webroot.images.mail',

    'savePath' => 'webroot.assets.mail', //путь к папке для сохранения писем (тестовый режим)
    'testMode' => false, //тестовый режим
    'layout' => 'mail', //основной макет (layout)
    'CharSet' => 'UTF-8', //кодировка

    //текст для тех у кого не включено отображение писем содержащих HTML
    'AltBody' => Yii::t('YiiMailer', 'You need an HTML capable viewer to read this message.'),

    //языковые настройки ошибок и прочего
    'language' => array(
        'authenticate' => Yii::t('YiiMailer', 'SMTP Error: Could not authenticate.'),
        'connect_host' => Yii::t('YiiMailer', 'SMTP Error: Could not connect to SMTP host.'),
        'data_not_accepted' => Yii::t('YiiMailer', 'SMTP Error: Data not accepted.'),
        'empty_message' => Yii::t('YiiMailer', 'Message body empty'),
        'encoding' => Yii::t('YiiMailer', 'Unknown encoding: '),
        'execute' => Yii::t('YiiMailer', 'Could not execute: '),
        'file_access' => Yii::t('YiiMailer', 'Could not access file: '),
        'file_open' => Yii::t('YiiMailer', 'File Error: Could not open file: '),
        'from_failed' => Yii::t('YiiMailer', 'The following From address failed: '),
        'instantiate' => Yii::t('YiiMailer', 'Could not instantiate mail function.'),
        'invalid_address' => Yii::t('YiiMailer', 'Invalid address'),
        'mailer_not_supported' => Yii::t('YiiMailer', ' mailer is not supported.'),
        'provide_address' => Yii::t('YiiMailer', 'You must provide at least one recipient email address.'),
        'recipients_failed' => Yii::t('YiiMailer', 'SMTP Error: The following recipients failed: '),
        'signing' => Yii::t('YiiMailer', 'Signing Error: '),
        'smtp_connect_failed' => Yii::t('YiiMailer', 'SMTP Connect() failed.'),
        'smtp_error' => Yii::t('YiiMailer', 'SMTP server error: '),
        'variable_set' => Yii::t('YiiMailer', 'Cannot set or reset variable: ')
    ),
);

Минимальная настройка для корректной отправки писем.

Откройте основной файл конфигураций и добавьте расширение в элемент массива import /protected/config/config.php (строка 11):

<?php
return array(

    'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',

    //...

    'import'=>array(
        'application.models.*',
        'application.components.*',
        'ext.YiiMailer.YiiMailer',
    ),
);
Далее необходимо добавить файл с HTML макетом письма, путь к нему содержит элемент массива настроек layoutPath (файл: /protected/config/mail.php, строка 5), по умолчанию это путь /protected/views/layouts/mail.php. Если вы используете свою тему, то замените путь layoutPath в /protected/config/mail.php на свою тему, например: webroot.themes.myThemeName.views.templates.sendMail (/themes/myThemeName/views/templates/sendMail/mail.php). Добавим макет со следующим содержимым (/protected/views/layouts/mail.php):
<html>
<head>
   <meta content="text/html; charset=UTF-8" http-equiv="content-type">
</head>
<body>
    <?php echo $content ?>
</body>
</html>

Сам макет письма можно внедрить любой, на свой вкус, $content - передаваемое содержимое письма или view.

С минимальной настройкой закончили, можем перейти к отправке писем.

Простая отправка писем

В данном примере будет описана простая отправка писем, без SMTP.

После установки и настройки расширения YiiMailer, переходим в контроллер/экшен, который будет отправлять письмо и добавляем код для отправки в нужном месте:

$mail = new YiiMailer();
$mail->setFrom('from@example.com', 'Test User');
$mail->setTo('to@example.com');
$mail->setSubject('Тема письма');
$mail->setBody('Содержание письма');
if ($mail->send()) {
    Yii::app()->user->setFlash('contact','Письмо успешно отправлено');
} else {
    Yii::app()->user->setFlash('error','Ошибка при отправке письма: '.$mail->getError());
}

Отправка писем через SMTP

Для того чтобы отправлять письма через SMTP, достаточно добавить настройки SMTP в конец массива файла /protected/config/mail.php, пример отправки писем через gmail:

'Mailer' => 'smtp',
'Host' => 'smtp.gmail.com',
'Port' => 465,
'SMTPSecure' => 'ssl',
'SMTPAuth' => true,
'Username' => 'yourEmail@gmail.com',
'Password' => '********',

В итоге файл настроек /protected/config/mail.php примет следующий вид:

<?php

return array(
    'viewPath' => 'application.views.mail',
    'layoutPath' => 'application.views.layouts',
    'baseDirPath' => 'webroot.images.mail',
    'savePath' => 'webroot.assets.mail',
    'testMode' => false,
    'layout' => 'mail',
    'CharSet' => 'UTF-8',
    'AltBody' => Yii::t('YiiMailer', 'You need an HTML capable viewer to read this message.'),

    'language' => array(
        'authenticate' => Yii::t('YiiMailer', 'SMTP Error: Could not authenticate.'),
        'connect_host' => Yii::t('YiiMailer', 'SMTP Error: Could not connect to SMTP host.'),
        'data_not_accepted' => Yii::t('YiiMailer', 'SMTP Error: Data not accepted.'),
        'empty_message' => Yii::t('YiiMailer', 'Message body empty'),
        'encoding' => Yii::t('YiiMailer', 'Unknown encoding: '),
        'execute' => Yii::t('YiiMailer', 'Could not execute: '),
        'file_access' => Yii::t('YiiMailer', 'Could not access file: '),
        'file_open' => Yii::t('YiiMailer', 'File Error: Could not open file: '),
        'from_failed' => Yii::t('YiiMailer', 'The following From address failed: '),
        'instantiate' => Yii::t('YiiMailer', 'Could not instantiate mail function.'),
        'invalid_address' => Yii::t('YiiMailer', 'Invalid address'),
        'mailer_not_supported' => Yii::t('YiiMailer', ' mailer is not supported.'),
        'provide_address' => Yii::t('YiiMailer', 'You must provide at least one recipient email address.'),
        'recipients_failed' => Yii::t('YiiMailer', 'SMTP Error: The following recipients failed: '),
        'signing' => Yii::t('YiiMailer', 'Signing Error: '),
        'smtp_connect_failed' => Yii::t('YiiMailer', 'SMTP Connect() failed.'),
        'smtp_error' => Yii::t('YiiMailer', 'SMTP server error: '),
        'variable_set' => Yii::t('YiiMailer', 'Cannot set or reset variable: ')
    ),

    'Mailer' => 'smtp',
    'Host' => 'smtp.gmail.com',
    'Port' => 465,
    'SMTPSecure' => 'ssl',
    'SMTPAuth' => true,
    'Username' => 'yourEmail@gmail.com',
    'Password' => '********',
);

Отправка письма вызывается как и в обычном режиме:

$mail = new YiiMailer();
$mail->setFrom('from@example.com', 'Test User');
$mail->setTo('to@example.com');
$mail->setSubject('Тема письма');
$mail->setBody('Содержание письма');
if ($mail->send()) {
    Yii::app()->user->setFlash('contact','Письмо успешно отправлено');
} else {
    Yii::app()->user->setFlash('error','Ошибка при отправке письма: ' . $mail->getError());
}

Так же настроить отправку через SMTP можно перед отправкой самого сообщения, например для отправки писем с разных почтовых ящиков в зависимости от действия пользователя, делается это следующим образом:

$mail->setSmtp('smtp.gmail.com', 465, 'ssl', true, 'yourEmail@gmail.com', '********');

Подробнее:

$mail = new YiiMailer();
$mail->setSmtp('smtp.gmail.com', 465, 'ssl', true, 'yourEmail@gmail.com', '********');
$mail->setFrom('from@example.com', 'Test User');
$mail->setTo('to@example.com');
$mail->setSubject('Тема письма');
$mail->setBody('Содержание письма');
if ($mail->send()) {
    Yii::app()->user->setFlash('contact','Письмо успешно отправлено');
} else {
    Yii::app()->user->setFlash('error','Ошибка при отправке письма: ' . $mail->getError());
}

Дополнительные настройки перед отправкой письма

Задать layout

Перед отправкой письма можно установить макет (layout) отличный от того, что указан в основных настройках расширения, например в зависимости от вызванного пользователем действия (action), макет письма будет отличаться:

$mail->setLayout('layoutName');

Задать view

Так же при отправке письма можно использовать свое представление (view):

$mail->setView('viewName');
$mail->setData(
    array(
        'header' => 'Привет, это тест', 
        'body' => 'Текст тестового письма'
    )
);

Список получателей

Указывать получателей можно в массиве, пример:

$mail->setTo('test@example.com');
$mail->setTo(array('test@example.com', 'test2@example.com'));
$mail->setTo(array('test@example.com' => 'Test User', 'test2@example.com'));

Отправка писем с вложением

Для отправки писем с вложением используется метод setAttachment(), который принимает имя файла или массив из файлов для вложения:

$mail->setAttachment('/path/to/file.pdf');
$mail->setAttachment(array('/path/to/file.pdf', '/file2.doc'));
$mail->setAttachment(array('/path/to/file.pdf' => 'Good file', '/file2.doc' => 'Good doc file'));

Тестовый режим

Для проверки содержимого письма можно включить тестовый режим, в основном файл настроек /protected/config/mail.php нужно включить testMode и указать папку для сохранения писем:

'savePath' => 'webroot.assets.mail',
'testMode' => true,

Подробный пример отправки писем через (SMTP)

Контроллер (Controller):

$mail = new YiiMailer();
//Если настройки не заданы в файле 
$mail->setSmtp('smtp.gmail.com', 465, 'ssl', true, 'yourEmail@gmail.com', '********');
$mail->setLayout('layoutName');
$mail->setView('viewName');
$mail->setSubject('Тема письма');
$mail->setData(
    array(
        'header' => 'Привет, это тест', 
        'body' => '<p>Текст <b>тестового</b> письма!</p>'
    )
);
$mail->setAttachment(array('/path/to/file.pdf'=>'Good file'));
$mail->setFrom('from@example.com', 'Test User');
$mail->setTo(array('test@example.com', 'test2@example.com'));
if ($mail->send()) {
    Yii::app()->user->setFlash('contact','Письмо успешно отправлено');
} else {
    Yii::app()->user->setFlash('error','Ошибка при отправке письма: ' . $mail->getError());
}

Макет (Layout) (/protected/views/layouts/layoutName.php):

<html>
<head>
   <meta content="text/html; charset=UTF-8" http-equiv="content-type">
</head>
<body>
    <?php echo $content ?>
</body>
</html>

Представление (View) (/protected/views/mail/viewName.php):

<h1><?= $header; ?></h1>
<?= $body ; ?>
<small>Подпись ;)</small>

Готово, приятной работы...