Last active
June 7, 2021 09:37
-
-
Save samuel-fonseca/ad0e9fd6ed66b33fe4d1aafcf190f60c to your computer and use it in GitHub Desktop.
A dynamic method to create HTML Emails and send them using PHPMailer XOAUTH2 with Gmail. This project is in no shape or form part of the PHPMailer project; I am simply using PHPMailer to send the emails because of their great project.
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 | |
/** | |
* Generate dynamic HTML emails | |
* | |
* @package Dynamic HTML PHPMailer builder | |
* @author Samuel Fonseca <[email protected]> | |
* @description Setup dynamic HTML emails using PHPMailer | |
*/ | |
/** | |
* NOTE: This class needs PHPMailer to work properly | |
* this is not an official extention, simply a test | |
* and a project which would hopefully help developers | |
* create dynamic HTML email bodies. | |
* I came up with the idea because I had a really hard | |
* time finding, and implementing a good solution. | |
* ----------- | |
* This software is made available as-is. I am not responsible as to | |
* how you use it. | |
*/ | |
/** | |
* I have no connection to PHPMailer | |
* All of PHPMailer's code is from their example | |
* find out more here: https://github.com/PHPMailer/PHPMailer | |
**/ | |
//Import PHPMailer classes into the global namespace | |
use PHPMailer\PHPMailer\PHPMailer; | |
use PHPMailer\PHPMailer\OAuth; | |
// Alias the League Google OAuth2 provider class | |
use League\OAuth2\Client\Provider\Google; | |
//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'); | |
//Load dependencies from composer | |
//If this causes an error, run 'composer install' | |
require 'vendor/autoload.php'; | |
class email | |
{ | |
/** | |
* @var $firstname will hold the recipient's first name | |
*/ | |
public $firstname = ''; | |
/** | |
* @var $lastname will hold the recipient's last name | |
*/ | |
public $lastname = ''; | |
/** | |
* @var $email will hold the recipient's email | |
*/ | |
public $email = ''; | |
/** | |
* @var $subject will hold the emails's subject | |
*/ | |
public $subject = ''; | |
/** | |
* @var $body will hold the HTML body content | |
*/ | |
public $body = ''; | |
/** | |
* @var $sender_name will hold the sender's email | |
*/ | |
public $sender_name = ''; | |
/** | |
* @var $sender_email will hold the sender's email | |
*/ | |
public $sender_email = ''; | |
/** | |
* @var $message will hold the message with responses | |
*/ | |
public $message = array(); | |
/** | |
* Construct function | |
* | |
* @param $firstname for recipient | |
* @param $lastname for recipient | |
* @param $email for recipient | |
* @param $subject for email | |
* | |
**/ | |
public function __construct( $firstname, $lastname, $email, $subject = '' ) | |
{ | |
$this->firstname = $firstname; | |
$this->lastname = $lastname; | |
$this->subject = $subject; | |
$this->email = $email; | |
} | |
/** | |
* set_sender function | |
* | |
* @param $name is the name of the sender (YOUR NAME) | |
* @param $email is the email of the sender (YOUR EMAIL) | |
*/ | |
public function set_sender($name, $email) | |
{ | |
$this->sender_name = $name; | |
$this->sender_email = $email; | |
} | |
/** | |
* | |
* Generate email | |
* | |
* @param $template_values will be an array with all the data | |
* @param $is_recurring boolean for us to know whether to add disclaimer (Donation only) | |
* @return boolean | |
**/ | |
public function generate( $template_values ) | |
{ | |
// setup email body with HTML features | |
// I included the `styling` here since it | |
// would be easier, but go wild with it | |
$this->body = "<html lang='en'> | |
<head> | |
<meta name='viewport' content='width=device-width,initial-scale=1.0'>" . /** set viewport for phone displays **/ . " | |
<title>" . $this->subject . "</title> | |
<style> | |
body{font-family:'Roboto',sans-serif;background-color:#f2f2f2}.header{background-color:#333;display:flex;position:relative;flex-direction:column;justify-content:space-between;width:40%;margin:auto;margin-left:auto;box-sizing:border-box;color:white;color:var(--mdc-theme-text-primary-on-primary, white)}.header img{margin-right:auto;margin-left:auto;width:35%}.text-centered{text-align:center}.content{z-index:10;width:40%;margin-left:auto;margin-right:auto; background-color:white; padding:15px;}.table{width:100%;margin-left:auto;margin-right:auto;padding:15px;background-color:#fff}@media only screen and (max-width: 850px){.header{width:100%}.content{width:100%}}p.copyright{text-align:center;background-color:#333;display:block;margin-top:0;color:#fff;padding:20px} | |
</style> | |
</head>"; | |
// if the content comes in an array the script | |
// will create a table which will hold the keys | |
// as well as the values beside each other | |
if ( is_array( $template_values ) ) | |
{ | |
$this->body .= "<body> | |
<div class='header mdc-elevation--z4'> | |
<h2 class='text-centered'>" . $this->subject . "</h2> | |
</div> | |
<div class='content'> | |
<table width='680' border='0' cellspacing='3' cellpadding='5' class='table mdc-elevation--z3'> | |
<tbody>"; | |
// create loop to get contents of array | |
foreach ( $template_values as $key => $value ) | |
{ | |
// make sure $value is not an array as well | |
if ( !is_array($value) ) | |
{ // <-- Need to break the content into sections | |
if ( empty($value) ) | |
{ | |
// we do not want any values that are empty | |
continue; | |
} | |
$this->body .= "<tr>"; | |
$this->body .= "<td>" . $key . "</td>"; | |
$this->body .= "<td>" . $value . "</td>"; | |
$this->body .= "</tr>"; | |
} | |
// if $value is an array then prepare to create new loop | |
else | |
{ | |
$this->body .= "<tr>"; | |
$this->body .= "<td colspan='2'><h3>" . $key . "</h3></td>"; | |
$this->body .= "</tr>"; | |
// loop through $value to get array content | |
foreach($value as $k => $val) | |
{ | |
if ( empty($val) ) | |
{ | |
// we do not want any values that are empty | |
continue; | |
} | |
$this->body .= "<tr>"; | |
$this->body .= "<td>" . $k . "</td>"; | |
$this->body .= "<td>" . $val . "</td>"; | |
$this->body .= "</tr>"; | |
} | |
} | |
} | |
$this->body .= "</table>"; | |
$this->body .= "</div>"; | |
$this->body .= "</body>"; | |
} | |
// if it's not an array, get the content | |
// and send it as HTML formatted text | |
else | |
{ | |
$this->body .= "<body> | |
<div class='header mdc-elevation--z4'> | |
<h2 class='text-centered'>" . $this->subject . "</h2> | |
</div> | |
<div class='content'>" | |
. $template_values . | |
"</div>"; | |
$this->body .= "</body>"; // <-- close `body` element | |
} | |
$this->body .= "</html>"; // <-- close `html` element | |
return true; // <-- email generated successfully | |
} | |
/** | |
* | |
* Send email | |
* | |
* @return $this->message | |
**/ | |
public function send() | |
{ | |
$mail = new PHPMailer; | |
$mail->isSMTP(); | |
//Enable SMTP debugging | |
// 0 = off (for production use) | |
// 1 = client messages | |
// 2 = client and server messages | |
$mail->SMTPDebug = 2; | |
$mail->Host = 'smtp.gmail.com'; | |
$mail->Port = 587; | |
$mail->SMTPSecure = 'tls'; | |
// OR | |
// $mail->Host = 'tls://smtp.gmail.com:587'; | |
/** AUTHENTICATION | |
* for security reasons I went with | |
* XOAUTH2 from Google, if you need | |
* setting it up look under their | |
* documentation: | |
* https://github.com/PHPMailer/PHPMailer/wiki/Using-Gmail-with-XOAUTH2 | |
**/ | |
$mail->SMTPAuth = true; | |
//Set AuthType to use XOAUTH2 | |
$mail->AuthType = 'XOAUTH2'; | |
//Fill in authentication details here | |
//Either the gmail account owner, or the user that gave consent | |
$email = '[email protected]'; // <-- your Google email | |
$clientId = 'YOUR_CLIENT_ID.apps.googleusercontent.com'; | |
$clientSecret = 'YOUR_CLIENT_SECRET'; | |
//Obtained by configuring and running get_oauth_token.php | |
//after setting up an app in Google Developer Console. | |
$refreshToken = 'YOUR_REFRESH_TOKEN'; | |
//Create a new OAuth2 provider instance | |
$provider = new Google( | |
[ | |
'clientId' => $clientId, | |
'clientSecret' => $clientSecret, | |
] | |
); | |
//Pass the OAuth provider instance to PHPMailer | |
$mail->setOAuth( | |
new OAuth( | |
[ | |
'provider' => $provider, | |
'clientId' => $clientId, | |
'clientSecret' => $clientSecret, | |
'refreshToken' => $refreshToken, | |
'userName' => $email, | |
] | |
) | |
); | |
// check for sender's name and email | |
if ( $this->sender_email == '' || $this->sender_name == '' ) | |
{ | |
$this->message = array("is_error" => 'danger', | |
"message" => "Sender name and email are required."); | |
return $this->message; | |
exit; | |
} | |
else | |
{ | |
//Set who the message is to be sent from | |
//For gmail, this generally needs to be the same as the user you logged in as | |
$mail->setFrom($this->sender_email, $this->sender_name); | |
} | |
//Set who the message is to be sent to | |
$mail->addAddress($this->email, $this->firstname . ' ' . $this->lastname); | |
//Set the subject line | |
$mail->Subject = $this->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->CharSet = 'utf-8'; | |
// body is set with generate | |
$mail->msgHTML( $this->body ); | |
//send the message, check for errors | |
if (!$mail->send()) { | |
$this->message = array("is_error" => 'danger', | |
"message" => "Mailer Error: " . $mail->ErrorInfo); | |
} else { | |
$this->message = array("is_error" => 'success', | |
"message" => "An email confirmation has been sent to " . $this->email . ". If there are any problems do not hesitate to contact us."); | |
} | |
return $this->message; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To call the function just set it up as: