As we saw in part 1, I was experiencing timeouts on scripts that sent a large number of legitimate messages out from php mailer. This appeared to be related to the web hosting company throttling the email rate. To still be able to send these messages out a setup was required that would allow messages to be released in smaller batches. Part 1 saw the setup of this script. Now we cover the script that will be used to send the mail out, and how to produce a simple report that shows messages in the queue.

Firstly we will cover the mailing script. This I called mailer.php and is called every 10 minutes by a cron timer.

<? 
	/* Include database information.*/
	include("inc/config.php"); 
	
	/* 
	* Mailer Script. 
	* This script will retrieve queued messages from the database and send them in batches.
	* Please set the batch number to determin how many messages are sent in one go.
	*/
	
	/* Variables */
	$process_count = 50; //The number of messages to process in one batch
	
	/* Now we get the queued emails from the database. Order by oldest first. */
	$sql = "SELECT * FROM  `email_queue` WHERE `status` = 'queued' ORDER BY  `submission_date` ASC LIMIT $process_count ";
	$results = mysql_query($sql)
		or die($error = "Error getting queued messages.");
		
	/* For each result that is extracted from the database. Attempt to send the email. */
	while($row = mysql_fetch_array($results)){
		/* Attempt to send the message. If successful update the database. */
		if(mail($row['recipient'], stripslashes($row['subject']), stripslashes($row['message']), stripslashes($row['headers']))) {
			/* If successful generate the SQL to update the database. */
			$sql = "UPDATE `email_queue` SET `status` =  'sent', `sent_date` = '" .strtotime("now") ."' WHERE  `id` = '" .$row['id'] ."' ";
			$results2 = mysql_query($sql)
				or die($error = "Error updating holding table. ");
		} 
	} //while getting results
	
	/* Display progress*/
	if(isset($error)) {
		echo $error; //if the error variable is set, display the message
	} else {
		echo "OK.";
	} //if else display status
?>

So with that running correctly, every 10 minutes 50 emails should be sent out, and the database updated.

Now it would be nice to be able to see what messages are waiting. The webpage below is written in HTML and PHP and pulls the queued messages from the database and displays them in a simple table.

<? include("inc/auth.php"); ?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title><? echo $site_name; ?> Report</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link type="text/css" rel="stylesheet" href="inc/cms.css">
</head>

<body class="body">
<? include("inc/header.php"); ?>
<? include("inc/menu.php"); ?>
    <?
		/****************************
		* Get the information from the database.
		*****************************/
		$sql = "SELECT * FROM  `email_queue` WHERE `status` = 'queued' ORDER BY  `submission_date` ASC ";
		$results = mysql_query($sql)
			or die("Error Getting Queued Email List.");
	?>
    <!-- Display the information in a table -->
    <table width="50%" border="0" align="center">
      <tr>
        <td><font size="-1"><b>Sent Date</b></font></td>
        <td><font size="-1"><b>Recipient</b></font></td>
        <td><font size="-1"><b>Subject</b></font></td>
        <td><font size="-1"><b>Status</b></font></td>
      </tr>
      <?
	  	while($row = mysql_fetch_array($results)) {
			echo "<tr>";
				echo "<td><font size=\"-1\">" .date("d-m-Y", $row['submission_date']) ."</a></font></td>";
				echo "<td><font size=\"-1\">" .stripslashes($row['recipient']) ."</a></font></td>";
				echo "<td><font size=\"-1\">" .stripslashes($row['subject']) ."</font></td>";
				echo "<td><font size=\"-1\">" .ucwords(stripslashes($row['status'])) ."</font></td>";
			echo "</tr>\n";
		} //while display results
	  ?>
    </table>
</body>
</html>

That completes this series. The first part was used to redirect email into the holding database table, then this part extracted a batch of emails and sent them out using a cron job every 10 minutes.