<?php 
/*
SEND NEWSLETTER/EMAILS THROUGH AJAX REQUEST.
DEVELOPER: STEVE CURRY
MAY 26, 2009
*/

// Increase session timeout.
@ini_set('session.gc_maxlifetime','28800');
set_time_limit(0);
session_start();

require 'configuration.php';
require_once 'includes/common.functions.php';
require_once ('classes/database.php');
require_once ('classes/functions.php');
$sqlObj = new mysqlClass;
$funcObj = new funcClass;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require 'PHPMailer/vendor/autoload.php';
/*
TRACK FIELDS EMAILS
*/

if (!isset($_SESSION['TRACKFAILEDEMAILS']) || $_GET['startfrom'] == 1)
{
	$_SESSION['TRACKFAILEDEMAILS'] = 0;
	$_SESSION['TOTAL_EMAIL_ROWS'] = 0;
}

$id	= intval(isset($_GET['id']) ? $_GET['id'] : '');
$startFrom	= intval(isset($_GET['startfrom']) ? $_GET['startfrom'] : '');
$threads	= intval(isset($_GET['threads']) ? $_GET['threads'] : '');
$dbFailed	= intval(isset($_GET['totalfailed']) ? $_GET['totalfailed'] : '');

if (isset($_GET['totalfailed']))
{
	// update the database
	$query = "UPDATE ##campaigns SET IS_SENT='1', FAILED_EMAILS = '".$dbFailed."', DATE_SENT=NOW() WHERE ID = '{$id}'"; 
	@$funcObj->updateQuery($query);
	exit;		
}

$sqlStart	= $startFrom - 1;

if (empty($startFrom) || empty($id) || empty($threads))
{
	echo '{';
	echo "'systemerror' : 'Required Parameter Missing'";
	echo '}';
	exit;
}

#### FETCH DEFAULT SMTP#########
$query = "SELECT *	FROM ##smtp WHERE `DEFAULT` = '1'";
$resultSetSMTP = array();
$resultSetSMTP = $funcObj->CustomQuery($query);
if (count($resultSetSMTP))
{
	if ($resultSetSMTP[0]['MAILER_TYPE'] == 'smtp')
	{
		$defHOST 		= $resultSetSMTP[0]['HOST'];
		$defPORT 		= $resultSetSMTP[0]['PORT'];
		$defUSER 		= $resultSetSMTP[0]['USER'];
		$defPassword	= base64_decode(base64_decode($resultSetSMTP[0]['PASSWORD']));
		$defAuth		= ($resultSetSMTP[0]['AUTHENTICATION'] == '1') ? 'true' : 'false';
	}
}
else
{
	echo '{';
	echo "'systemerror':'No default SMTP found'";
	echo '}';
	exit;
}
##### END OF SMTP SETUP#########################

###FETCH ACTIVE ADDRESSBOOK(S)########################
$query = "SELECT A.ID AS CAMPAIGNID 
FROM ##addressbook AS A,
##campaign_send_stats AS B
WHERE B.ADDR_ID = A.ID
AND B.SESSION_ID = '".session_id()."'
AND B.CAMPAIGN_ID = '{$id}'";
$AddrResultSet = array();
$AddrResultSet = $funcObj->CustomQueryArray($query);

$campIds = array();
foreach($AddrResultSet as $row)
{
	$campIds[] = $row['CAMPAIGNID'];
}
$campIdsStr = implode(",", $campIds);
######################################################

########## 	calculate total row and store that into SESSION	for faster retrieval####
if (empty($_SESSION['TOTAL_EMAIL_ROWS']) || $_SESSION['TOTAL_EMAIL_ROWS'] == '0') 
{
	$query = "SELECT COUNT(DISTINCT(EMAIL)) AS TOTAL FROM ##contacts WHERE ADDR_ID IN ($campIdsStr) AND IS_DELETED = 0";
	$resultCampIds = $funcObj->CustomQuery($query);
	$_SESSION['TOTAL_EMAIL_ROWS'] = $resultCampIds[0]['TOTAL'];
	$total = $resultCampIds[0]['TOTAL'];
}
else
{
	$total = $_SESSION['TOTAL_EMAIL_ROWS'];
}

$query = "SELECT DISTINCT(EMAIL), FIRSTNAME, LASTNAME, MISC_1, MISC_2, MISC_3 FROM
##contacts WHERE ADDR_ID IN ($campIdsStr) AND IS_DELETED = 0 ORDER BY EMAIL ASC
LIMIT {$sqlStart}, {$threads}";
$contactsResultSet = array();
$contactsResultSet = $funcObj->CustomQueryArray($query);

$nextStart = intval($startFrom) + intval($threads);
$percentage = floor((($nextStart-1)/$total) * 100);

$failedEmails = array();

$query = "SELECT FROM_NAME, FROM_EMAIL, REPLYTO_NAME, REPLYTO_EMAIL, SUBJECT, CONTENTS, CONTENTSPLAIN FROM ##campaigns WHERE ID = '$id'";
$resultSet = array();
$resultSet = $funcObj->CustomQuery($query);

/* Update the newsletter content 
by replacing the MARKERS with the 
actual values
*/

$sent 		= 0;
$success 	= 0;
$failed 	= 0;
$iStart 	= 0;
foreach ($contactsResultSet as $rowContactsResultSet)
{
	$contents = "";
	$liveContent = "";
	$contentsPlain = "";
	$liveContentPlain = "";

	$contents = $resultSet[0]['CONTENTS'];
	$code = sha1($id); 
	$hash = sha1($rowContactsResultSet['EMAIL']);
	
	$forwardStr 	= '';
	$forwardStr 	= $id . ';' . $rowContactsResultSet['FIRSTNAME'] . ' ' . $rowContactsResultSet['LASTNAME'] . ';' . $rowContactsResultSet['EMAIL'];
	$forwardStr		= base64_encode($forwardStr);
	
	$replaceContent = array(
	'$UNSUB$' 		=> $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&hash={$hash}&action=unsubscribe&friend=0&redirect=",
	'$CANTREAD$' 	=> $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&code={$code}&action=cantread&friend=0&redirect=",
	'$LINKTRACK$' 	=> $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&action=track&friend=0&redirect=",	 
	'$FORWARD$' 	=> $absPath . "/forward.php?id={$forwardStr}",
	'@EMAIL@' 		=> $rowContactsResultSet['EMAIL'], 
	'@FIRSTNAME@' 	=> $rowContactsResultSet['FIRSTNAME'],	 
	'@LASTNAME@'	=> $rowContactsResultSet['LASTNAME'],	 
	'@MISC_1@' 		=> $rowContactsResultSet['MISC_1'], 
	'@MISC_2@' 		=> $rowContactsResultSet['MISC_2'], 
	'@MISC_3@' 		=> $rowContactsResultSet['MISC_3'],
	'</html>'		=> "</html><div style='display:none'><img src='" . $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&action=view&friend=0&redirect=''/></div>"
	);
	
	$liveContent = $funcObj->replaceAll($replaceContent, $contents);


	$contentsPlain = $resultSet[0]['CONTENTSPLAIN'];
	
	$replaceContent2 = array(
	'$UNSUB$' 		=> $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&hash={$hash}&action=unsubscribe&friend=0&redirect=",
	'$CANTREAD$' 	=> $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&code={$code}&action=cantread&friend=0&redirect=",
	'$LINKTRACK$' 	=> $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&action=track&friend=0&redirect=",	 
	'$FORWARD$' 	=> $absPath . "/forward.php?id={$forwardStr}",
	'@EMAIL@' 		=> $rowContactsResultSet['EMAIL'], 
	'@FIRSTNAME@' 	=> $rowContactsResultSet['FIRSTNAME'],	 
	'@LASTNAME@'	=> $rowContactsResultSet['LASTNAME'],	 
	'@MISC_1@' 		=> $rowContactsResultSet['MISC_1'], 
	'@MISC_2@' 		=> $rowContactsResultSet['MISC_2'], 
	'@MISC_3@' 		=> $rowContactsResultSet['MISC_3']
	);
	
	$liveContentPlain = trim($funcObj->replaceAll($replaceContent2, $contentsPlain));
	
	if (empty($liveContentPlain))
	{
		$liveContentPlain = 'To view the message, please use an HTML compatible email viewer!';
	}	
	
	############## SEND EMAIL ##############
	//require_once('classes/class.phpmailer.php');
	//$mail             = new PHPMailer(); // defaults to using php "mail()"

	$mail = new PHPMailer(true);
	if ($resultSetSMTP[0]['MAILER_TYPE'] == 'smtp')
	{
		$mail->IsSMTP();  //SMTP IS DOWN SO SEND EMAILS THROUGH SENDMAIL INSTEAD.
		//$mail->IsSendmail(); // telling the class to use SendMail transport 				
		$mail->SMTPAuth   = $defAuth; 
		if($defPORT == 465){
			$mail->SMTPSecure = 'ssl';
		}else{
			$mail->SMTPOptions = array(
			'ssl' => array(
				'verify_peer' => false,
				'verify_peer_name' => false,
				'allow_self_signed' => true
			)
		);
	
		}
		
		//$mail->SMTPSecure = "ssl"; 
		if (!empty($bounceEmail))
		{
			//$mail->Sender = $bounceEmail; 
		}	
		$mail->Host       = $defHOST;   
		$mail->Port       = $defPORT;   
		$mail->Username   = $defUSER;  
		$mail->Password   = $defPassword;
		
	}
	else if ($resultSetSMTP[0]['MAILER_TYPE'] == 'sendmail')
	{
		$mail->IsSendmail(); // telling the class to use SendMail transport
	}
	else
	{
		// no need to do anything.
		// phpmailer will use the default mail() function.
	}
	
	
	if (empty($resultSet[0]['REPLYTO_EMAIL']))
	{
		$mail->AddReplyTo($resultSet[0]['FROM_EMAIL'], $resultSet[0]['FROM_NAME']);
	}
	else
	{
		if (empty($resultSet[0]['REPLYTO_NAME']))
			$mail->AddReplyTo($resultSet[0]['REPLYTO_EMAIL']);
		else
			$mail->AddReplyTo($resultSet[0]['REPLYTO_EMAIL'], $resultSet[0]['REPLYTO_NAME']);
	}
	
	$mail->SetFrom($resultSet[0]['FROM_EMAIL'], $resultSet[0]['FROM_NAME']);
	
	## do not add invalid email address otherwise it will error out
	## if the address is invalid (invalid format) then add a valid format
	## address. This is just a dummy addresses the system won't send email
	## at this address.
	if (!validate_email ($rowContactsResultSet['EMAIL']))
	{
		$mail->AddAddress('testaddress@test.com', 'Test User');
	}	
	else
	{
		$mail->AddAddress($rowContactsResultSet['EMAIL'], $rowContactsResultSet['FIRSTNAME'] . ' ' . $rowContactsResultSet['LASTNAME']);
	}	

		
	/* 23-02-2015 //replace macros with original content
	
	$mail->Subject    	= $resultSet[0]->SUBJECT;
	*/
	$replaceContent3 = array(
	'$UNSUB$' 		=> $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&hash={$hash}&action=unsubscribe&friend=0&redirect=",
	'$CANTREAD$' 	=> $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&code={$code}&action=cantread&friend=0&redirect=",
	'$LINKTRACK$' 	=> $trackURL . "?email={$rowContactsResultSet['EMAIL']}&camid={$id}&action=track&friend=0&redirect=",	 
	'$FORWARD$' 	=> $absPath . "/forward.php?id={$forwardStr}",
	'@EMAIL@' 		=> $rowContactsResultSet['EMAIL'], 
	'@FIRSTNAME@' 	=> $rowContactsResultSet['FIRSTNAME'],	 
	'@LASTNAME@'	=> $rowContactsResultSet['LASTNAME'],	 
	'@MISC_1@' 		=> $rowContactsResultSet['MISC_1'], 
	'@MISC_2@' 		=> $rowContactsResultSet['MISC_2'], 
	'@MISC_3@' 		=> $rowContactsResultSet['MISC_3'],
	);
	$mail->Subject    	= trim($funcObj->replaceAll($replaceContent3, $resultSet[0]['SUBJECT']));
	
	$mail->AltBody 		= $liveContentPlain;
	
	//$mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
	
	$mail->MsgHTML($liveContent);
	
	// Only send email if the email address is valid.
	if (!validate_email ($rowContactsResultSet['EMAIL']))
	{
		$failedEmails[] = $rowContactsResultSet['EMAIL'];
		
		$_SESSION['TRACKFAILEDEMAILS'] = (intval($_SESSION['TRACKFAILEDEMAILS']) + 1);
		$failed++;
		
		$query = "INSERT INTO ##report SET CAMPAIGN_ID='$id', EMAIL='".$rowContactsResultSet['EMAIL']."', USER_IP='', BROWSER='', 
		OS='', PLATFORM='', ACTION='hardbounce', REDIRECT_URL='', IS_FRIEND = '0', DATE_TIME=NOW()";
		$insertId = $funcObj->insertQuery($query);
		
	}
	else 
	{
		
		  if(!$mail->Send()) 
		  {
			  /*
			  If the error is on the very first record probably the error is 
			  in SMTP setup.
			  Return with error message.
			  */
			  if ($iStart == 0)
			  {
				echo '{';
				echo "'systemerror':'Unable to send emails. Please check your SMTP'";
				echo '}';
				exit;
			  }
			  else
			  {
				$failedEmails[] = $rowContactsResultSet['EMAIL'];
				// Insert the failed email address (hard bounce email) into the database.
				$query = "INSERT INTO ##report SET CAMPAIGN_ID='$id', EMAIL='".$rowContactsResultSet['EMAIL']."', USER_IP='', BROWSER='', 
				OS='', PLATFORM='', ACTION='hardbounce', REDIRECT_URL='', IS_FRIEND = '0', DATE_TIME=NOW()";
				$insertId = $funcObj->insertQuery($query);

			  }
			  $failed++;
			  $_SESSION['TRACKFAILEDEMAILS'] = (intval($_SESSION['TRACKFAILEDEMAILS']) + 1);
		  } 
		  else 
		  {
			  $success++;
		  }
	}	
	
	############ END OF SEND MAIL###############
	$iStart++;
}

/* AS SOON AS THE PERCENTAGE IS >= 100)
MARKS THE CAMPAIGN AS SENT */

if ($percentage >= 100)
{
	/**
	 * Update the Database and mark the campaign as SENT
	 */
	$query = "UPDATE ##campaign_send_stats SET DATE_SENT =NOW() WHERE CAMPAIGN_ID = '{$id}' AND SESSION_ID = '".session_id()."'"; 
	@$funcObj->updateQuery($query);	
	
	$query = "UPDATE ##contacts SET IS_USED	= '1' WHERE ADDR_ID IN ($campIdsStr)"; 
	@$funcObj->updateQuery($query);
	
	/**
	 * Remove the session variable after sending all emails.
	 */
	unset($_SESSION['TRACKFAILEDEMAILS']);
	unset($_SESSION['TOTAL_EMAIL_ROWS']);
}

$failedEmailsStr = implode(",", $failedEmails);
echo '{';
echo "'start' 		: '$nextStart',\n";
echo "'success'		: '$success',\n";
echo "'percentage' 	: '$percentage',\n";
echo "'failed'		: '$failed',\n";
echo "'checkparam'	: '$total',\n";
echo "'failedEmails': '$failedEmailsStr'\n";
echo '}';
?>
