<?php
//require 'dbConnection.php'; //database connection script with mysql_connect and mysql_select_db
/**
* class to mail shot a group of people
*
* @example
* <code>
* $mailer = NEW listMailer();
* if (isset($_GET['action']) && $_GET['action'] == 'getImage'){
* if (!empty($_GET['id']) && !empty($_GET['email'])){
* $mailer->track($_GET['uid'], 'mail opened', $_GET['email']);
* }
* }
* $text = 'I am a text based version of the email';
* $html = '<body><h2>Hello World</h2><p>I am an html version of the email</p>{TRACK}</body>';
* $subject = 'New Email';
* $mailer->setMessageInfo($subject, $text, $html);
* $mailer->sendToList();
* </code>
*/
$mailer = new listMailer();
class listMailer{
/**
* method to construct the object
*
* this method sets all the variables that are used in the class.
* these properties/variables are predominanly user settable
*/
public function listMailer(){
/*
* database level variables
*/
$this->dbTable = ''; //the table where the email addresses are to be found
$this->nameCol = ''; // the table column in which the actual names of the recipients are to be found
$this->emailCol = ''; //the table column in which the email addresses will be found
/*
* mail server information
*/
$this->smtpHost = ''; //host name or IP address of the SMTP server.
/*
* other application level variables
*/
$this->logging = true; //set to false for no logging
$this->loggingTable = 'listmailerlogtable'; //this does not need to exist. if it does not it will be created.
$this->pauseTime = 10; //seconds to pause between email blocks
$this->numEmailsinBlock = 20; //number of emails to send per block
$this->fromAddress = ''; //the email address that the mail should be sent from
$this->fromName = '';//the name of the sender
/*
* perform some internal checks
*/
if (!$this->checkLogging()){
$this->createLoggingTable();
}
}
/**
* method to set the html and non-html etc variables for the mail shot
*
* @return void
* @param $subject string - the subject of the email
* @param $text string - the text body of the email
* @param $html string [optional] - formed html body of the email
*/
public function setMessageInfo($subject, $text, $html=null){
$this->textBody = $text;
$this->htmlBody = $html;
$this->subject = $subject;
}
/**
* method to perform the mail shot
*
* @return void
*/
public function sendToList(){
if (empty($this->text)) die ('You must set at least a plain text message');
if (empty($this->subject)) die ('You must set a subject for the message');
//get email recipients
$this->getRecipients();
//get count of recipients
$count = count($this->getRecipients);
//get the phpmailer class
require_once("class.phpmailer.php");
//create an outer loop
$i = 0;
//initialise the phpmailer
$mail = new PHPMailer();
//set some common variables
$mail->From = $this->fromAddress;
$mail->FromName = $this->fromName;
$mail->Host = $this->smtpHost;
$mail->Mailer = "smtp";
$mail->Subject = $this->subject;
while ($i<$count){
//reset the timeout counter
set_time_limit(60 + $this->pauseTime);
for ($c=0; $c < $this->numEmailsinBlock; $c++){
if ($i >= $count) break;
list($pixel, $uid) = $this->getTrackingPixel($this->emailRecipients[$i][1]);
if (empty($this->htmlBody)){
$mail->Body = $this->textBody;
} else {
$mail->isHTML(true); //set to html
$mail->Body = str_replace('{TRACK}', $pixel, $this->htmlBody);
$mail->AltBody = $this->textBody;
}
$mail->Body = $this->htmlBody . $pixel;
$mail->AddAddress($this->emailRecipients[$i][1], $this->emailRecipients[$i][0]);
if($mail->Send()){
$this->log($uid, 'sent', $this->emailRecipients[$i][1] );
} else {
$this->log($uid, 'error', $this->emailRecipients[$i][1] );
}
echo "$i {$this->emailRecipients[$i][1]} <br/>";
$i++;
// Clear all addresses and attachments for next loop
$mail->ClearAddresses();
} //close the inner loop
sleep($this->pauseTime);
} //close the outer loop
echo 'process complete. See the log for details of errors etc';
}
/**
* method for logging the opening of an email
*
* @return
* @param $uid string - the unique identifier logged in the email
* @param $event string - the event message
* @param $email string - the email address
*/
public function track($uid, $event, $email){
$this->log($uid, $event);
$this->deliverPixel();
}
/**
* method to create the logging table if it does not already exist
*
* @return
*/
private function createLoggingTable(){
$sql = <<<HTML
CREATE TABLE
IF NOT EXISTS
{$this->loggingTable}
(
logID int(11) NOT NULL AUTO_INCREMENT ,
logEmail varchar(255) NOT NULL,
logUniqueID varchar(255) NOT NULL,
logEvent varchar (10) NOT NULL,
logTime int(16) NOT NULL
)
PRIMARY KEY logID
HTML;
echo $sql;
mysql_query($sql) or die (mysql_error());
}
/**
* method to determine whether the logging table has already been created
*
* @return
*/
private function checkLogging(){
if ($this->logging){
$query = "show tables where name='{$this->loggingTable}'";
$result = mysql_query($query);
if (mysql_num_rows($result) === 1){
return true;
} else {
return false;
}
}
}
/**
* method to obtain the html to embed the tracking pixel
*
* @return void
*/
private function getTrackingPixel($email){
if($this->logging){
$uid = $better_token = md5(uniqid(rand(), true));
$url = "[URL unfurl="true"]http://".[/URL] $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] . "?id=$uid&action=getImage&email=$email";
$html = <<<HTML
<img width="1px" height="1px" src="{$url}" alt="tracking"/>
HTML;
return array($html, $uid);
} else {
return array('','');
}
}
/**
* method to obtain all the recipients of the mailshot in an object property
*
* @return
*/
private function getRecipients(){
$sql = "Select {$this->nameCol}, {$this->emailCol} from {$this->dbTable}";
$results = mysql_query($sql) or die (mysql_error());
//create holding variable
$this->emailRecipients = array(); //
while ($this->emailRecipients[] = mysql_fetch_array($result, MYSQL_NUM)){
//do nothing
}
}
/**
* method to log data
*
* @return void
* @param $uniqueID string - the unique ID associated with the email recipient for this mailshot.
* @param $event string - text to be logged
* @param $emailAddress string - email address of recipient
*/
private function log($uniqueID, $event, $emailAddress){
if ($this->logging){
$params = array($emailAddress, $uniqueID, $event, time());
$params = array_walk($params, 'mysql_real_escape_string');
$sql = "insert into {$this->loggingTable}
(logID, logEmail, logUniqueID, logEvent, logTime)
VALUES
(NULL, '%s', '%s', '%s', '%s');";
mysql_query(vsprintf($sql, $params));
}
}
/**
* method to deliver the actual pixel image so we don't get a broken image on the email.
* @return void
*/
private function deliverPixel(){
if (!file_exists('pixel.png')){
$this->createPixel();
}
//send some no cacheing headers
header( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Cache-Control: post-check=0, pre-check=0', false );
header( 'Pragma: no-cache' );
header('Content-Length: '.filesize('pixel.png'));
header('Content-Type: image/png');
readfile('pixel.gif');
exit();
}
/**
* method to create a transparent png pixel image if one has not already been created
*
* @return void
*/
private function createPixel(){
$pixel = imagecreatetruecolor(1, 1);
imagesavealpha($pixel, true);
$trans_colour = imagecolorallocatealpha($pixel, 0, 0, 0, 127);
imagefill($pixel, 0, 0, $trans_colour);
//now save the image
imagepng($pixel, 'pixel.png');
}
}
?>