根据用户输入更新 swiftmailer 配置

Update swiftmailer configuration based on user input

我需要根据用户输入更新 SwiftMailer 配置,特别是用户可能决定使用 SMTP 协议发送电子邮件或将它们存储在本地(在特定文件系统的文件夹中)。用户将使用视图来决定选项,然后控制器捕获决定并更新会话变量。当前的方法是从 config/web.php 读取该会话变量,然后选择适当的配置。

我不确定 web.php 在应用程序执行期间是否只加载了一次,事实上我无法检查会话是否处于活动状态,然后从 var 中获取信息。我不确定哪种方法可能是合适的。

这是我的 config/web.php:

<?php
use yii\web\Session;

$params = require __DIR__ . '/params.php';
$db = require __DIR__ . '/db.php';
$session = Yii::$app->session;
if($session->isActive){
    $mailTransport = Yii::app()->session->get('emailtransport');    
}
else{ //session is not started
    $mailTransport = 'local';
}

if($mailTransport=='local'){
    $config = [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'aliases' => [
        '@bower' => '@vendor/bower-asset',
        '@npm'   => '@vendor/npm-asset',
    ],
    'components' => [
        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'a4ARdWYauHJ-UEAvVfagzk0LTyT_KEuZ',
        ],
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
        ],
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
            'viewPath' => '@app/mail',
            'htmlLayout' => 'layouts/main-html', //template to Send Emails Html based
            'textLayout' => 'layouts/main-text', //template to Send Emails text based
            'messageConfig' => [
               'charset' => 'UTF-8',
               'from' => ['clients@ok.com' => 'OK Premiun Clients'],
             ], //end of messageConfig
            // send all mails to a file by default. You have to set
            // 'useFileTransport' to false and configure a transport
            // for the mailer to send real emails.
            'useFileTransport' => true,
            //'useFileTransport' => false,
            'transport' => [
            'class' => 'Swift_SmtpTransport',
            'host' => 'smtp.gmail.com',
            'username' => 'ok@gmail.com',
            'password' => "password",
            'port' => '465',
            'encryption' => 'ssl',
          ],
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'db' => $db,
        /*
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
            ],
        ],
        */
    ],
    'params' => $params,
];
}//end of if loop
else{
    $config = [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'aliases' => [
        '@bower' => '@vendor/bower-asset',
        '@npm'   => '@vendor/npm-asset',
    ],
    'components' => [
        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'a4ARdWYauHJ-UEAvVfagzk0LTyT_KEuZ',
        ],
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
        ],
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
            'viewPath' => '@app/mail',
            'htmlLayout' => 'layouts/main-html', //template to Send Emails Html based
            'textLayout' => 'layouts/main-text', //template to Send Emails text based
            'messageConfig' => [
               'charset' => 'UTF-8',
               'from' => ['ok@namesilo.com' => 'OK Premiun Clients'],
             ], //end of messageConfig
            // send all mails to a file by default. You have to set
            // 'useFileTransport' to false and configure a transport
            // for the mailer to send real emails.
            'useFileTransport' => false,
            'transport' => [
            'class' => 'Swift_SmtpTransport',
            'host' => 'smtp.gmail.com',
            'username' => 'ok@gmail.com',
            'password' => "password",
            'port' => '465',
            'encryption' => 'ssl',
          ],
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'db' => $db,
        /*
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
            ],
        ],
        */
    ],
    'params' => $params,
];
}//end of if else loop

因为会话从未在 web.php 到达,所以电子邮件始终存储在本地。

您要执行的操作要求您从代码中实例化 yii\swiftmailer\Mailer class 并通过调用 setTransport() 设置传输,而不是通过在配置文件中的组件。

我会给你一个例子,我将使用 smtp.gmail.com 作为传输主机并发送电子邮件

public function actionTest(){

    //instantiate the mailer
    $mailer = new \yii\swiftmailer\Mailer(
        [
            'useFileTransport' => false
        ]
    );

    //set the transport params
    $mailer->setTransport(
        [
            'class' => 'Swift_SmtpTransport',
            'host' => 'smtp.gmail.com',
            'username' => 'username',
            'password' => 'password',
            'port' => '587',
            'encryption' => 'tls'
        ]
    );

    //to email 
    $to = "someemail@gmail.com";

    //email subject
    $subject = "this is a test mail";

    //email body 
    $body ="Some body text for email";

    //send the email
    $mailer->compose()->setTo($to)->setFrom(
        [
            'support@site.com' => 'Site Support'
        ]
    )->setTextBody($body)->setSubject($subject)->send();
}

另一个解决方案是:我使用我的模型做了一些更改 Class:

    public function sendMail($transport, $view, $subject, $params = []){
      //set layout params
      \Yii::$app->mailer->getView()->params['userName'] = $this->username;

      if($transport == 'local'){
        \Yii::$app->mailer->useFileTransport=true;
      }
      else{
        \Yii::$app->mailer->useFileTransport=false;
      }
      $result = \Yii::$app->mailer->compose([
          'html' => 'views/' . $view . '-html',
          'text' => 'views/' . $view . '-text',
      ], $params)->setTo([$this->email => $this->username])
          ->setSubject($subject)
          ->send();

      //reset layout params
      \Yii::$app->mailer->getView()->params['userName'] = null;
      return $result;
    } //end of sendMail

它帮助我简化了 web.php,没有必要使用会话变量。