<?php
include_once 'class.phpmailer.php';
include_once 'class.smtp.php';
include_once '../config.php';
include_once '../settings.php';
include_once '../utils.php';
class MailController {
protected $default_params = array(
'debug_level' => 1,
'attachments' => array(),
);
function __construct() {
//SMTP needs accurate times, and the PHP time zone MUST be set
//This should be done in your php.ini, but this is how to do it if you don't have access to that
date_default_timezone_set('Etc/UTC');
}
function isLocalRequest() {
return $_SERVER['SERVER_ADDR'] == $_SERVER['REMOTE_ADDR'];
}
public function run() {
$method = $_SERVER['REQUEST_METHOD'];
if ($method == "GET"){
$this->doGet();
} else if ($method == "POST") {
$this->doPost();
} else {
error_log("request method '" . $method . "' is not supported");
}
}
protected function doGet() {
}
// Example parameters:
// $params = array(
// 'smtp_server' => 'smtp.qq.com', //14.18.245.164
// 'smtp_secure' => 'tls', //optional
// 'smtp_port' => 465, //optional
// 'smtp_user' => 'ivincentwang@qq.com',
// 'smtp_pass' => "XXXXXXXXX",
// 'from_addr' => 'ivincentwang@qq.com',
// 'from_name' => 'Vincent Wang',
// 'cc_addr' => 'vincent@easyio.com', //optional
// 'cc_name' => 'Vincent Wang', //optional
// 'to_addr' => 'linsong.qizi@gmail.com',
// 'to_name' => 'Linsong Qizi',
// 'subject' => 'PHPMailer GMail SMTP test',
// 'content' => "hello test",
// 'attachments' => array('composer.json', 'class.smtp.php') // optional
// );
// NOTE: if manul test in browser, need to comment out the local request
// check below, otherwise, you will always be redirected
protected function doPost() {
if (!$this->isLocalRequest())
{
$url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header('Location: ' . $url, 302)
die();
}
$params = array_merge($this->default_params, $_POST);
//validate input
$required_keys = array('smtp_server', 'from_addr', 'to_addr', 'subject');
foreach($required_keys as $key) {
if (empty($params[$key])) {
die("ERROR : missing parameter '" . $key . "'");
}
}
if (!empty($params['attachments'])) {
$attachments = explode(',', $params['attachments']);
$params['attachments'] = $attachments;
}
$to_addrs = explode(',', $params['to_addr']);
$params['to_addr'] = $to_addrs;
if (!empty($params['to_name']))
{
$to_names = explode(',', $params['to_name']);
$params['to_name'] = $to_names;
}
if (!empty($params['cc_addr']))
{
$cc_addrs = explode(',', $params['cc_addr']);
$params['cc_addr'] = $cc_addrs;
}
if (!empty($params['cc_name']))
{
$cc_names = explode(',', $params['cc_name']);
$params['cc_name'] = $cc_names;
}
$this->sendMail($params);
exit();
}
protected function setupTlsTunnel($mail) {
$conf = new INIFile;
if ($conf->load("/mnt/tls_tunnel/tls_tunnel.conf")) {
$conf->setValue(NULL, 'remote_host', $mail->Host);
$conf->setValue(NULL, 'remote_port', $mail->Port);
$mail->Host = $conf->value(NULL, 'local_host', '127.0.0.1');
$mail->Port = intval($conf->value(NULL, 'local_port', '3333'));
$conf->save();
$pid = rtrim(file_get_contents("/var/run/tls_tunnel.pid"));
execCmd('kill -HUP ' . $pid)
}
}
protected function sendMail($params) {
//Create a new PHPMailer instance
$mail = new PHPMailer;
//Tell PHPMailer to use SMTP
$mail->isSMTP();
//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = $params['debug_level'];
//Enable auto TLS or not, by default disable it
if (!empty($params['auto_tls']))
$mail->SMTPAutoTLS = ($params['auto_tls'] == 'true' || $params['auto_tls'] == '1');
else
$mail->SMTPAutoTLS = false;
//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';
//Set the hostname of the mail server
$mail->Host = $params['smtp_server'];
// use
// $mail->Host = gethostbyname('smtp.gmail.com');
// if your network does not support SMTP over IPv6
//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
if (!empty($params['smtp_port']))
$mail->Port = $params['smtp_port'];
//Set the encryption system to use - ssl (deprecated) or tls
if (!empty($params['smtp_secure']))
{
$this->setupTlsTunnel($mail);
// never set SMTPSecure
// $mail->SMTPSecure = $params['smtp_secure'];
}
//Whether to use SMTP authentication
$mail->SMTPAuth = !empty($params['smtp_user']) && !empty($params['smtp_pass']);
//Username to use for SMTP authentication - use full email address for gmail
$mail->Username = $params['smtp_user'];
//Password to use for SMTP authentication
$mail->Password = $params['smtp_pass'];
//Set who the message is to be sent from
$mail->setFrom($params['from_addr'], $params['from_name']);
//Set cc data
if (!empty($params['cc_addr'])) {
foreach($params['cc_addr'] as $index => $addr)
$mail->addCC($addr, arrayGet($params['cc_name'], $index, ''));
}
//Set an alternative reply-to address
$mail->addReplyTo($params['from_addr'], $params['from_name']);
//Set who the message is to be sent to
foreach($params['to_addr'] as $index => $addr) {
$mail->addAddress($addr, arrayGet($params['to_name'], $index, ''));
}
//Set the subject line
$mail->Subject = $params['subject'];
//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
//$mail->sgHTML(file_get_contents('contents.html'), dirname(__FILE__));
$mail->sgHTML($params['content']);
$mail->Body = preg_replace('/\r\n/', '<br>', $mail->Body);
//Add Attachments
foreach($params['attachments'] as $path) {
$path = trim($path, "\r\n\t ");
//check if the path is relative path
if (!startsWith($path, '/')) {
$rootPath = $_SERVER['DOCUMENT_ROOT'];
$path = build_file_path($rootPath, $path);
}
if (!file_exists($path)) {
echo 'file "' . $path . '" does not exist, skip it ' . "\n";
continue;
}
$mail->addAttachment($path);
}
//send the message, check for errors
if (!$mail->send()) {
echo "ERROR : " . $mail->ErrorInfo;
http_response_code(503);
} else {
echo "SUCCESS";
}
}
}
$controller = new MailController();
$controller->run();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<eta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title><?php echo Config::$webPageTitle ?> Mail </title>
<link rel="stylesheet" href="../../css/bootstrap.min.css" media="screen" />
</head>
<body>
<div class="container">
<div class="row">
<div class="page-header"><h1>Mail SMTP Server Settings</h1></div>
<div class="alert alert-info">
<p>To send email by mail_controller, you need to send it a POST request from the <strong>*SAME*</strong> host.</p>
</div>
<h3>Gmail SMTP Setting:</h3>
<dl class='dl-horizontal'>
<dt>SMTP Server: </dt>
<dd>smtp.gmail.com</dd>
<dt>SMTP Port:</dt>
<dd><strong>5</strong> (for secure, recommended)</dd>
<dd> (for nonsecure)</dd>
</dl>
<div class="alert alert-info">
<h4>NOTE</h4>
If you can not send email successfully by Gmail SMTP server, there are two things you need to check:
<ul>
<li>Make sure the option 'Access for less secure apps' has been turned on. <strong><a href="https://support.google.com/accounts/answer/6010255?hl=en">Here</a></strong> is how to change it.</li>
<li>If you enabled 2-Step-Verification, then you will need to generate an App password and use it instead of your password. <strong><a href="https://support.google.com/accounts/answer/185833">Here</a></strong> is how to do it.</li>
</ul>
</div>
<h3>Yahoo! Mail SMTP Setting:</h3>
<dl class='dl-horizontal'>
<dt>SMTP Server: </dt>
<dd>smtp.mail.yahoo.com</dd>
<dt>SMTP Port:</dt>
<dd><strong>5</strong> (for secure, recommended)</dd>
<dd> (for nonsecure)</dd>
</dl>
<div class="alert alert-info">
<h4>NOTE</h4>
If you can not send email successfully by Yahoo! mail SMTP server, there are two things you need to check:
<ul>
<li>If you don't enable 2-Step-Verification, then make sure the option 'Allow apps that use less secure sign in' has been turned on. <strong><a href="https://help.yahoo.com/kb/account/SLN27791.html">Here</a> </strong> is how to do it.</li>
<li>If you enabled 2-Step-Verification, then you will need to generate an App password and use it as 'smtp_pass' instead of your password. <strong><a href="https://help.yahoo.com/kb/SLN15241.html">Here</a></strong> is how to do it.</li>
</ul>
</div>
</div>
</div>
</body>
</html>