Skip to content

Instantly share code, notes, and snippets.

@gaffling
Last active February 20, 2020 12:05
Show Gist options
  • Save gaffling/e821cab1ab486fbdc3d0a567a17fa94b to your computer and use it in GitHub Desktop.
Save gaffling/e821cab1ab486fbdc3d0a567a17fa94b to your computer and use it in GitHub Desktop.
[Send Mail] Use PHPMailer or PHP mail() function as fallback NEED logo.png and mail.tpl.htm & github.com/PHPMailer/PHPMailer #php #class #html #email
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>[SUBJECT]</title>
<style>
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important;
}
table[class=body] p,
table[class=body] ul,
table[class=body] ol,
table[class=body] td,
table[class=body] span,
table[class=body] a {
font-size: 16px !important;
}
table[class=body] .wrapper,
table[class=body] .article {
padding: 10px !important;
}
table[class=body] .content {
padding: 0 !important;
}
table[class=body] .container {
padding: 0 !important;
width: 100% !important;
}
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
table[class=body] .btn table {
width: 100% !important;
}
table[class=body] .btn a {
width: 100% !important;
}
table[class=body] .img-responsive {
height: auto !important;
max-width: 100% !important;
width: auto !important;
}
}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
#MessageViewBody a {
color: inherit;
text-decoration: none;
font-size: inherit;
font-family: inherit;
font-weight: inherit;
line-height: inherit;
}
.btn-primary table td:hover {
background-color: #34495e !important;
}
.btn-primary a:hover {
background-color: #34495e !important;
border-color: #34495e !important;
}
}
</style>
</head>
<body class="" style="background-color: #f6f6f6; font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: #f6f6f6;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
<td class="container" style="font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; Margin: 0 auto; max-width: 580px; padding: 10px; width: 580px;">
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px;">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">
[PREHEADER] <!-- max. 130 chars -->
</span>
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 3px;">
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
<p style="font-family: sans-serif; font-size: 30px; font-weight: bold; margin: 0; margin-bottom: 30px;">
<span style="font-size: 50px; vertical-align: middle; line-height: 0.5;"><img style="width: 50px;" src='logo.png' alt="🐡"></span>
Fugu &mdash; Mail
</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">
[BODY]
</p>
<!-- <BUTTON orange="#fd7e14"> -------------------------------------
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box;">
<tbody>
<tr>
<td align="left" style="font-family: sans-serif; font-size: 14px; vertical-align: top; padding-bottom: 15px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
<tbody>
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top; background-color: #fd7e14; border-radius: 5px; text-align: center;"> <a href="http://htmlemail.io" target="_blank" style="display: inline-block; color: #ffffff; background-color: #fd7e14; border: solid 1px #fd7e14; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px; text-transform: capitalize; border-color: #fd7e14;"> CALL TO ACTION </a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</BUTTON> ------------------------------------- -->
</td>
</tr>
</table>
</td>
</tr>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- START FOOTER -->
<div class="footer" style="clear: both; Margin-top: 10px; text-align: center; width: 100%;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td class="content-block" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; font-size: 12px; color: #999999; text-align: center;">
<span class="apple-link" style="color: #999999; font-size: 12px; text-align: center;">
<strong>You are receiving this email because you are a registered customer.</strong><br>
<br>
<strong>Imprint</strong><br>
Company Inc, Road, City ZIP-Code, Country<br>
Managing Director John Doe<br>
Commercial Register Local Court City &mdash; Commercial register HRB 4711<br>
Turnover tax ID no. 1234567890 &mdash; Tax number 123/123/12345<br>
</span>
<a href="##" style="text-decoration: underline; color: #999999; font-size: 12px; text-align: center;">Privacy-Policy</a>.<br>
</td>
</tr>
<tr>
<td class="content-block powered-by" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; font-size: 12px; color: #999999; text-align: center;">
powered by <a href="https://adilbo.com/" style="color: #999999; font-size: 12px; text-align: center; text-decoration: none;">adilbo</a>.
</td>
</tr>
</table>
</div>
<!-- END FOOTER -->
<!-- END CENTERED WHITE CONTAINER -->
</div>
</td>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
</tr>
</table>
</body>
</html>
<?php
/* ----------------------------------------------------------------------------------------------------------------------- */
/* [Send Mail] Use PHPMailer or PHP mail() function as fallback NEED logo.png, mail.tpl.htm & PHPMailer #php #class #email */
/* ----------------------------------------------------------------------------------------------------------------------- */
// SETUP
$config = array(
'emailSender' => 'pro@gaffling.com', // FROM (if PHPMailer = PHPMailerUsername)
'HTMLtemplate' => 'mail.tpl.htm', // HTML TEMPLATE NAME use [SUBJECT], [PREHEADER] & [BODY] as replace tag
'oneMailEveryXHours' => 1, // SEND MAIL MAX. EVERY X HOURS (0=don't use)
'usePHPMailer' => false, // PHPMAILER = true / PHP mail() = false
'PHPMailerSMTPhost' => 'smtp.gmail.com', // smtp.gmail.com
'PHPMailerSMTPSecure' => 'tls', // tls OR ssl
'PHPMailerPort' => 587, // 587=tls OR 465=ssl
'PHPMailerUsername' => 'pro@gaffling.com', // SMTP USERNAME (YOUR EMAIL ADRESS)
'PHPMailerPassword' => 'YOUR-SECRET-PASSWORD',// SMTP PASSWORD
'emoji' => '❌', // EMOJI FOR EMAIL SUBJECT ⚠️🔥🔔🚨📌📍❌
'DEBUG' => true, // NEVER SET TO true IN LIVE SYSTEME
);
// INI
use PHPMailer\PHPMailer\PHPMailer; // https://github.com/PHPMailer/PHPMailer
$send = new send($config);
$to = 'pro@gaffling.com'; // RECIPIENT ADDRESS OF THE EMAIL
$subject = 'Das ist ein Test'; // SUBJECT OF THE EMAIL
$message = '<h1>Headline</h1><p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p><p><a href="http://www.example.com/">www.example.com</a></p>'; // HTML CONTENT
$template = file_get_contents('email.tpl.htm', FALSE); // CONTENT OF THE HTML EMAIL TEMPLATE https://github.com/leemunroe/responsive-html-email-template
$dump = $send->mail($to, $subject, $message, $template);
// TEST OUTPUT
echo '<pre>';
echo var_dump($dump);
echo '</pre>';
class send {
public $config = null;
public function __construct($config) {
$this->config = $config;
}
public function mail($to, $subject, $message, $template='') {
// ini new line
$nl = PHP_EOL; // "\r\n"; # CHECK WHAT FITS FOR YOU
// ini return value
$status = false;
// ini session
if ( session_status() == PHP_SESSION_NONE ) session_start();
// ini flood protection
$name = str_replace('@', '', $to);
// FOR DEBUG ONLY
if ( isset($this->config['DEBUG']) && $this->config['DEBUG'] == TRUE ) {
$this->config['oneMailEveryXHours'] = 0;
$_SESSION[$name] = 0;
}
// check flood protection
if ( (time() - @$_SESSION[$name]) > (60*60*$this->config['oneMailEveryXHours']) or $this->config['oneMailEveryXHours'] == 0 ) {
// save mailtime for flood protection
$_SESSION[$name] = time();
// if template is given replace template placeholder
if ( $template != '' ) {
$template = str_replace('[SUBJECT]', $subject, $template);
$template = str_replace('[PREHEADER]', self::preheader($message), $template);
$template = str_replace('[BODY]', $message, $template);
$message = $template;
}
// parse template and message for images
preg_match_all('~<img.*?src=.([\/.a-z0-9:_-]+).*?>~si', $message, $matches);
$i = 0;
$paths = array();
// loop all found images
foreach ( $matches[1] as $img ) {
$img_old = $img;
// embedd only if its not an image from the web
if ( strpos($img, "http") == false ) {
// build path
$uri = parse_url($img);
$paths[$i]['path'] = __DIR__ . DIRECTORY_SEPARATOR . $uri['path']; // ####### CHECK IF THAT WILL WORK FOR YOU !!!!!!!
// build cid
$content_id = md5($img);
// replace image with cid in the template/message
$message = str_replace($img_old, 'cid:' . $content_id, $message);
// save cid for later user
$paths[$i]['cid'] = $content_id;
// next in the loop
++$i;
}
}
// SMTP mail by PHPMailer
if ( isset($this->config['usePHPMailer']) && $this->config['usePHPMailer'] == TRUE ) {
// FOR DEBUG ONLY
if ( isset($this->config['DEBUG']) && $this->config['DEBUG'] == TRUE ) {
$SMTPDebug = 3;
} else {
$SMTPDebug = 0;
}
// load extern classes
require_once 'PHPMailer/PHPMailer.php';
require_once 'PHPMailer/SMTP.php';
require_once 'PHPMailer/Exception.php';
// ini class
$mail = new PHPMailer();
// setup SMTP
$mail->IsSMTP();
$mail->SMTPAuth = true;
$mail->Host = $this->config['PHPMailerSMTPhost'];
$mail->SMTPSecure = $this->config['PHPMailerSMTPSecure'];
$mail->Port = $this->config['PHPMailerPort'];
$mail->Username = $this->config['PHPMailerUsername'];
$mail->Password = $this->config['PHPMailerPassword'];
// FOR DEBUG ONLY
$mail->SMTPDebug = $SMTPDebug; // 0 = DEBUG OFF & 3 = DEBUG ON
// set charset to utf8
$mail->CharSet = 'UTF-8';
// set sender email
$mail->From = $this->config['emailSender'];
// set sender name
$mail->FromName = 'Webmaster';
// set email subject
$mail->Subject = $this->config['emoji'] . ' ' . $subject;
// set boty to template with message
$mail->Body = $message;
// append the images
$mail->AltBody = self::html_to_text($message);
// set the recipient mail address and name
$mail->AddAddress($to, 'Webmaster');
// embedd images
$i = 0;
foreach ( $matches[1] as $img ) {
$mail->AddEmbeddedImage($paths[$i]['path'], $paths[$i++]['cid']);
}
// make clear that it is a HTML email
$mail->IsHTML(true);
// send SMTP mail
if ( $mail->Send() ) $status = true;
} else {
// use PHP mail() function as fallback
// see https://stackoverflow.com/a/32268272
// build header
$uniqid = md5(uniqid(time()));
// boundary
$boundary = "--==_mimepart_" . $uniqid;
// header
$header = 'From: ' . $this->config['emailSender'] . $nl;
$header .= 'Reply-To: ' . $this->config['emailSender'] . $nl;
$header .= 'Return-Path: ' . $this->config['emailSender'] . $nl;
$header .= 'Message-ID: <' . $uniqid . '@' . $_SERVER['SERVER_NAME'] . '>' . $nl;
$header .= 'Date: '.gmdate('D, d M Y H:i:s', time()) . $nl;
$header .= 'MIME-Version: 1.0'."\r\n";
$header .= 'Content-Type: multipart/related;' . $nl;
$header .= ' boundary=' . $boundary . ';' . $nl;
$header .= ' charset=UTF-8' . $nl;
$header .= 'X-Mailer: PHP/' . phpversion();
// build multipart
$multipart = '';
$multipart .= '--' . $boundary . $nl;
$multipart .= 'Content-Type: text/html; charset=UTF-8' . $nl;
$multipart .= 'Content-Transfer-Encoding: 7-bit' . $nl;
$multipart .= $message . $nl;
// replace images for inbound image
foreach ( $paths as $path ) {
// read file, if not exist or could not be opend - take next one
if ( file_exists($path['path']) ) {
$fp = fopen($path['path'], 'r');
if (!$fp) continue;
} else {
continue;
}
// get image type
$imagetype = strtolower(substr(strrchr($path['path'], '.' ), 1));
// read image
$file = fread($fp, filesize($path['path']));
fclose($fp);
// add image type to message part
$message_part = "";
switch ($imagetype) {
case 'png':
$message_part .= "Content-Type: image/png"; break;
case 'jpg':
case 'jpeg':
$message_part .= "Content-Type: image/jpeg"; break;
case 'gif':
$message_part .= "Content-Type: image/gif"; break;
}
// build message part for image
$message_part .= '; file_name = "' . $path['path'] . '"' . $nl;
$message_part .= 'Content-ID: <' . $path['cid'] . '>' . $nl;
$message_part .= 'Content-Transfer-Encoding: base64' . $nl;
$message_part .= 'Content-Disposition: inline; filename = "' . basename($path['path']) . '"' . $nl;
$message_part .= chunk_split(base64_encode($file)) . $nl;
$multipart .= '--' . $boundary . $nl . $message_part . $nl;
}
// close the build of the multipart message
$multipart .= '--' . $boundary.'--' . $nl;
// FOR DEBUG ONLY
if ( isset($this->config['DEBUG']) && $this->config['DEBUG'] == TRUE ) {
print('<pre>'.
'To: ' . $to . $nl .
'Subject: ' . $this->config['emoji'] . ' ' . $subject . $nl .
'Multipart: ' . $multipart.'<xmp>' .
'Text: ' . self::html_to_text($message).'</xmp>' .
'Header: ' . $header .
'</pre>'
);
}
// send multipart mail
if ( mail($to, $this->config['emoji'].' '.$subject, $multipart, $header) ) $status = true;
}
}
return $status;
}
private function html_to_text($string) {
// first remove the <head> we only need the <body>
$needle = array('<head', '</head>');
while(($pos = mb_stripos($string, $needle[0])) !== false) {
$aux = mb_substr($string, $pos + mb_strlen($needle[0]));
$string = mb_substr($string, 0, $pos).mb_substr($aux, mb_stripos($aux, $needle[1]) + mb_strlen($needle[1]));
}
$string = html_entity_decode($string); // change e.g. &amp; to &
$string = str_replace('>', '> ', $string); // add a space after each HTML tag
$string = strip_tags($string); // delete all HTML tags
$string = preg_replace('/\s+/', ' ', $string); // change double space and linebreak to one space
$string = preg_replace('/ \./', '.', $string); // change "space." to "."
$string = trim($string, ' '.chr(194).chr(160)); // trim all types of spaces
return $string;
}
private function preheader($string, $width=130) {
$string = self::html_to_text($string);
return strtok(wordwrap($string, $width, "...\n"), "\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment