Files
HotLunches/cronEmailSend.php
T
2026-10-19 15:22:52 -07:00

237 lines
7.5 KiB
PHP

<?php
$CurrentDomain = "hotlunches.net";
$BASEDIR = "/m/data1/app.$CurrentDomain";
$WORKDIR = "$BASEDIR";
chdir("$BASEDIR");
date_default_timezone_set("Canada/Pacific");
$timeNow = date("Hi",time());
if ($timeNow > "0205" && $timeNow < "0300") exit();
// Set max processing limits
$maxTime = 10 * 60 - 20;
$sleepTime = 10;
// Set start time
$timeNow = time();
$endTime = $timeNow + $maxTime;
$lockFile = "{$BASEDIR}/email.cron.lock";
if (file_exists($lockFile)) {
// cronjob is already running for this domain
// check the age of the lockfile... if it's more than 10 minutes old,
// the other cronjob probably crashed and we can ignore it
$t = filemtime($lockFile);
if (time() - $t > 60*10)
touch($lockFile);
else {
error_log("cronEmailSend.php ($CurrentDomain): skipped, lock held since " . date("Y-m-d H:i:s",$t));
exit();
}
}
else {
touch($lockFile);
}
// Ensure the lock is always released, even on a fatal error, uncaught
// exception, or execution timeout - otherwise one bad run permanently
// blocks the queue until the lock is removed by hand.
register_shutdown_function(function() use ($lockFile) {
@unlink($lockFile);
});
$ValidAccess = 2010;
include "$BASEDIR/include/globals.php";
// startLog("cronEmailSend");
// ---------- WILL BE A SERVER-WIDE SCRIPT ----------
if (!is_file("$BASEDIR/include/sendmail2.php")) {
echo("ERROR: $BASEDIR/include/sendmail2.php not found\n");
writeLog("ERROR: $BASEDIR/include/sendmail2.php not found");
@unlink($lockFile);
exit();
}
include "$BASEDIR/include/sendmail2.php";
// Open the log file
$today = date("Y-m-d",time());
$fp = fopen("$BASEDIR/logs/cron/$today.log","a");
fprintf($fp,"Start: %s\n",date("Y-m-d H:i:s",time()));
$logText = "";
$numSent = 0;
// Recover any rows left stuck in 'Processing' by a prior run that crashed
// or was killed before it could update their status (e.g. today's outage
// where the lock file was never released). Only touch rows old enough
// that they can't belong to a run that's still legitimately in progress.
$staleProcessingTime = time() - 60*10;
$query = "UPDATE email_queue SET status = 'Queued' " .
"WHERE status = 'Processing' AND processing_start_time < $staleProcessingTime";
writeLog($query);
db_query($query);
writeLog("timeNow: $timeNow");
writeLog("endTime: $endTime");
// Loop until end processing time
while ($timeNow < ($endTime - $sleepTime * 5)) {
writeLog("endTime: $endTime");
// Exit when MySQL is being backed up
$currentTime = date("Hi",time());
if ($currentTime > "0210" && $currentTime < "0230") exit();
// Get set of queued messages
db_query("START TRANSACTION");
$query = "SELECT * FROM email_queue " .
"WHERE status = 'Queued' " .
"AND delay < 15 " .
"ORDER BY delay,posted_time,record_num LIMIT 0,50";
writeLog($query);
$results = db_query($query);
// Get the messages
$Messages = array();
$RecordNums = array();
if ($results && db_num_rows($results)) {
$processing_start_time = time();
while ($row = db_fetch_assoc($results)) {
$Messages[] = $row;
$RecordNums[] = $row['record_num'];
}
$currentRecords = implode(",", $RecordNums);
$query = "UPDATE email_queue " .
"SET status = 'Processing', " .
"processing_start_time = $processing_start_time " .
"WHERE record_num IN ($currentRecords)";
writeLog($query);
db_query($query);
}
db_query("COMMIT");
writeLog("Count Messages: ".count($Messages));
if (count($Messages) > 0) {
$errorNums = array();
// Process each message
for ($i = 0; $i < count($Messages); $i++) {
$row = $Messages[$i];
extract($row);
// Set status and processing start time
// $processing_start_time = time();
// db_query("UPDATE email_queue SET status = 'Processing', processing_start_time = $processing_start_time WHERE record_num = $record_num");
// Convert attachments to an array
if (strlen($attachments)) {
$files = explode("\n",$attachments);
$attachments = $files;
}
else {
$attachments = array();
}
$email_subject = htmlspecialchars_decode($email_subject,ENT_QUOTES);
$email_subject = preg_replace("#&amp;#","&",$email_subject);
$email_message = htmlspecialchars_decode($email_message,ENT_QUOTES);
$email_message = preg_replace("#&amp;#","&",$email_message);
writeLog("email_subject: $email_subject");
// Send email
try {
$sendOk = SendEmail($email_to, $email_from, $email_subject, $email_message, $email_from_name, $email_to_name, $attachments, $template_file);
}
catch (Exception $e) {
$sendOk = false;
error_log("cronEmailSend.php ($CurrentDomain): SendEmail exception for record $record_num: " . $e->getMessage());
}
if ($sendOk) {
$status = 'Sent';
$numSent++;
}
else {
$status = 'Error';
$errorNums[] = $record_num;
}
writeLog("status: $status");
// Update status
$priority = $delay;
// Print status message
$logText .= sprintf("%s %5s to %s from %s (%s) - %s\n",$processing_end_date_time,
$status,
$email_to,
$email_from,
$template_file,
$email_subject." ($priority)");
$timeNow = time();
if ($timeNow > $endTime) break;
}
$processing_end_time = time();
$processing_end_date_time = date("Y-m-d H:i:s",$processing_end_time);
$delay = $processing_end_time - $posted_time;
// Only mark the records that actually sent successfully as 'Sent'
$sentNums = array_diff($RecordNums, $errorNums);
writeLog("Count sentNums: ".count($sentNums));
if (count($sentNums)) {
$sentRecords = implode(",", $sentNums);
$query = "UPDATE email_queue SET status = 'Sent', " .
"processing_end_time = $processing_end_time, " .
"processing_end_date_time = '$processing_end_date_time', " .
"delay = $delay " .
"WHERE record_num IN ($sentRecords)";
writeLog($query);
db_query($query);
}
if (count($errorNums)) {
$errorRecords = implode(",", $errorNums);
$query = "UPDATE email_queue SET status = 'Error', " .
"processing_end_time = $processing_end_time, " .
"processing_end_date_time = '$processing_end_date_time' " .
"WHERE record_num IN ($errorRecords)";
writeLog($query);
db_query($query);
}
}
sleep($sleepTime);
$timeNow = time();
fprintf($fp, $logText);
$logText = '';
// fprintf($fp,"-\n");
}
@unlink($lockFile);
if ($numSent > 0) {
// Check for more queued messages
$query = "SELECT count(*) FROM email_queue " .
"WHERE status IN ('Queued','Processing')";
$count = db_getVal($query);
fprintf($fp,"\n");
fprintf($fp,"Emails Sent: $numSent\n");
fprintf($fp,"Queued Messsages: $count\n");
}
fprintf($fp,"End: %s\n\n-------------------------------------------\n",date("Y-m-d H:i:s",time()));
?>