Your IP : 216.73.217.79


Current Path : /var/www/cesa.co.za/crons/
Upload File :
Current File : /var/www/cesa.co.za/crons/sendlater.php

<?php

// No longer used - use ToSendProcess.php instead
exit;

//if ($_GET["override"] != 1) die();

ini_set('max_execution_time', '0'); // 0 = no limit
ini_set('display_errors', 1);
error_reporting(E_ALL);
ob_start();

$maxmsgs = 20;
$loopMax = 10;

if (!isset($_SERVER['DOCUMENT_ROOT']) || strlen($_SERVER['DOCUMENT_ROOT']) <= 0) {
    $_SERVER['DOCUMENT_ROOT'] = str_replace('/crons', '', getcwd());
}

// Check if process is running
$lockFile = $_SERVER['DOCUMENT_ROOT'] . '/crons/ToSendProcess.lock';
if (file_exists($lockFile)) {
    echo "Process already running. Exiting.\n";
    exit;
}
file_put_contents($lockFile, time());

// echo $_SERVER['DOCUMENT_ROOT'];
// exit;

include_once($_SERVER['DOCUMENT_ROOT'] . "/cfg/config.php");
include_once($_SERVER['DOCUMENT_ROOT'] . "/php/includes/maill.php");
include_once($_SERVER['DOCUMENT_ROOT'] . "/php/includes/ErrorLog.php");

/**
 * Format and validate a list of email addresses
 * Handles comma, semicolon, and space-separated lists
 * Returns formatted comma-separated list of valid emails, or false if none valid
 * 
 * @param string $emailList The email list string
 * @return string|false Formatted email list or false if no valid emails
 */
function formatEmailList($emailList) {
    if (empty($emailList)) {
        return false;
    }
    
    // Normalize separators: replace semicolons and multiple spaces with commas
    $emailList = str_replace(array(';', "\r\n", "\r", "\n", "\t"), ',', $emailList);
    // Replace multiple commas with single comma
    $emailList = preg_replace('/,+/', ',', $emailList);
    // Split by comma
    $emails = explode(',', $emailList);
    
    $validEmails = array();
    $invalidEmails = array();
    
    foreach ($emails as $email) {
        $email = trim($email);
        if (empty($email)) {
            continue;
        }
        
        // Extract email from "Name <email@domain.com>" format if present
        if (preg_match('/<(.+?)>/', $email, $matches)) {
            $email = trim($matches[1]);
        }
        
        // Validate email
        if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
            // Remove duplicates (case-insensitive)
            $emailLower = strtolower($email);
            if (!isset($validEmails[$emailLower])) {
                $validEmails[$emailLower] = $email;
            }
        } else {
            $invalidEmails[] = $email;
        }
    }
    
    // Log invalid emails if any
    if (!empty($invalidEmails)) {
        ErrorLog::logError("Invalid email addresses found in list: " . implode(', ', $invalidEmails));
    }
    
    // Return formatted list or false if no valid emails
    if (empty($validEmails)) {
        return false;
    }
    
    return implode(', ', array_values($validEmails));
}

$db = mysqli_connect(EW_CONN_HOST, MAILDB_USER, MAILDB_PASS, MAILDB_DB);

$bCanSend = false;
$bSomethingSent = false;

$sql = "SELECT StartSend, EndSend FROM LastSend";
$rsRec = mysqli_query($db, $sql);

// echo 'Selecting last send: ' . $rsRec . "\r\n";

if ($rsR = mysqli_fetch_assoc($rsRec)) {
    // echo 'Last send was ' . $rsR["StartSend"] . ' and ' . $rsR["EndSend"] . "\r\n";
    // Has 15 seconds passed since the last send?
    if ((time() - strtotime($rsR["StartSend"])) >= 15) {
        $bCanSend = true;
        // Or, was the last start a loooong time ago?
    } elseif ((time() - strtotime($rsR["StartSend"])) >= 10) {
        $bCanSend = true;
    }
}

if ($bCanSend) {

    // Get the messages
    $sql = "SELECT * "
        . "FROM Messages "
        . "WHERE FromSchool=0 "
        . "AND EXISTS (SELECT * FROM ToSend WHERE ToSend.MessageID=Messages.MessageID AND ToSend.Sent=0) "
        . "ORDER BY Messages.Prioritise DESC, Messages.MessageID";
    $rsMsg = mysqli_query($db, $sql);

    if ($rsM = mysqli_fetch_assoc($rsMsg)) {
    } else {
        // echo 'Select from messages failed: ' . $sql . ' <br />';
        $bCanSend = false;
    }
}

if ($bCanSend) {

    for ($loopCnt = 1; $loopCnt <= $loopMax; $loopCnt++) {
        //Send 20 messages 10 times
        // Make sure another instance of this script doesn't start sending!!
        $sql = "UPDATE LastSend SET StartSend='" . date("Y-m-d H:i:s") . "', EndSend='2020-01-01'";
        mysqli_query($db, $sql);

        $iMsgsSent = 0;

        $sql = "SELECT ToSend.SendTo, ToSend.Message FROM ToSend WHERE ToSend.MessageID=" . $rsM["MessageID"] . " and ToSend.Sent=0 and ToSend.SendTo LIKE '%@cesa.co.za' "
            . "ORDER BY ToSend.SendTo LIMIT 0," . $maxmsgs;
        // echo $sql . "\r\n";

        $rsRec = mysqli_query($db, $sql);

        if (mysqli_num_rows($rsRec) <= 0) {
            $sql = "SELECT ToSend.SendTo, ToSend.Message FROM ToSend WHERE ToSend.MessageID=" . $rsM["MessageID"] . " and ToSend.Sent=0 and NOT (ToSend.SendTo LIKE '%@cesa.co.za') "
                . "ORDER BY ToSend.SendTo LIMIT 0," . $maxmsgs;
            // echo $sql . "\r\n";

            $rsRec = mysqli_query($db, $sql);
        }

        while ($rsR = mysqli_fetch_assoc($rsRec)) {

            $sMessage = $rsM["Message"];
            if (!empty($rsR["Message"]))
                $sMessage = $rsR["Message"];

            // Format and validate email list
            $formattedEmailList = formatEmailList($rsR["SendTo"]);
            if ($formattedEmailList === false) {
                echo 'No valid e-mail addresses found in: ' . $rsR["SendTo"] . "\r\n";
                ErrorLog::logError("No valid e-mail addresses found in: " . $rsR["SendTo"]);
                
                // Mark as sent with error status (Sent=2)
                $sql = "UPDATE ToSend SET Sent=2 WHERE SendTo='" . addslashes($rsR["SendTo"]) . "' AND MessageID=" . $rsM["MessageID"];
                mysqli_query($db, $sql);
                continue;
            }
            
            // Use formatted email list
            $sendToEmail = $formattedEmailList;
            
            // If list was reformatted, log it
            if ($sendToEmail !== $rsR["SendTo"]) {
                echo 'Email list reformatted from "' . $rsR["SendTo"] . '" to "' . $sendToEmail . '"' . "\r\n";
                ErrorLog::logInfo("Email list reformatted from \"" . $rsR["SendTo"] . "\" to \"" . $sendToEmail . "\"");
            }
            
            ErrorLog::logInfo("Valid e-mail address(es): " . $sendToEmail);
            if ($rsM['Headers'] != '') {
                // echo 'using built in mail <br />' . "\r\n";
                // var_dump($rsM["Headers"]);
                // exit;
                // mail(stripslashes($rsR["SendTo"]), $rsM["Subject"], $sMessage, $rsM["Headers"]);
                //TODO: Send raw message via SMTP server

                $messageFile = sys_get_temp_dir() . '/' . $rsM["MessageID"] . '.html';

                if (strpos($rsM["MessageFrom"], 'cesa.co.za') !== false) {
                    $fromAddress = $rsM["MessageFrom"];
                } else {
                    $fromAddress = $smtp_user;
                }

                $headerValues = explode("\r\n", $rsM["Headers"]);
                $contentType = '';
                $boundary = '';
                foreach ($headerValues as $headerValue) {

                    echo 'Looking for boundary: ' . $headerValue . ' '
                        . strpos($headerValue, 'boundary') . "\r\n";
                    if (strpos($headerValue, 'Content-Type:') === 0) {
                        $contentType = $headerValue;
                    } elseif (strpos($headerValue, 'boundary') !== false) {
                        $boundary = $headerValue;
                        echo 'Found: ' . $boundary . "\r\n";
                    }
                }

                // var_dump($headerValues);
                // echo "\r\n\r\n";

                $msgPre = "From: " . $smtp_user . "\r\n"
                    . "Reply-To: " . $fromAddress . "\r\n"
                    . "To: " . $sendToEmail . "\r\n"
                    . "Subject: " . $rsM["Subject"] . "\r\n"
                    . "MIME-Version: 1.0\r\n"
                    . $contentType . "\r\n" .  $boundary . "\r\n\r\n";

                // echo $msgPre;

                $sMessage = $msgPre . $sMessage;
                file_put_contents($messageFile, $sMessage);

                // echo 'python3 '
                //     . $_SERVER['DOCUMENT_ROOT'] . '/python/send-mail.py ' . $messageFile . ' "'
                //     . $fromAddress . '" "' . $rsR["SendTo"] . '" ' . $smtp_host . ' '
                //     . $smtp_port . ' "' . $smtp_user . '" "' . $smtp_pass . '"';

                $response = shell_exec('python3 '
                    . $_SERVER['DOCUMENT_ROOT'] . '/python/send-mail.py ' . $messageFile . ' "'
                    . $fromAddress . '" "' . $sendToEmail . '" ' . $smtp_host . ' '
                    . $smtp_port . ' "' . $smtp_user . '" "' . $smtp_pass . '"');

                if (strpos($response, 'Email sent successfully') !== false) {
                    echo 'Python send response: ' . $response . "\r\n";
                    ErrorLog::logInfo("Email sent successfully");
                } else {
                    echo 'Python send response: ' . $response . "\r\n";
                    ErrorLog::logError("Email sent failed: " . $response);
                }

                $iMsgsSent++;
                $bSomethingSent = true;
            } elseif ($rsM['Options'] != '') {

                $json_obj = json_decode($rsM['Options'], true);

                if (!is_array($json_obj)) {
                    $json_obj = [];
                }

                if (!isset($json_obj['from-name'])) {
                    $json_obj['from-name'] = 'CESA';
                }

                maill(stripslashes($sendToEmail), $rsM["Subject"], $sMessage, null, $json_obj, true);
            }
            $iMsgsSent++;
            $bSomethingSent = true;

            $sql = "UPDATE ToSend SET Sent=1 "
                . "WHERE SendTo='" . addslashes($rsR["SendTo"]) . "' "
                . "AND MessageID=" . $rsM["MessageID"];
            // echo 'Updating ToSend: ' . $sql . "\r\n";
            mysqli_query($db, $sql);

            echo $sendToEmail . "<br />\r\n";
            //            echo ".";
            flush();
            ob_flush();
            //wait for a quarter second
            //            usleep(250);
        } //while

        mysqli_free_result($rsRec);

        $sql = "DELETE ts FROM ToSend ts "
            . "INNER JOIN Messages m ON ts.MessageID = m.MessageID "
            . "WHERE ts.Sent = 1 AND m.DateSent <= DATE_SUB(NOW(), INTERVAL 21 DAY)";
        // echo 'Cleaning out ToSend: ' . $sql . "\r\n";
        mysqli_query($db, $sql);

        $sql = "SELECT Messages.MessageID, COUNT(ToSend.ToSendID) AS Num FROM Messages LEFT JOIN ToSend USING (MessageID) "
            . "WHERE SendComplete=0 GROUP BY Messages.MessageID";
        $rsRec = mysqli_query($db, $sql);
        while ($rsRow = mysqli_fetch_assoc($rsRec)) {
            if ($rsRow["Num"] == 0) {
                $sql = "UPDATE Messages SET SendComplete=1, DateComplete='" . date("Y-m-d H:i:s") . "' WHERE MessageID='" . $rsRow["MessageID"] . "'";
                mysqli_query($db, $sql);
            }
        } //while
        // Get school mailing list messages
        /*
          $sql = "SELECT sml_message_archive.subject AS Subject, sml_message_archive.message AS Message, sml_message_archive.id AS MessageID, sml_delivery_queue.email AS SendTo
          FROM sml_message_archive, sml_delivery_queue
          WHERE sml_message_archive.id=sml_delivery_queue.message_id
          AND sml_message_archive.start_send<=UNIX_TIMESTAMP()";
          $rsMsg = mysql_query($sql);

          echo ".";
          flush();
          ob_flush();

          while (($iMsgsSent <= $maxmsgs) && ($rsM = mysql_fetch_assoc($rsMsg))) {

          $bSendFinished = false;

          $sql = "DELETE FROM sml_delivery_queue WHERE message_id=".$rsM["MessageID"]." AND email='".$rsM["SendTo"]."'";
          mysql_query($sql);

          mail(stripslashes($rsM["SendTo"]), $rsM["Subject"], $rsM["Message"], "MIME-Version: 1.0" . "\r\n"."Content-type:text/html;charset=UTF-8" . "\r\n"."From: brenda@cesa.co.za"."\r\n"."Reply-To: brenda@cesa.co.za"."\r\n");

          $iMsgsSent++;
          $bSomethingSent = true;

          $sql = "UPDATE sml_message_archive SET recipients=recipients+1 WHERE id=".$rsM["MessageID"];
          mysql_query($sql);

          echo $rsM["SendTo"]."<BR>";
          echo ".";
          flush();
          ob_flush();

          usleep(100000);

          }
         */

        //if ($bSomethingSent) {
        $sql = "UPDATE LastSend SET EndSend='" . date("Y-m-d H:i:s") . "'";
        mysqli_query($db, $sql);
    }
    //}
} else {
    echo "Can't send yet.";
}

flush();
ob_flush();

unlink($lockFile);