Skip to content
This repository has been archived by the owner on Sep 3, 2021. It is now read-only.

Commit

Permalink
SMTP channel sends mail in a non-blocking manner
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowySpirits committed Mar 2, 2019
1 parent aedadc1 commit f992a1c
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 116 deletions.
66 changes: 66 additions & 0 deletions Action.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

class Comment2Mail_Action extends Widget_Abstract_Contents implements Widget_Interface_Do
{
public function action() {}

public function sendSMTP($param = array())
{
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404);
}
if (empty($param)) {
$param = $_POST;
}
$stime = microtime(true);
if (!class_exists(\PHPMailer\PHPMailer\PHPMailer::class)) {
require __DIR__ . '/lib/PHPMailer.php';
}

if (!class_exists(\PHPMailer\PHPMailer\SMTP::class)) {
require __DIR__ . '/lib/SMTP.php';
}

if (!class_exists('PHPMaile\PHPMailer\Exception')) {
require __DIR__ . '/lib/Exception.php';
}

$mail = new PHPMailer\PHPMailer\PHPMailer(FALSE);
$mail->CharSet = 'UTF-8';
$mail->isSMTP();
$mail->Host = $param['smtp_host'];
$mail->Port = $param['smtp_port'] ?: 25;
$mail->Username = $param['smtp_user'];
$mail->Password = $param['smtp_pass'];

if (in_array('enable', $param['smtp_auth'])) {
$mail->SMTPAuth = TRUE;
}

if ('none' !== $param['smtp_secure']) {
$mail->SMTPSecure = $param['smtp_secure'];
}

$mail->setFrom($param['from'], $param['fromName']);
$mail->addReplyTo($param['replyTo'], $param['fromName']);
$mail->addAddress($param['to']);
$mail->isHTML(TRUE);
$mail->SMTPDebug = 4;
$mail->Subject = $param['subject'];
$mail->msgHTML($param['html']);
$result = $mail->send();
$etime = microtime(true);

$plugin = Helper::options()->plugin('Comment2Mail');
if (in_array('enable', $plugin->public_debug)) {
$log = '[SMTP] ' . date('Y-m-d H:i:s') . ': ' . PHP_EOL;
if (!empty($mail->ErrorInfo)) $log .= serialize($result) . '; PHPMailer error: ' . $mail->ErrorInfo . PHP_EOL;
$log .= 'execution time:' . ($etime - $stime) . PHP_EOL;
$log .= 'to:' . $param['to'] . PHP_EOL;
$log .= 'email content:' . $param['html'] . PHP_EOL;
$log .= '-------------------------------------------' . PHP_EOL . PHP_EOL . PHP_EOL;
file_put_contents(__DIR__ . '/debug.log', $log, FILE_APPEND);
}
return $result;
}
}
191 changes: 75 additions & 116 deletions Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
*
* @package Comment2Mail
* @author SSpirits
* @version 1.0.0
* @version 1.1.0
* @link https://blog.sspirits.top
*/

if (!defined('__TYPECHO_ROOT_DIR__')) exit;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}

date_default_timezone_set('Asia/Shanghai');

Expand All @@ -21,14 +23,15 @@ class Comment2Mail_Plugin implements Typecho_Plugin_Interface
* @access public
* @throws Typecho_Plugin_Exception
*/
static public function activate()
public static function activate()
{
if (!function_exists('curl_init')) {
throw new Typecho_Plugin_Exception(_t('您需要先安装 PHP CURL 拓展'));
}
Typecho_Plugin::factory('Widget_Feedback')->finishComment = array(__CLASS__, 'sendMail');
Typecho_Plugin::factory('Widget_Comments_Edit')->finishComment = array(__CLASS__, 'sendMail');
Typecho_Plugin::factory('Widget_Comments_Edit')->mark = array(__CLASS__, 'approvedMail');
Helper::addRoute('route_SMTP', '/send-by-smtp', 'Comment2Mail_Action', 'sendSMTP');
}

/**
Expand All @@ -37,8 +40,9 @@ static public function activate()
* @static
* @access public
*/
static public function deactivate()
public static function deactivate()
{
Helper::removeRoute("route_SMTP");
}

/**
Expand All @@ -49,7 +53,7 @@ static public function deactivate()
*
* @param Typecho_Widget_Helper_Form $form
*/
static public function config(Typecho_Widget_Helper_Form $form)
public static function config(Typecho_Widget_Helper_Form $form)
{
$normal_section = new Typecho_Widget_Helper_Layout('div');
$normal_section->html('<h2>通用设置</h2>');
Expand Down Expand Up @@ -98,7 +102,7 @@ static public function config(Typecho_Widget_Helper_Form $form)
*
* @param Typecho_Widget_Helper_Form $form
*/
static public function personalConfig(Typecho_Widget_Helper_Form $form)
public static function personalConfig(Typecho_Widget_Helper_Form $form)
{
}

Expand All @@ -114,7 +118,7 @@ static public function personalConfig(Typecho_Widget_Helper_Form $form)
* @throws Typecho_Plugin_Exception
* @throws \PHPMailer\PHPMailer\Exception
*/
static public function sendMail($comment)
public static function sendMail($comment)
{
if (0 < $comment->parent) {
$parentComment = self::getWidget('Comments', 'coid', $comment->parent);
Expand Down Expand Up @@ -144,7 +148,7 @@ static public function sendMail($comment)
* @throws Typecho_Plugin_Exception
* @throws \PHPMailer\PHPMailer\Exception
*/
static public function approvedMail($comment, $edit, $status)
public static function approvedMail($comment, $edit, $status)
{
if ('approved' === $status) {
self::send($edit->mail, $edit, NULL, TRUE);
Expand All @@ -167,19 +171,19 @@ static public function approvedMail($comment, $edit, $status)
* @throws Typecho_Plugin_Exception
* @throws \PHPMailer\PHPMailer\Exception
*/
static private function send($mail, $comment, $parentComment, $isApproved = FALSE)
private static function send($mail, $comment, $parentComment, $isApproved = FALSE)
{
$options = Helper::options();
$plugin = $options->plugin('Comment2Mail');
$data = array(
'fromName' => (!isset($plugin->public_name) || is_null($plugin->public_name) || empty($plugin->public_name)) ? trim($options->title) : $plugin->public_name,
'fromName' => (!isset($plugin->public_name) || $plugin->public_name === null || empty($plugin->public_name)) ? trim($options->title) : $plugin->public_name,
'from' => $plugin->public_mail,
'to' => $mail,
'replyTo' => $plugin->public_replyto,
);
if ($isApproved) {
$data['subject'] = '您在 [' . trim($options->title) . '] 发表的文章有新评论!';
$html = file_get_contents(dirname(__FILE__) . '/theme/approved.html');
$html = file_get_contents(__DIR__ . '/theme/approved.html');
$data['html'] = str_replace(array(
'{blogUrl}',
'{blogName}',
Expand All @@ -195,55 +199,54 @@ static private function send($mail, $comment, $parentComment, $isApproved = FALS
trim($comment->title),
str_replace(PHP_EOL, '<br>', trim($comment->text))
), $html);
} elseif ($parentComment !== null) {
$data['subject'] = '您在 [' . $options->title . '] 的评论有了新的回复!';
$html = file_get_contents(__DIR__ . '/theme/reply.html');
$post = self::getWidget('Contents', 'cid', $parentComment->cid);
$data['html'] = str_replace(array(
'{blogUrl}',
'{blogName}',
'{author}',
'{permalink}',
'{title}',
'{text}',
'{replyAuthor}',
'{replyText}',
'{commentUrl}'
), array(
trim($options->siteUrl),
trim($options->title),
trim($parentComment->author),
trim($post->permalink),
trim($post->title),
str_replace(PHP_EOL, '<br>', trim($parentComment->text)),
trim($comment->author),
str_replace(PHP_EOL, '<br>', trim($comment->text)),
trim($comment->permalink)
), $html);
} else {
if (!is_null($parentComment)) {
$data['subject'] = '您在 [' . $options->title . '] 的评论有了新的回复!';
$html = file_get_contents(dirname(__FILE__) . '/theme/reply.html');
$post = self::getWidget('Contents', 'cid', $parentComment->cid);
$data['html'] = str_replace(array(
'{blogUrl}',
'{blogName}',
'{author}',
'{permalink}',
'{title}',
'{text}',
'{replyAuthor}',
'{replyText}',
'{commentUrl}'
), array(
trim($options->siteUrl),
trim($options->title),
trim($parentComment->author),
trim($post->permalink),
trim($post->title),
str_replace(PHP_EOL, '<br>', trim($parentComment->text)),
trim($comment->author),
str_replace(PHP_EOL, '<br>', trim($comment->text)),
trim($comment->permalink)
), $html);
} else {
$data['subject'] = '您在 [' . $options->title . '] 发表的文章有新评论!';
$html = file_get_contents(dirname(__FILE__) . '/theme/author.html');
$data['html'] = str_replace(array(
'{blogUrl}',
'{blogName}',
'{author}',
'{permalink}',
'{title}',
'{text}'
), array(
trim($options->siteUrl),
trim($options->title),
trim($comment->author),
trim($comment->permalink),
trim($comment->title),
str_replace(PHP_EOL, '<br>', trim($comment->text))
), $html);
}
$data['subject'] = '您在 [' . $options->title . '] 发表的文章有新评论!';
$html = file_get_contents(__DIR__ . '/theme/author.html');
$data['html'] = str_replace(array(
'{blogUrl}',
'{blogName}',
'{author}',
'{permalink}',
'{title}',
'{text}'
), array(
trim($options->siteUrl),
trim($options->title),
trim($comment->author),
trim($comment->permalink),
trim($comment->title),
str_replace(PHP_EOL, '<br>', trim($comment->text))
), $html);
}

switch ($plugin->public_interface) {
case 'mailgun':
$data['from'] = ((!isset($plugin->public_name) || is_null($plugin->public_name) || empty($plugin->public_name)) ? trim($options->title) : $plugin->public_name) . '<' . $plugin->public_mail . '>';
$data['from'] = ((!isset($plugin->public_name) || $plugin->public_name === null || empty($plugin->public_name)) ? trim($options->title) : $plugin->public_name) . '<' . $plugin->public_mail . '>';
return self::mailGun($data, $plugin->mailgun_api_domain, $plugin->mailgun_api_key);
case 'smtp':
$data['smtp_host'] = $plugin->smtp_host;
Expand All @@ -254,6 +257,7 @@ static private function send($mail, $comment, $parentComment, $isApproved = FALS
$data['smtp_secure'] = $plugin->smtp_secure;
return self::smtp($data);
}
return '';
}

/**
Expand All @@ -269,7 +273,7 @@ static private function send($mail, $comment, $parentComment, $isApproved = FALS
* @return mixed
* @throws Typecho_Db_Exception
*/
static private function getWidget($name, $key, $val)
private static function getWidget($name, $key, $val)
{
$className = 'Widget_Abstract_' . $name;
$widget = new $className(new Typecho_Request(), new Typecho_Response(), NULL);
Expand All @@ -290,14 +294,12 @@ static private function getWidget($name, $key, $val)
* @return mixed
* @throws Typecho_Plugin_Exception
*/
static private function mailGun($param, $domain, $apikey)
private static function mailGun($param, $domain, $apikey)
{
$stime = microtime(true);
$ch = curl_init();
$url = 'https://api.mailgun.net/v2/' . $domain . '/messages';
curl_setopt($ch, CURLOPT_USERPWD, 'api:' . $apikey);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_URL, $url);
Expand All @@ -312,8 +314,8 @@ static private function mailGun($param, $domain, $apikey)
$log = '[Mailgun] ' . date('Y-m-d H:i:s') . ': ' . PHP_EOL;
$log .= serialize($result) . PHP_EOL;
$log .= 'execution time:' . ($etime - $stime) . PHP_EOL;
$log .= 'to:' .$param['to'] . PHP_EOL;
$log .= 'email content:' .$param['html'] . PHP_EOL;
$log .= 'to:' . $param['to'] . PHP_EOL;
$log .= 'email content:' . $param['html'] . PHP_EOL;
$log .= '-------------------------------------------' . PHP_EOL . PHP_EOL . PHP_EOL;
file_put_contents(__DIR__ . '/debug.log', $log, FILE_APPEND);
}
Expand All @@ -332,60 +334,17 @@ static private function mailGun($param, $domain, $apikey)
* @throws Typecho_Plugin_Exception
* @throws \PHPMailer\PHPMailer\Exception
*/
static private function smtp($param)
private static function smtp($param)
{

$stime = microtime(true);
if (!class_exists('PHPMailer\PHPMailer\PHPMailer')) {
require dirname(__FILE__) . '/lib/PHPMailer.php';
}

if (!class_exists('PHPMailer\PHPMailer\SMTP')) {
require dirname(__FILE__) . '/lib/SMTP.php';
}

if (!class_exists('PHPMaile\PHPMailer\Exception')) {
require dirname(__FILE__) . '/lib/Exception.php';
}

$mail = new PHPMailer\PHPMailer\PHPMailer(FALSE);
$mail->CharSet = 'UTF-8';
$mail->isSMTP();
$mail->Host = $param['smtp_host'];
$mail->Port = $param['smtp_port'] ?: 25;
$mail->Username = $param['smtp_user'];
$mail->Password = $param['smtp_pass'];

if (in_array('enable', $param['smtp_auth'])) {

$mail->SMTPAuth = TRUE;
}

if ('none' != $param['smtp_secure']) {

$mail->SMTPSecure = $param['smtp_secure'];
}

$mail->setFrom($param['from'], $param['fromName']);
$mail->addReplyTo($param['replyTo'], $param['fromName']);
$mail->addAddress($param['to']);
$mail->isHTML(TRUE);
$mail->SMTPDebug = 4;
$mail->Subject = $param['subject'];
$mail->msgHTML($param['html']);
$result = $mail->send();
$etime = microtime(true);

$plugin = Helper::options()->plugin('Comment2Mail');
if (in_array('enable', $plugin->public_debug)) {
$log = '[SMTP] ' . date('Y-m-d H:i:s') . ': ' . PHP_EOL;
$log .= serialize($result) . '; PHPMailer error: ' . $mail->ErrorInfo . PHP_EOL;
$log .= 'execution time:' . ($etime - $stime) . PHP_EOL;
$log .= 'to:' .$param['to'] . PHP_EOL;
$log .= 'email content:' .$param['html'] . PHP_EOL;
$log .= '-------------------------------------------' . PHP_EOL . PHP_EOL . PHP_EOL;
file_put_contents(__DIR__ . '/debug.log', $log, FILE_APPEND);
}
return $result;
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,Helper::options()->siteUrl . '/send-by-smtp');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($param));
curl_setopt($ch, CURLOPT_HEADER, true);
curl_exec($ch);
curl_close($ch);
return true;
}
}

0 comments on commit f992a1c

Please sign in to comment.