Skip to content

Instantly share code, notes, and snippets.

@shanept
Last active March 7, 2024 19:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shanept/77f8b69fc89a2df2b8cd1029670abb6f to your computer and use it in GitHub Desktop.
Save shanept/77f8b69fc89a2df2b8cd1029670abb6f to your computer and use it in GitHub Desktop.
Provides a simple PHP mailer wrapper for contact foms.
<?php
/**
* Ensure you define the following constants - for example:
*
* define('SMTP_FROM', 'noreply@example.com');
* define('MAIL_TO', 'rcpt@example.com');
*
* // If using SMTP transport:
* define('SMTP_HOST', 'smtp.example.com');
* define('SMTP_PORT', '25'); // 25, 465, 587, 2525 are common options
* define('SMTP_USER', 'sender@example.com'); // defaults to ''
* define('SMTP_PASS', 'SMTP_USER Password'); // defaults to ''
*/
include __DIR__ . '/PHPMailer-6.9.1/src/Exception.php';
include __DIR__ . '/PHPMailer-6.9.1/src/PHPMailer.php';
include __DIR__ . '/PHPMailer-6.9.1/src/SMTP.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
/**
* This is a helper function around PHP Mailer.
* Server parameters are configured with the above declarations.
* Email-specific functions are dictated within the 'data' array.
*
* @author Shane Thompson <me@shane.pt>
*
* @param array $args {
* An array of arguments.
*
* @type array $to Required. Takes an array of address fields.
* $to = [
* 'user1@example.com,
* ['user2@example.com', 'John Doe]
* ]
* @type array $cc Optional. Same format as $to.
* @type array $bcc Optional. Same format as $to.
* @type array $reply-to Optional. Same format as $to.
* @type string $subject Required.
* @type string $body Optional. If not specified, will be generated from supplied fields.
* @type string $transport Optional. 'smtp', 'sendmail' or 'mail'. If not specified, tests the
* environment in that order.
* @type bool $debug Optional. Enables debugging. Defaults to false.
* @type string * Optional. Any remaining contact form fields from which to generate
* an email body.
* } /args
*/
function send_email(array $args) {
$SMTP_FROM = 'noreply@' . $_SERVER['HTTP_HOST'];
$SMTP_PORT = 25;
$SMTP_USER = '';
$SMTP_PASS = '';
if (defined('SMTP_FROM')) $SMTP_FROM = SMTP_FROM;
if (defined('SMTP_PORT')) $SMTP_PORT = SMTP_PORT;
if (defined('SMTP_USER')) $SMTP_USER = SMTP_USER;
if (defined('SMTP_PASS')) $SMTP_PASS = SMTP_PASS;
if (!array_key_exists('to', $args) ||
!array_key_exists('subject', $args))
{
throw new ValueError(sprintf(
'%s missing required keys.', __FUNC__
));
}
$allowed_transports = array('smtp', 'sendmail', 'mail');
if (! array_key_exists('transport', $args) ||
! in_array($args['transport'], $allowed_transports))
{
if (defined('SMTP_HOST')) {
$args['transport'] = 'smtp';
} elseif (ini_get('sendmail_path')) {
$args['transport'] = 'sendmail';
} elseif (function_exists('mail')) {
$args['transport'] = 'mail';
} else {
throw new \RuntimeException(
'No valid mail transport could be detected. ' .
'Please configure a valid mail transport.'
);
}
}
if (! array_key_exists('debug', $args)) {
$args['debug'] = false;
}
$mail = new PHPMailer;
if ($args['debug']) {
$mail->Debugoutput = $args['debug'];
$mail->SMTPDebug = 2;
}
call_user_func([$mail, 'is' . $args['transport']]);
if ('smtp' === $args['transport']) {
if (! defined('SMTP_HOST')) {
throw new RuntimeException(sprintf(
'%s: No SMTP_HOST defined.', __FUNC__
));
}
$mail->Host = SMTP_HOST;
if (!empty($SMTP_USER) && !empty($SMTP_PASS)) {
$mail->SMTPAuth = true;
$mail->Username = $SMTP_USER;
$mail->Password = $SMTP_PASS;
}
$mail->port = $SMTP_PORT;
switch ($mail->port) {
case 465:
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
break;
case 587:
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
break;
case 25:
default:
$mail->SMTPSecure = ''; // No encryption
$mail->SMTPAutoTLS = true; // Automatically negotiate TLS connections where supported
break;
}
}
//Recipients
$mail->setFrom($SMTP_FROM);
// Add all addresses
foreach (['to', 'cc', 'bcc', 'reply-to'] as $func) {
if (! array_key_exists($func, $args)) {
continue;
}
foreach ($args[$func] as $rcpt) {
if (!is_array($rcpt)) {
$rcpt = [$rcpt, ''];
}
if ('reply-to' === $func) {
$func = 'ReplyTo';
}
if ('addto' === ($method = "add{$func}")) {
$method = 'addAddress';
}
call_user_func_array(array($mail, $method), $rcpt);
}
}
$body = '';
// Generate a generic body output to fall back upon
$skip_keys = array('subject', 'body', 'to', 'cc', 'bcc', 'reply-to', 'transport', 'debug');
foreach ($args as $key=>$val) {
if (in_array($key, $skip_keys, true)) {
continue;
}
$body .= sprintf(
'<b>%s</b> %s<br/>',
htmlspecialchars($key),
nl2br(htmlspecialchars($val))
);
}
//Content
$mail->isHTML(true); //Set email format to HTML
$mail->Subject = $args['subject'];
$mail->Body = $args['body'] ?: $body;
$mail->AltBody = strip_tags(preg_replace('/\<br(\s*)?\/?\>/i', "\n", $mail->Body));
return $mail->send();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment