Last active
February 20, 2020 12:05
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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;"> </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 — 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 — Commercial register HRB 4711<br> | |
Turnover tax ID no. 1234567890 — 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;"> </td> | |
</tr> | |
</table> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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. & 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