Add email sending functionality

master
Skylar Ittner 6 years ago
parent a3583ae16b
commit e4c4f3286f

@ -9,6 +9,9 @@
*/
require_once __DIR__ . "/required.php";
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
if ($VARS['action'] !== "signout") {
dieifnotloggedin();
}
@ -31,7 +34,97 @@ function returnToSender($msg, $arg = "") {
switch ($VARS['action']) {
case "sendpub":
die("not implemented yet.");
try {
ini_set('max_execution_time', 60 * 5);
// Setup mailer
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = SMTP_AUTH;
if (SMTP_AUTH) {
$mail->Username = SMTP_USERNAME;
$mail->Password = SMTP_PASSWORD;
}
if (SMTP_SECURITY != "none") {
$mail->SMTPSecure = SMTP_SECURITY;
}
$mail->Port = SMTP_PORT;
$mail->isHTML(false);
$mail->setFrom(SMTP_FROMADDRESS, SMTP_FROMNAME);
// Get addresses
$addresses = [];
if ($database->has('mail_lists', ['listid' => $VARS['list']])) {
$addresses = $database->select("addresses", 'email', ['listid' => $VARS['list']]);
} else {
returnToSender("invalid_listid");
}
// Split address list into batches
$segmented = [];
$s = 0;
for ($i = 0; $i < count($addresses); $i++) {
$segmented[$s][] = $addresses[$i];
if (count($segmented[$s]) >= SMTP_BATCH_SIZE) {
$s++;
}
}
// Build message content
if (empty($VARS['subject']) || trim($VARS['subject']) == "") {
returnToSender("invalid_parameters");
}
if (empty($VARS['pubid']) || !$database->has("publications", ['pubid' => $VARS['pubid']])) {
returnToSender("invalid_pubid");
}
$mail->Subject = $VARS['subject'];
$parsedown = new Parsedown();
$parsedown->setSafeMode(true);
$html = $parsedown->text($VARS['message']);
if (strpos(URL, "https://") === 0 || strpos(URL, "http://") === 0) {
$url = URL;
} else {
// Don't trust the URL setting, it's not an absolute URL
$url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]";
$path = explode("/", $_SERVER["REQUEST_URI"]);
array_pop($path);
$url .= implode("/", $path);
}
$url = $url . (substr($url, -1) == '/' ? '' : '/');
$puburl = $url . "view.php?id=" . $VARS['pubid'];
$unsuburl = $url . "unsubscribe.php";
$link = "<a href=\"$puburl\">$puburl</a>\n";
$footer = "<hr />\nUnsubscribe: <a href=\"$unsuburl\">$unsuburl</a>";
$mail->Body = $html . "<br />\n" . $link . $footer;
$mail->AltBody = $VARS['message'] . "\n" . $puburl . "\n\n-----\nUnsubscribe: $unsuburl";
var_dump($mail->Body);
var_dump($mail->AltBody);
// Send the mail
foreach ($segmented as $segment) {
foreach ($segment as $s) {
$mail->addBCC($s);
}
$mail->send();
$mail->clearAllRecipients();
}
} catch (Exception $ex) {
returnToSender("mail_error", $mail->ErrorInfo);
}
$database->update("publications", ['mailedon' => date("Y-m-d H:i:s"), 'mailedto' => $VARS['list']], ['pubid' => $VARS['pubid']]);
returnToSender("mail_sent");
break;
case "editpub":
$insert = true;
@ -51,9 +144,9 @@ switch ($VARS['action']) {
returnToSender('invalid_parameters');
}
$VARS['columns'] = 4;
/*if (!is_numeric($VARS['columns'])) {
returnToSender('invalid_parameters');
}*/
/* if (!is_numeric($VARS['columns'])) {
returnToSender('invalid_parameters');
} */
if (!preg_match("/([A-Za-z0-9_])+/", $VARS['style'])) {
$VARS['style'] = "";
}

@ -4,7 +4,9 @@
"type": "project",
"require": {
"catfan/medoo": "^1.5",
"guzzlehttp/guzzle": "^6.2"
"guzzlehttp/guzzle": "^6.2",
"phpmailer/phpmailer": "^6.0",
"erusev/parsedown": "^1.7"
},
"license": "MPL-2.0",
"authors": [

116
composer.lock generated

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "924faa0bab19df95b4ae0a73869d1a64",
"content-hash": "78381125cec2264192fbd0feacb704c1",
"hash": "fdb05abdb1063e98e613030e3ef8d688",
"content-hash": "9f22ca23358d7714943dd9e7fe1b22f0",
"packages": [
{
"name": "catfan/medoo",
@ -66,6 +66,52 @@
],
"time": "2017-12-25 17:02:41"
},
{
"name": "erusev/parsedown",
"version": "1.7.1",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "92e9c27ba0e74b8b028b111d1b6f956a15c01fc1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/92e9c27ba0e74b8b028b111d1b6f956a15c01fc1",
"reference": "92e9c27ba0e74b8b028b111d1b6f956a15c01fc1",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35"
},
"type": "library",
"autoload": {
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"markdown",
"parser"
],
"time": "2018-03-08 01:11:30"
},
{
"name": "guzzlehttp/guzzle",
"version": "6.3.0",
@ -247,6 +293,72 @@
],
"time": "2017-03-20 17:10:46"
},
{
"name": "phpmailer/phpmailer",
"version": "v6.0.5",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "cb3ea134d4d3729e7857737d5f320cce9caf4d32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/cb3ea134d4d3729e7857737d5f320cce9caf4d32",
"reference": "cb3ea134d4d3729e7857737d5f320cce9caf4d32",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-filter": "*",
"php": ">=5.5.0"
},
"require-dev": {
"doctrine/annotations": "1.2.*",
"friendsofphp/php-cs-fixer": "^2.2",
"phpdocumentor/phpdocumentor": "2.*",
"phpunit/phpunit": "^4.8 || ^5.7",
"zendframework/zend-eventmanager": "3.0.*",
"zendframework/zend-i18n": "2.7.3",
"zendframework/zend-serializer": "2.7.*"
},
"suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
},
"type": "library",
"autoload": {
"psr-4": {
"PHPMailer\\PHPMailer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "Jim Jagielski",
"email": "jimjag@gmail.com"
},
{
"name": "Marcus Bointon",
"email": "phpmailer@synchromedia.co.uk"
},
{
"name": "Andy Prevost",
"email": "codeworxtech@users.sourceforge.net"
},
{
"name": "Brent R. Matzelle"
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"time": "2018-03-27 13:49:45"
},
{
"name": "psr/http-message",
"version": "1.0.1",

Binary file not shown.

@ -77,6 +77,7 @@ define("STRINGS", [
"view file" => "View File",
"password incorrect" => "Password incorrect.",
"invalid listid" => "Invalid list ID.",
"new list" => "New List",
"list saved" => "Mailing list saved.",
"list deleted" => "Mailing list deleted.",
"adding list" => "Adding mailing list",
@ -97,5 +98,8 @@ define("STRINGS", [
"placeholder subject" => "Type an email subject",
"message" => "Message",
"default message" => "Hello, \nClick the link to view the newsletter:",
"cancel" => "Cancel"
"cancel" => "Cancel",
"mail error {arg}" => "Mail error: {arg}",
"mail sent" => "Mail sent!",
"last mailed on x to y" => "Publication last mailed on {x} to list {y}.",
]);

@ -45,4 +45,12 @@ define("MESSAGES", [
"string" => "list deleted",
"type" => "success"
],
"mail_error" => [
"string" => "mail error {arg}",
"type" => "danger"
],
"mail_sent" => [
"string" => "mail sent",
"type" => "success"
],
]);

@ -13,14 +13,40 @@ if (is_empty($VARS['pubid']) || !$database->has("publications", ['pubid' => $VAR
}
$lists = $database->select("mail_lists", ['listid', 'listname']);
$lastmailed = $database->get("publications", ["[>]mail_lists" => ["mailedto" => "listid"]], ['mailedon', 'mailedto', 'listname'], ['pubid' => $VARS['pubid']]);
if (strpos(URL, "https://") === 0 || strpos(URL, "http://") === 0) {
$url = URL;
} else {
// Don't trust the URL setting, it's not an absolute URL
$url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]";
$path = explode("/", $_SERVER["REQUEST_URI"]);
array_pop($path);
$url .= implode("/", $path);
}
$url = $url . (substr($url, -1) == '/' ? '' : '/');
?>
<form role="form" action="action.php" method="POST">
<form role="form" action="action.php" method="POST" id="sendform">
<div class="card border-deep-purple">
<h3 class="card-header text-deep-purple">
<i class="fas fa-paper-plane"></i> <?php lang("send publication"); ?>
</h3>
<div class="card-body">
<?php
if (isset($lastmailed['mailedon']) && isset($lastmailed['listname'])) {
?>
<div class="alert alert-info">
<i class="fas fa-info-circle"></i> <?php
lang2("last mailed on x to y", [
"x" => date(DATETIME_FORMAT, strtotime($lastmailed['mailedon'])),
"y" => $lastmailed['listname']]);
?>
</div>
<?php
}
?>
<div class="row">
<div class="col-12 col-sm-6">
<div class="form-group">
@ -40,12 +66,12 @@ $lists = $database->select("mail_lists", ['listid', 'listname']);
</div>
<div class="card-body">
<span id="messagepreview">
<?php echo str_replace("\n", "<br>", lang("default message", false)); ?>
<?php echo str_replace("\n", "<br>", lang("default message", false)); ?>
</span>
<br>
<a href="<?php echo URL; ?>/view.php?id=<?php echo $VARS['pubid']; ?>"><?php echo URL; ?>/view.php?id=<?php echo $VARS['pubid']; ?></a>
<a href="<?php echo $url; ?>view.php?id=<?php echo $VARS['pubid']; ?>"><?php echo $url; ?>view.php?id=<?php echo $VARS['pubid']; ?></a>
<hr />
Unsubscribe: <a href="<?php echo URL; ?>/unsubscribe.php?a=xxxxx@example.com"><?php echo URL; ?>/unsubscribe.php?a=xxxxx@example.com</a>
Unsubscribe: <a href="<?php echo $url; ?>unsubscribe.php"><?php echo $url; ?>unsubscribe.php</a>
</div>
</div>
</div>
@ -63,16 +89,16 @@ $lists = $database->select("mail_lists", ['listid', 'listname']);
</div>
<input type="hidden" name="pubid" value="<?php
echo htmlspecialchars($VARS['pubid']);
?>" />
echo htmlspecialchars($VARS['pubid']);
?>" />
<input type="hidden" name="action" value="sendpub" />
<input type="hidden" name="source" value="home" />
<div class="card-footer d-flex">
<button type="submit" class="btn btn-success mr-auto"><i class="fas fa-paper-plane"></i> <?php lang("send"); ?></button>
<button type="submit" class="btn btn-success mr-auto" id="sendbtn"><i class="fas fa-paper-plane"></i> <?php lang("send"); ?></button>
<a href="./app.php?page=content&pubid=<?php echo htmlspecialchars($VARS['pubid']); ?>" class="btn btn-danger"><i class="fas fa-times"></i> <?php lang('cancel'); ?></a>
<a id="cancelbtn" href="./app.php?page=content&pubid=<?php echo htmlspecialchars($VARS['pubid']); ?>" class="btn btn-info"><i class="fas fa-arrow-left"></i> <?php lang('cancel'); ?></a>
</div>
</div>
</form>

@ -20,6 +20,15 @@ define("DB_CHARSET", "utf8");
// Name of the app.
define("SITE_TITLE", "NewsPen");
define("SMTP_HOST", "");
define("SMTP_AUTH", true);
define("SMTP_SECURITY", "tls"); // tls, ssl, or none
define("SMTP_PORT", 25);
define("SMTP_USERNAME", "");
define("SMTP_PASSWORD", "");
define("SMTP_FROMADDRESS", "newspen@example.com");
define("SMTP_FROMNAME", "NewsPen");
define("SMTP_BATCH_SIZE", 20);
// URL of the AccountHub API endpoint
define("PORTAL_API", "http://localhost/accounthub/api.php");

@ -11,4 +11,12 @@ $("#subject").on("keyup", function () {
$("#message").on("keyup", function () {
$("#messagepreview").html(snarkdown($("#message").val()));
});
$("#sendform").submit(function () {
$("#sendbtn").attr("disabled", true);
$("#sendbtn").prop("disabled", true);
$("#cancelbtn").attr("disabled", true);
$("#cancelbtn").prop("disabled", true);
$("#sendbtn").html("<i class=\"fas fa-spinner fa-spin\"></i> Sending...");
});

@ -8,22 +8,38 @@ require __DIR__ . "/required.php";
require __DIR__ . "/lib/iputils.php";
$address = $VARS['a'];
?>
<!DOCTYPE html>
<title>Unsubscribe</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<?php
engageRateLimit();
if (isset($VARS['a'])) {
echo "<p>";
$address = $VARS['a'];
if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
die("Invalid email address.");
}
engageRateLimit();
$address = str_replace("%", '\%', $address);
if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
die("Invalid email address.");
}
echo $address;
$address = str_replace("%", '\%', $address);
if ($database->has('addresses', ['email' => $address])) {
$count = $database->count('addresses', ['email' => $address]);
$database->delete('addresses', ['email' => $address]);
die("$address has been removed from $count mailing " . ($count === 1 ? "list" : "lists") . ".");
if ($database->has('addresses', ['email' => $address])) {
$count = $database->count('addresses', ['email' => $address]);
$database->delete('addresses', ['email' => $address]);
die("$address has been removed from $count mailing " . ($count === 1 ? "list" : "lists") . ".");
} else {
die("$address has already been removed.");
}
} else {
die("$address has already been removed.");
?>
<p>Enter your email address below to unsubscribe:</p>
<form action="" method="GET">
<input type="email" name="a" placeholder="xxxxx@example.com" required />
<br />
<input type="submit" value="Unsubscribe" />
</form>
<?php
}
Loading…
Cancel
Save