* Date: 2018-4-3
*/
namespace app\common\logic;
use think\Db;
/**
* Description of SmsLogic
*
* 邮件类
*/
class EmailLogic
{
private $config;
private $home_lang;
public function __construct($smtp_config = [])
{
$this->config = !empty($smtp_config) ? $smtp_config : tpCache('smtp');
$this->home_lang = get_home_lang();
}
/**
* 置换邮件模版内容
* @param intval $scene 应用场景
*/
private function replaceContent($scene = '', $params = '')
{
if (0 == intval($scene)) {
$msg = $params;
} else {
$params_arr = [];
$emailTemp = Db::name('smtp_tpl')->where([
'send_scene'=> $scene,
'lang' => $this->home_lang,
])->find();
if (!empty($emailTemp)) {
$msg = $emailTemp['tpl_content'];
preg_match_all('/\${([^\}]+)}/i', $msg, $matchs);
if (!empty($matchs[1])) {
foreach ($matchs[1] as $key => $val) {
if (is_array($params)) {
$params_arr[$val] = $params[$val];
} else {
$params_arr[$val] = $params;
}
}
}
//置换邮件模版内容
foreach ($params_arr as $k => $v) {
$msg = str_replace('${' . $k . '}', $v, $msg);
}
} else {
return '';
}
}
return $msg;
}
/**
* 邮件发送
* @param $to 接收人
* @param string $subject 邮件标题
* @param string|array $data 邮件内容(html模板渲染后的内容)
* @param string $scene 使用场景
* @throws Exception
*/
public function send_email($to='', $subject='', $data='', $scene=1, $library = 'phpmailer'){
if (0 < intval($scene)) {
$smtp_tpl_row = Db::name('smtp_tpl')->where([
'send_scene'=> $scene,
'lang' => $this->home_lang,
])->find();
if (empty($smtp_tpl_row)) {
return ['code'=>0,'msg'=>'找不到相关邮件模板!'];
} else if (empty($smtp_tpl_row['is_open'])) {
return ['code'=>0,'msg'=>'该功能待开放,请先启用邮件模板('.$smtp_tpl_row['tpl_name'].')'];
} else {
empty($subject) && $subject = $smtp_tpl_row['tpl_title'];
}
}
switch ($library) {
case 'phpmailer':
return $this->send_phpmailer($to, $subject, $data, $scene);
break;
case 'swiftmailer':
return $this->send_swiftmailer($to, $subject, $data, $scene);
break;
default:
return $this->send_phpmailer($to, $subject, $data, $scene);
break;
}
}
/**
* 邮件发送 - swiftmailer第三方库
* @param $to 接收人
* @param string $subject 邮件标题
* @param string|array $data 邮件内容(html模板渲染后的内容)
* @param string $scene 使用场景
* @throws Exception
*/
private function send_swiftmailer($to='', $subject='', $data='', $scene=1){
vendor('swiftmailer.lib.swift_required');
// require_once 'vendor/swiftmailer/lib/swift_required.php';
try {
//判断openssl是否开启
$openssl_funcs = get_extension_funcs('openssl');
if(!$openssl_funcs){
return array('code'=>0 , 'msg'=>'请先开启php的openssl扩展');
}
//判断openssl是否开启
// $sockets_funcs = get_extension_funcs('sockets');
// if(!$sockets_funcs){
// return array('code'=>0 , 'msg'=>'请先开启php的sockets扩展');
// }
empty($to) && $to = $this->config['smtp_from_eamil'];
$to = explode(',', $to);
//smtp服务器
$host = $this->config['smtp_server'];
//端口 - likely to be 25, 465 or 587
$port = intval($this->config['smtp_port']);
//用户名
$user = $this->config['smtp_user'];
//密码
$pwd = $this->config['smtp_pwd'];
//发送者
$from = $this->config['smtp_user'];
//发送者名称
$from_name = $user;//tpCache('web.web_name');
// 使用安全协议
$encryption_type = null;
switch ($port) {
case 465:
$encryption_type = 'ssl';
break;
case 587:
$encryption_type = 'tls';
break;
default:
# code...
break;
}
//HTML内容转换
$body = $this->replaceContent($scene, $data);
// Create the Transport
$transport = (new \Swift_SmtpTransport($host, $port, $encryption_type))
->setUsername($user)
->setPassword($pwd);
// Create the Mailer using your created Transport
$mailer = new \Swift_Mailer($transport);
// Create a message
$message = (new \Swift_Message($subject))
->setFrom([$from=>$from_name])
// ->setTo([$to, '第二个接收者邮箱' => '别名'])
->setTo($to)
->setContentType("text/html")
->setBody($body);
// Send the message
$result = $mailer->send($message);
if (!$result) {
return array('code'=>0 , 'msg'=>'发送失败');
} else {
return array('code'=>1 , 'msg'=>'发送成功');
}
} catch (\Exception $e) {
return array('code'=>0 , 'msg'=>'发送失败: '.$e->errorMessage());
}
}
/**
* 邮件发送 - 第三方库phpmailer
* @param $to 接收人
* @param string $subject 邮件标题
* @param string|array $data 邮件内容(html模板渲染后的内容)
* @param string $scene 使用场景
* @throws Exception
*/
private function send_phpmailer($to='', $subject='', $data='', $scene=1){
vendor('phpmailer.PHPMailerAutoload');
try {
//判断openssl是否开启
$openssl_funcs = get_extension_funcs('openssl');
if(!$openssl_funcs){
return array('code'=>0 , 'msg'=>'请先开启php的openssl扩展');
}
//判断openssl是否开启
// $sockets_funcs = get_extension_funcs('sockets');
// if(!$sockets_funcs){
// return array('code'=>0 , 'msg'=>'请先开启php的sockets扩展');
// }
$mail = new \PHPMailer;
$mail->CharSet = 'UTF-8'; //设定邮件编码,默认ISO-8859-1,如果发中文此项必须设置,否则乱码
$mail->isSMTP();
//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = 0;
//调试输出格式
//$mail->Debugoutput = 'html';
//接收者邮件
empty($to) && $to = $this->config['smtp_from_eamil'];
$to = explode(',', $to);
//smtp服务器
$mail->Host = $this->config['smtp_server'];
//端口 - likely to be 25, 465 or 587
$mail->Port = intval($this->config['smtp_port']);
// 使用安全协议
switch ($mail->Port) {
case 465:
$mail->SMTPSecure = 'ssl';
break;
case 587:
$mail->SMTPSecure = 'tls';
break;
default:
# code...
break;
}
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//用户名
$mail->Username = $this->config['smtp_user'];
//密码
$mail->Password = $this->config['smtp_pwd'];
//Set who the message is to be sent from
$mail->setFrom($this->config['smtp_user']);
//回复地址
//$mail->addReplyTo('replyto@example.com', 'First Last');
//接收邮件方
if(is_array($to)){
foreach ($to as $v){
$mail->addAddress($v);
}
}else{
$mail->addAddress($to);
}
$mail->isHTML(true);// send as HTML
//标题
$mail->Subject = $subject;
//HTML内容转换
$content = $this->replaceContent($scene, $data);
$mail->msgHTML($content);
//Replace the plain text body with one created manually
//$mail->AltBody = 'This is a plain-text message body';
//添加附件
//$mail->addAttachment('images/phpmailer_mini.png');
//send the message, check for errors
$result = $mail->send();
if (!$result) {
$msg = $mail->ErrorInfo;
if (stristr($msg, 'smtp connect() failed')) {
if (465 == $mail->Port) {
$msg = '
1.请检查配置是否正确
2.空间是否开启函数fsockopen
3.尝试切换PHP不同版本重试';
} else {
$msg = '请检查SMTP端口填写是否正确,一般默认是465端口,其次25端口,具体请参看各STMP服务商的设置说明。';
}
}
return array('code'=>0 , 'msg'=>'发送失败:'.$msg);
} else {
return array('code'=>1 , 'msg'=>'发送成功');
}
} catch (\Exception $e) {
return array('code'=>0 , 'msg'=>'发送失败: '.$e->errorMessage());
}
}
}