= Yii 2 Email Tools = == Setup Emailer (Swiftmailer) == Setup mailer in ''app/config/main.php'' (or ''main-local.php''). * Basic application: * ''app/config/web.php'' * ''app/config/console.php'' * Advanced application: * ''common/config/main.php''. * NOTE: you can also find settings in: * ''environments/prod/common/config/main-local.php'' * ''environments/dev/common/config/main-local.php'' return [ 'components' => [ ... 'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', // Directory that contains the view files // for composing mail messages. Defaults to '@app/mail' 'viewPath' => '@common/mail', // Send all mail messages to a file by default. // The messages get stored locally under '@app/runtime/mail' 'useFileTransport' => true, //'fileTransportPath' => '@runtime/mail', // Send all mail messages as real emails. // Set 'useFileTransport' to false, // and configure a transport for the mailer. // 'useFileTransport' => false, //'transport' => [ // 'class' => 'Swift_SmtpTransport', // 'host' => 'localhost', // 'username' => 'username', // 'password' => 'password', // 'port' => '587', // 'encryption' => 'tls', //], ], ], ]; To send an email directly from a controller (no form/view): public function sendMessage($srcMail, $srcName, $dstEmail, $subject, $textBody) { $success = Yii::$app->mailer->compose() ->setFrom([$srcMail => $srcName]) ->setTo($dstEmail) ->setSubject($subject) ->setTextBody($textBody) ->send(); return $success; } To send an email with a form (view), you may use the following code in a controller. Eg: controller ''@app/controllers/SiteController'': class SiteController extends \yii\web\Controller { /** * @inheritdoc */ public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'rules' => [ //... [ // any user (authenticated or not) 'actions' => ['contact', 'captcha', ...], 'allow' => true, ], ], ], ]; } //... private function sendMessage($srcMail, $srcName, $dstEmail, $subject, $textBody) { $success = Yii::$app->mailer->compose('contact/html' /* view */, ['contactForm' => $form] /* view params */) ->setFrom('from@domain.com') ->setTo($form->email) ->setSubject($form->subject) ->send(); return $success; } View ''@app/views/site/contact'': title = 'Contact'; $this->params['breadcrumbs'][] = $this->title; ?>

title) ?>

session->hasFlash('contactFormSubmitted')): ?>
Thank you for contacting us. We will respond to you as soon as possible.

Note that if you turn on the Yii debugger, you should be able to view the mail message on the mail panel of the debugger. mailer->useFileTransport): ?> Because the application is in development mode, the email is not sent but saved as a file under mailer->fileTransportPath) ?>. Please configure the useFileTransport property of the mail application component to be false to enable email sending.

If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.

'contact-form']); ?> field($model, 'name') ?> field($model, 'email') ?> field($model, 'subject') ?> field($model, 'body')->textArea(['rows' => 6]) ?> context->createAction('captcha')->getVerifyCode(true); ?> field($model, 'verifyCode')->widget(Captcha::className(), [ 'template' => '
{image}
{input}
', ]) ?>
'btn btn-primary', 'name' => 'contact-button']) ?>
See also: * [[http://www.yiiframework.com/doc-2.0/guide-tutorial-mailing.html|Yii 2 Guide: Mailing]] * [[http://swiftmailer.org]] == Email Model == Create model ''@app/models/Email'': 'Verification Code', ]; } /** * Sends an email to the specified email address using the information collected by this model. * @param string $dstEmail - the target email address * @return boolean whether the model passes validation */ public function sendMessage($dstEmail) { if ($this->validate()) { Yii::$app->mailer->compose() ->setTo($dstEmail) ->setFrom([$this->email => $this->name]) ->setSubject($this->subject) ->setTextBody($this->body) ->send(); return true; } else { return false; } } } == Console Email == Create a console action to email: stdout("\n"); $this->stdout("Dest Email: " . $dstEmail . "\n", Console::BOLD); $this->stdout("Work Order: " . $workOrderId . "\n", Console::BOLD); $this->stdout("\n"); if (($workOrder = WorkOrder::findOne($workOrderId)) !== null) { $workOrderID = str_pad($workOrder->id, 6, "0", STR_PAD_LEFT); // Setup email data $model = new Email(); $model->name = Yii::$app->params['companyNameShort']; $model->email = Yii::$app->params['adminEmail']; $model->subject = "Work Order [{$workOrderID}]: {$workOrder->task->name}"; $model->body = "There is a new work order: \n" . "------------------------------------------------------------------\n" . "Work Order [{$workOrderID}]: {$workOrder->task->name}\n" . "Date: " . date("M-d-Y", strtotime($workOrder->date)) . "\n" . "Location: {$workOrder->property->name}\n" . "------------------------------------------------------------------\n\n" . "Details: \n{$workOrder->notes}\n"; //$model->verifyCode; $data['name'] = Yii::$app->params['companyNameShort']; $data['email'] = Yii::$app->params['adminEmail']; $data['subject'] = "Work Order [{$workOrderID}]: {$workOrder->task->name}"; $data['body'] = "There is a new work order: \n" . "Work Order [{$workOrderID}]: {$workOrder->task->name}\n" . "Date: " . date("M-d-Y", strtotime($workOrder->date)) . "\n" . "Location: {$workOrder->property->name}\n" . "Details: \n{$workOrder->notes}\n"; //$data['verifyCode'] = ''; // Send email //if ($model->load($data) && $model->sendMessage($dstEmail)) { //if ($model->load($data)) { if ($model->sendMessage($dstEmail)) { $this->stdout("--------------------------------------\n", Console::BOLD); $this->stdout("Email Notification Sent\n", Console::BOLD); $this->stdout("--------------------------------------\n", Console::BOLD); $this->stdout("Subject: " . $data['subject'] . "\n", Console::BOLD); $this->stdout("Message:\n" . $data['body'] . "\n", Console::BOLD); $this->stdout("--------------------------------------\n", Console::BOLD); $this->stdout("Mailer: ".print_r(Yii::$app->mailer, true)."\n", Console::BOLD); $this->stdout("--------------------------------------\n", Console::BOLD); return Controller::EXIT_CODE_NORMAL; } else { $this->stdout("Email Notification NOT Sent\n - Unable to post data for: Work Order ID " . $workOrderId . "\n", Console::BOLD); return Controller::EXIT_CODE_ERROR; } /*} else { //return $this->render('contact', [ // 'model' => $model, //]); //return $this->goHome(); // nothing to render $this->stdout("Email Notification NOT Sent\nUnable to load data:\n" . $data['subject'] . "\n" . $data['body'] . "\n", Console::BOLD); return Controller::EXIT_CODE_NORMAL; // nothing to render }*/ } else { $this->stdout("Email Notification NOT Sent\n - Work Order ID " . $workOrderId . " not found\n", Console::BOLD); return Controller::EXIT_CODE_ERROR; } } } === Running Console Action From CLI === Call console action from command line: $ yii email-notification/send-email dstEmail=info@acme.com workOrderId=1 === Running Console Action From View === Call console action from web view: ''@app/views/WorkOrder/view'' ... $model->id], ['class' => 'btn btn-primary'] ) ?> ... Flash Alert Zone
session->hasFlash('success')): ?> session->hasFlash('error')): ?>
''@app/controllers/WorkOrderController'' actionSendEmail(Yii::$app->params['taskAssigneeEmail'], $id); // $dstEmail, $workOrderId Yii::$app->session->setFlash('success', "Sent Email"); return $this->redirect(['view', 'id' => $id]); } } == Send PDF Attachment Through Email == Assuming you have created a PDF document using TCPDF, you can attach it to an email message as follows: function sendEmail($model, $pdf, $filename) { // Setup email content $emailSubj = "Report by Email"; $emailBody = "Hi {$model->customer->contact}, \n\n"; $emailBody .= "Please see the included attachment.\n\n"; $emailBody .= "Sales Team"; // Attach PDF document as MIME multipart $attachment = $pdf->Output("{$filename}", 'S'); // document as a string // Create and send email message Yii::$app->mailer->compose() ->setFrom([Yii::$app->params['adminEmail'] => Yii::$app->params['companyName']]) ->setTo($model->customer->email) ->setBcc([ //Yii::$app->params['adminEmail'] => Yii::$app->params['companyNameShort'] . ' Support', Yii::$app->params['debugEmail'] => 'Debug Email' ]) ->setSubject($emailSubj) ->setTextBody($emailBody) ->attachContent($attachment, ['fileName' => $filename, 'contentType' => 'application/pdf']) ->send(); } == Setup Captcha == ''CaptchaAction'' requires either GD2 extension or ImageMagick PHP extension. Check that it meets this requirement. In controller's function ''behaviors()'', add ''captcha'' to ''actions'' for user group that requires the use ot if: /** * Site controller */ class SiteController extends Controller { //... /* * @inheritdoc */ public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'rules' => [ //... [ // any user (authenticated or not) 'actions' => ['contact-us', 'captcha', ...], 'allow' => true, ], ], ], //... ]; } //... } In controller, add ''CaptchaAction'' to ''actions()'': /** * Site controller */ class SiteController extends Controller { //... /** * @inheritdoc */ public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ], 'captcha' => [ 'class' => 'yii\captcha\CaptchaAction', 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, 'testLimit' => 1, 'foreColor' => 0xA02040, ], ]; } //... } In model using the captcha, add ''verifyCode'' entry to the ''rules()'' function: /** * ContactForm is the model behind the contact form. */ class ContactForm extends Model { public $name; public $email; public $subject; public $body; public $verifyCode; /** * @return array the validation rules. */ public function rules() { return [ // name, email, subject and body are required [['name', 'email', 'subject', 'body'], 'required'], // email has to be a valid email address ['email', 'email'], // verifyCode needs to be entered correctly ['verifyCode', 'captcha', 'captchaAction' => 'site/captcha'], ]; } //... } In form view using the captcha, add ''verifyCode'' field: context->createAction('captcha')->getVerifyCode(true); ?> field($model, 'verifyCode')->widget(Captcha::className(), [ 'captchaAction' => 'site/captcha', // redirect to correct controller where captcha is defined 'template' => '
{image}
{input}
', ]) ?>
See more: * [[https://www.yiiframework.com/doc/api/2.0/yii-captcha-captchaaction|Yii CaptchaAction]]