* @license http://www.contenido.org/license/LIZENZ.txt * @link http://www.4fb.de * @link http://www.contenido.org * @since file available since contenido release <= 4.6 * * {@internal * created 2004-08-01 * modified 2008-06-30, Dominik Ziegler, add security fix * modified 2011-03-14, Murat Purc, adapted to new GenericDB, partly ported to PHP 5, formatting * * $Id: class.newsletter.jobs.php 128 2019-07-03 11:58:28Z oldperl $: * }} * */ if (!defined('CON_FRAMEWORK')) { die('Illegal call'); } /** * Collection management class */ class cNewsletterJobCollection extends ItemCollection { /** * Constructor Function * @param none */ public function __construct() { global $cfg; parent::__construct($cfg["tab"]["news_jobs"], "idnewsjob"); $this->_setItemClass("cNewsletterJob"); } /** * Creates a newsletter job * @param $name string Specifies the name of the newsletter, the same name may be used more than once * @param $idnews integer Newsletter id */ public function create($iIDNews, $iIDCatArt, $sName = "") { global $client, $lang, $cfg, $cfgClient, $auth; $oNewsletter = new Newsletter; if ($oNewsletter->loadByPrimaryKey($iIDNews)) { $iIDNews = Contenido_Security::toInteger($iIDNews); $iIDCatArt = Contenido_Security::toInteger($iIDCatArt); $lang = Contenido_Security::toInteger($lang); $client = Contenido_Security::toInteger($client); $sName = Contenido_Security::escapeDB($sName, null); $oItem = parent::createNewItem(); $oItem->set("idnews", $iIDNews); $oItem->set("idclient", $client); $oItem->set("idlang", $lang); if ($sName == "") { $oItem->set("name", $oNewsletter->get("name")); } else { $oItem->set("name", $sName); } $oItem->set("type", $oNewsletter->get("type")); $oItem->set("use_cronjob", $oNewsletter->get("use_cronjob")); $oLang = new cApiLanguage($lang); $oItem->set("encoding", $oLang->get("encoding")); unset($oLang); $oItem->set("idart", $oNewsletter->get("idart")); $oItem->set("subject", $oNewsletter->get("subject")); // Precompile messages $sPath = $cfgClient[$client]["path"]["htmlpath"] . "front_content.php?changelang=" . $lang . "&idcatart=" . $iIDCatArt . "&"; $sMessageText = $oNewsletter->get("message"); // Preventing double lines in mail, you may wish to disable this function on windows servers if (!getSystemProperty("newsletter", "disable-rn-replacement")) { $sMessageText = str_replace("\r\n", "\n", $sMessageText); } $oNewsletter->_replaceTag($sMessageText, false, "unsubscribe", $sPath . "unsubscribe={KEY}"); $oNewsletter->_replaceTag($sMessageText, false, "change", $sPath . "change={KEY}"); $oNewsletter->_replaceTag($sMessageText, false, "stop", $sPath . "stop={KEY}"); $oNewsletter->_replaceTag($sMessageText, false, "goon", $sPath . "goon={KEY}"); $oItem->set("message_text", $sMessageText); if ($oNewsletter->get("type") == "text") { // Text newsletter, no html message $sMessageHTML = ""; } else { // HTML newsletter, get article content $sMessageHTML = $oNewsletter->getHTMLMessage(); if ($sMessageHTML) { $oNewsletter->_replaceTag($sMessageHTML, true, "name", "MAIL_NAME"); $oNewsletter->_replaceTag($sMessageHTML, true, "number", "MAIL_NUMBER"); $oNewsletter->_replaceTag($sMessageHTML, true, "date", "MAIL_DATE"); $oNewsletter->_replaceTag($sMessageHTML, true, "time", "MAIL_TIME"); $oNewsletter->_replaceTag($sMessageHTML, true, "unsubscribe", $sPath . "unsubscribe={KEY}"); $oNewsletter->_replaceTag($sMessageHTML, true, "change", $sPath . "change={KEY}"); $oNewsletter->_replaceTag($sMessageHTML, true, "stop", $sPath . "stop={KEY}"); $oNewsletter->_replaceTag($sMessageHTML, true, "goon", $sPath . "goon={KEY}"); // Replace plugin tags by simple MAIL_ tags if (getSystemProperty("newsletter", "newsletter-recipients-plugin") == "true") { if (is_array($cfg['plugins']['recipients'])) { foreach ($cfg['plugins']['recipients'] as $sPlugin) { plugin_include("recipients", $sPlugin . "/" . $sPlugin . ".php"); if (function_exists("recipients_" . $sPlugin . "_wantedVariables")) { $aPluginVars = array(); $aPluginVars = call_user_func("recipients_" . $sPlugin . "_wantedVariables"); foreach ($aPluginVars as $sPluginVar) { $oNewsletter->_replaceTag($sMessageHTML, true, $sPluginVar, "MAIL_" . strtoupper($sPluginVar)); } } } } } } else { // There was a problem getting html message (maybe article deleted) // Cancel job generation return false; } } $oItem->set("message_html", $sMessageHTML); $oItem->set("newsfrom", $oNewsletter->get("newsfrom")); if ($oNewsletter->get("newsfromname") == "") { $oItem->set("newsfromname", $oNewsletter->get("newsfrom")); } else { $oItem->set("newsfromname", $oNewsletter->get("newsfromname")); } $oItem->set("newsdate", date("Y-m-d H:i:s"), false); //$oNewsletter->get("newsdate")); $oItem->set("dispatch", $oNewsletter->get("dispatch")); $oItem->set("dispatch_count", $oNewsletter->get("dispatch_count")); $oItem->set("dispatch_delay", $oNewsletter->get("dispatch_delay")); // Store "send to" info in serialized array (just info) $aSendInfo = array(); $aSendInfo[] = $oNewsletter->get("send_to"); switch ($oNewsletter->get("send_to")) { case "selection": $oGroups = new RecipientGroupCollection; $oGroups->setWhere("idnewsgroup", unserialize($oNewsletter->get("send_ids")), "IN"); $oGroups->setOrder("groupname"); $oGroups->query(); #$oGroups->select("idnewsgroup IN ('" . implode("','", unserialize($oNewsletter->get("send_ids"))) . "')", "", "groupname"); while ($oGroup = $oGroups->next()) { $aSendInfo[] = $oGroup->get("groupname"); } unset($oGroup); unset($oGroups); break; case "single": if (is_numeric($oNewsletter->get("send_ids"))) { $oRcp = new Recipient($oNewsletter->get("send_ids")); if ($oRcp->get("name") == "") { $aSendInfo[] = $oRcp->get("email"); } else { $aSendInfo[] = $oRcp->get("name"); } $aSendInfo[] = $oRcp->get("email"); unset($oRcp); } break; default: } $oItem->set("send_to", serialize($aSendInfo), false); $oItem->set("created", date("Y-m-d H:i:s"), false); $oItem->set("author", $auth->auth["uid"]); $oItem->set("authorname", $auth->auth["uname"]); unset($oNewsletter); // Not needed anymore // Adds log items for all recipients and returns recipient count $oLogs = new cNewsletterLogCollection(); $iRecipientCount = $oLogs->initializeJob($oItem->get($oItem->primaryKey), $iIDNews); unset($oLogs); $oItem->set("rcpcount", $iRecipientCount); $oItem->set("sendcount", 0); $oItem->set("status", 1); // Waiting for sending; note, that status will be set to 9, if $iRecipientCount = 0 in store() method $oItem->store(); return $oItem; } else { return false; } } /** * Overridden delete method to remove job details (logs) from newsletter logs table * before deleting newsletter job * * @param $iItemID int specifies the frontend user group */ public function delete($iItemID) { $oLogs = new cNewsletterLogCollection(); $oLogs->delete($iItemID); parent::delete($iItemID); } } /** * Single NewsletterJob Item */ class cNewsletterJob extends Item { /** * Constructor Function * @param mixed $mId Specifies the ID of item to load */ public function __construct($mId = false) { global $cfg; parent::__construct($cfg["tab"]["news_jobs"], "idnewsjob"); if ($mId !== false) { $this->loadByPrimaryKey($mId); } } public function runJob() { global $cfg, $recipient; $iCount = 0; if ($this->get("status") == 2) { // Job is currently running, check start time and restart if // started 5 minutes ago $dStart = strtotime($this->get("started")); $dNow = time(); if (($dNow - $dStart) > (5 * 60)) { $this->set("status", 1); $this->set("started", "0000-00-00 00:00:00", false); $oLogs = new cNewsletterLogCollection(); $oLogs->setWhere("idnewsjob", $this->get($this->primaryKey)); $oLogs->setWhere("status", "sending"); $oLogs->query(); while ($oLog = $oLogs->next()) { $oLog->set("status", "error (sending)"); $oLog->store(); } } } if ($this->get("status") == 1) { // Job waiting for sending $this->set("status", 2); $this->set("started", date("Y-m-d H:i:s"), false); $this->store(); // Initialization $aMessages = array(); $oLanguage = new cApiLanguage($this->get("idlang")); $sFormatDate = $oLanguage->getProperty("dateformat", "date"); $sFormatTime = $oLanguage->getProperty("dateformat", "time"); unset($oLanguage); if ($sFormatDate == "") { $sFormatDate = "%d.%m.%Y"; } if ($sFormatTime == "") { $sFormatTime = "%H:%M"; } // Get newsletter data $sFrom = $this->get("newsfrom"); $sFromName = $this->get("newsfromname"); $sSubject = $this->get("subject"); $sMessageText = $this->get("message_text"); $sMessageHTML = $this->get("message_html"); $dNewsDate = strtotime($this->get("newsdate")); $sEncoding = $this->get("encoding"); $bIsHTML = false; if ($this->get("type") == "html" && $sMessageHTML != "") { $bIsHTML = true; } $bDispatch = false; if ($this->get("dispatch") == 1) { $bDispatch = true; } // Single replacements // Replace message tags (text message) $sMessageText = str_replace("MAIL_DATE", strftime($sFormatDate, $dNewsDate), $sMessageText); $sMessageText = str_replace("MAIL_TIME", strftime($sFormatTime, $dNewsDate), $sMessageText); $sMessageText = str_replace("MAIL_NUMBER", $this->get("rcpcount"), $sMessageText); // Replace message tags (html message) if ($bIsHTML) { $sMessageHTML = str_replace("MAIL_DATE", strftime($sFormatDate, $dNewsDate), $sMessageHTML); $sMessageHTML = str_replace("MAIL_TIME", strftime($sFormatTime, $dNewsDate), $sMessageHTML); $sMessageHTML = str_replace("MAIL_NUMBER", $this->get("rcpcount"), $sMessageHTML); } // Enabling plugin interface $bPluginEnabled = false; if (getSystemProperty("newsletter", "newsletter-recipients-plugin") == "true") { $bPluginEnabled = true; $aPlugins = array(); if (is_array($cfg['plugins']['recipients'])) { foreach ($cfg['plugins']['recipients'] as $sPlugin) { plugin_include("recipients", $sPlugin . "/" . $sPlugin . ".php"); if (function_exists("recipients_" . $sPlugin . "_wantedVariables")) { $aPlugins[$sPlugin] = call_user_func("recipients_" . $sPlugin . "_wantedVariables"); } } } } // Get recipients (from log table) if (!is_object($oLogs)) { $oLogs = new cNewsletterLogCollection; } else { $oLogs->resetQuery(); } $oLogs->setWhere("idnewsjob", $this->get($this->primaryKey)); $oLogs->setWhere("status", "pending"); if ($bDispatch) { $oLogs->setLimit(0, $this->get("dispatch_count")); } $oLogs->query(); while ($oLog = $oLogs->next()) { $iCount++; $oLog->set("status", "sending"); $oLog->store(); $sRcpMsgText = $sMessageText; $sRcpMsgHTML = $sMessageHTML; $sKey = $oLog->get("rcphash"); $sEMail = $oLog->get("rcpemail"); $bSendHTML = false; if ($oLog->get("rcpnewstype") == 1) { $bSendHTML = true; // Recipient accepts html newsletter } if (strlen($sKey) == 30) { // Prevents sending without having a key $sRcpMsgText = str_replace("{KEY}", $sKey, $sRcpMsgText); $sRcpMsgText = str_replace("MAIL_MAIL", $sEMail, $sRcpMsgText); $sRcpMsgText = str_replace("MAIL_NAME", $oLog->get("rcpname"), $sRcpMsgText); // Replace message tags (html message) if ($bIsHTML && $bSendHTML) { $sRcpMsgHTML = str_replace("{KEY}", $sKey, $sRcpMsgHTML); $sRcpMsgHTML = str_replace("MAIL_MAIL", $sEMail, $sRcpMsgHTML); $sRcpMsgHTML = str_replace("MAIL_NAME", $oLog->get("rcpname"), $sRcpMsgHTML); } if ($bPluginEnabled) { // Don't change name of $recipient variable as it is used in plugins! $recipient = new Recipient(); $recipient->loadByPrimaryKey($oLog->get("idnewsrcp")); foreach ($aPlugins as $sPlugin => $aPluginVar) { foreach ($aPluginVar as $sPluginVar) { // Replace tags in text message $sRcpMsgText = str_replace("MAIL_" . strtoupper($sPluginVar), call_user_func("recipients_" . $sPlugin . "_getvalue", $sPluginVar), $sRcpMsgText); // Replace tags in html message if ($bIsHTML && $bSendHTML) { $sRcpMsgHTML = str_replace("MAIL_" . strtoupper($sPluginVar), call_user_func("recipients_" . $sPlugin . "_getvalue", $sPluginVar), $sRcpMsgHTML); } } } unset($recipient); } $oMail = new PHPMailer(); $oMail->CharSet = $sEncoding; $oMail->IsHTML($bIsHTML && $bSendHTML); $oMail->From = $sFrom; $oMail->FromName = $sFromName; $oMail->AddAddress($sEMail); $oMail->Mailer = "mail"; $oMail->Subject = $sSubject; if ($bIsHTML && $bSendHTML) { $oMail->Body = $sRcpMsgHTML; $oMail->AltBody = $sRcpMsgText . "\n\n"; } else { $oMail->Body = $sRcpMsgText . "\n\n"; } if ($oMail->Send()) { $oLog->set("status", "successful"); $oLog->set("sent", date("Y-m-d H:i:s"), false); } else { $oLog->set("status", "error (sending)"); } } else { $oLog->set("status", "error (key)"); } $oLog->store(); } $this->set("sendcount", $this->get("sendcount") + $iCount); if ($iCount == 0 || !$bDispatch) { // No recipients remaining, job finished $this->set("status", 9); $this->set("finished", date("Y-m-d H:i:s"), false); } else if ($bDispatch) { // Check, if there are recipients remaining - stops job faster $oLogs->resetQuery(); $oLogs->setWhere("idnewsjob", $this->get($this->primaryKey)); $oLogs->setWhere("status", "pending"); $oLogs->setLimit(0, $this->get("dispatch_count")); $oLogs->query(); If ($oLogs->next()) { // Remaining recipients found, set job back to pending $this->set("status", 1); $this->set("started", "0000-00-00 00:00:00", false); } else { // No remaining recipients, job finished $this->set("status", 9); $this->set("finished", date("Y-m-d H:i:s"), false); } } else { // Set job back to pending $this->set("status", 1); $this->set("started", "0000-00-00 00:00:00", false); } $this->store(); } return $iCount; } /** * Overriden store() method to set status to finished if rcpcount is 0 */ public function store() { if ($this->get("rcpcount") == 0) { // No recipients, job finished $this->set("status", 9); if ($this->get("started") == "0000-00-00 00:00:00") { $this->set("started", date("Y-m-d H:i:s"), false); } $this->set("finished", date("Y-m-d H:i:s"), false); } parent::store(); } } ?>