Để giúp ứng dụng hay website tiếp cận đến gần hơn với người dùng thì việc gửi mail thông báo hay chạy một chiến dịch nào đó là điều không thể thiếu. Yii2 đã hỗ trợ soạn thảo và gửi email thông qua một tiện ích mở rộng được cài đặt sẵn là yii2-swiftmailer.
Cấu hình gửi mail
Để cấu hinh gửi mail chung cho cả backend hay frontend trong yii2 advanced thì các đồng dev cần điều chỉnh các thông số sau trong common/config/main-local.php
return [
//....
'components' => [
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'encryption' => 'tls',
'host' => 'your_mail_server_host',
'port' => 'your_smtp_port',
'username' => 'your_username',
'password' => 'your_password',
],
],
],
];
Ở đây tại hạ ví dụ sẽ gửi mail thông qua host của google sẽ cấu hình như sau
return [
//....
'components' => [
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'viewPath' => '@common/mail',
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'encryption' => 'tls',
'host' => 'smtp.gmail.com',
'port' => '587',
'username' => '[email protected]',
'password' => 'mật khẩu của emai anh em đã tạo',
],
],
],
];
Gửi mail
Sau khi đã cấu hình xong, tại hạ sẽ tạo 1 action sendMail trong SiteController với nội dung như sau
<?php
namespace frontend\controllers;
use Yii;
use yii\base\InvalidArgumentException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
/**
* Site controller
*/
class SiteController extends Controller
{
//...............
public function actionSendmail(){
Yii::$app->mailer->compose() // Sử dụng nếu có template
->setFrom('[email protected]') // Mail sẽ gửi đi
->setTo('[email protected]') // Mail sẽ nhận
->setSubject('Demo gửi mail trong Yii2') // tiêu đề mail
->setHtmlBody('<b>Nội dung gửi mail trong Yii2</b>') // Nội dung mail dạng Html nếu không muốn dùng html thì có thể thay thế bằng setTextBody('Nội dung gửi mail trong Yii2') để chỉ hiển thị text
->send();
}
}
Lưu ý* : Các đồng dev nếu sử dụng gmail thì cần phải mở các chế độ bảo mật để có thể truy cập email trong quá trình gửi. Anh em đồng dev truy cập vào https://www.google.com/settings/security/lesssecureapps và https://accounts.google.com/b/0/UnlockCaptcha để tắt hết bảo mật đi nhé =)) thì mới dùng để test gửi mail được.
Sau đó các đồng dev chạy Url http://localhost/advanced/site/sendmail trên trình duyệt và kiểm tra hòm thư xem nhận được thư không nhé. Ở đây tai hạ đã nhận được email trong hòm thư [email protected]
OK, đó là gửi 1 mail đơn lẻ, nếu các đồng dev gửi nhiều mail 1 lúc thì đổi lại code như sau
Ví dụ ở đây tại hạ muốn gửi cho 2 email là [email protected] và v[email protected]
<?php
namespace frontend\controllers;
use Yii;
use yii\base\InvalidArgumentException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
/**
* Site controller
*/
class SiteController extends Controller
{
//...............
public function actionSendmail(){
$messages = [];
$users = [
'[email protected]',
'[email protected]'
];
foreach ($users as $user) {
$messages[] = Yii::$app->mailer->compose()
->setFrom('[email protected]')
->setTo($user)
->setSubject('Demo gửi multi mail trong Yii2')
->setHtmlBody('<b>Nội dung gửi multi mail trong Yii2</b>');
}
Yii::$app->mailer->sendMultiple($messages);
}
}
Và kết quả là
Gửi mail với mẫu có sẵn
Để tiện cho việc không phải thay đổi nội dung mỗi khi gửi một chiến dịch mail nào đó thì Yii2 đã cung cấp cho các đồng dev xây dựng các template email thông qua thư mục mail trong common. Ví dụ ở đây tại hạ sẽ tạo 1 template là register để thông báo đăng ký tài khoản thành công như sau
Trong thư mục mail, tại hạ tạo 1 file là register.php như sau
Tiếp đó tại hạ sửa lại action Sendmail
<?php
namespace frontend\controllers;
use Yii;
use yii\base\InvalidArgumentException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
/**
* Site controller
*/
class SiteController extends Controller
{
//...............
public function actionSendmail(){
Yii::$app->mailer->compose('register',['name' => 'Voi xanh']) // giống như render view từ controller, tham số đầu là view/template, tham số thứ 2 là data được truyền ra view để hiển thị
->setFrom('[email protected]')
->setTo('[email protected]')
->setSubject('Đăng ký tài khoản thành công')
->send();
}
}
Và kết quả có được
Ngoài ra, các đồng dev có thể tùy chỉnh kiểu muốn gửi dạng text hoặc html cho template có sẵn như sau
Yii::$app->mailer->compose([
'html' => 'contact-html', // là file contact-html.php trong common/mail
'text' => 'contact-text', // là file contact-text.php trong common/mail
]);
Gửi mail với file đính kèm
Để gửi mail với file đính kèm các đồng dev sử dụng đoạn mã sau
$message = Yii::$app->mailer->compose();
// attach file from local file system
$message->attach('/path/to/source/file.pdf');
// create attachment on-the-fly
$message->attachContent('Attachment content', ['fileName' => 'attach.txt', 'contentType' => 'text/plain']);
Ví dụ ở đây tại hạ có 1 file là voixanh.doc đặt ở ngoài cùng của thư mục dự án
Trong phần actionSendmail tại hạ đổi lại như sau
public function actionSendmail(){
Yii::$app->mailer->compose()
->setFrom('[email protected]')
->setTo('[email protected]')
->setSubject('Đăng ký tài khoản thành công')
->attach(dirname(dirname(__DIR__)).'/voixanh.docx') // dirname(dirname(__DIR__)) -> /var/www/html/advanced
->attachContent('Attachment content', ['fileName' => 'voixanh.docx', 'contentType' => 'text/plain'])
->send();
}
và kết quả nhận được
Tổng kết
Trên đây tại hạ đã giới thiệu cho các đồng dev các gửi mail trong Yii2 như thế nào, trong các bài biết sắp tới tại hạ sẽ demo thêm về việc sử dụng các service mail bên thứ 3 khác như SES AWS, Mail Gun, Sendgrid .... để anh em đồng dev được tiếp cận thêm. Mặc dù việc gửi mail được là 1 chuyện nhưng làm thế nào để giảm tải cho server khi có nhiều email cần phải được gửi thì lại là chuyện khác. Tại hạ sẽ đề cập tới việc sử dụng các Queue Service để nhận và phân phối các mail tới đích để giảm tải cho server ở bài tiếp sau nhé. Bài viết còn nhiều thiếu sót mong anh em đồng dev thông cảm. Cảm ơn đã ghé đọc!