function SendMessage($ID, $timeout = 0, $maxcount = 0, $check_charset = false) { global $DB, $APPLICATION; $eol = CEvent::GetMailEOL(); $ID = intval($ID); $timeout = intval($timeout); $start_time = getmicrotime(); @set_time_limit(0); $this->LAST_ERROR = ""; $post = $this->GetByID($ID); if (!($post_arr = $post->Fetch())) { $this->LAST_ERROR .= GetMessage("class_post_err_notfound"); return false; } if ($post_arr["STATUS"] != "P") { $this->LAST_ERROR .= GetMessage("class_post_err_status") . "<br>"; return false; } if ($check_charset && strlen($post_arr["MSG_CHARSET"]) > 0 && strtoupper($post_arr["MSG_CHARSET"]) != strtoupper(LANG_CHARSET)) { return "CONTINUE"; } if (CPosting::Lock($ID) === false) { if ($e = $APPLICATION->GetException()) { $this->LAST_ERROR .= GetMessage("class_post_err_lock") . "<br>" . $e->GetString(); if (strpos($this->LAST_ERROR, "PLS-00201") !== false && strpos($this->LAST_ERROR, "'DBMS_LOCK'") !== false) { $this->LAST_ERROR .= "<br>" . GetMessage("class_post_err_lock_advice"); } $APPLICATION->ResetException(); return false; } else { return "CONTINUE"; } } if ($post_arr["VERSION"] != '2') { if (is_string($post_arr["BCC_TO_SEND"]) && strlen($post_arr["BCC_TO_SEND"]) > 0) { $a = explode(",", $post_arr["BCC_TO_SEND"]); foreach ($a as $e) { $DB->Query("INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL) VALUES (" . $ID . ", 'Y', '" . $DB->ForSQL($e) . "')"); } } if (is_string($post_arr["ERROR_EMAIL"]) && strlen($post_arr["ERROR_EMAIL"]) > 0) { $a = explode(",", $post_arr["ERROR_EMAIL"]); foreach ($a as $e) { $DB->Query("INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL) VALUES (" . $ID . ", 'E', '" . $DB->ForSQL($e) . "')"); } } if (is_string($post_arr["SENT_BCC"]) && strlen($post_arr["SENT_BCC"]) > 0) { $a = explode(",", $post_arr["SENT_BCC"]); foreach ($a as $e) { $DB->Query("INSERT INTO b_posting_email (POSTING_ID, STATUS, EMAIL) VALUES (" . $ID . ", 'N', '" . $DB->ForSQL($e) . "')"); } } $DB->Query("UPDATE b_posting SET VERSION='2', BCC_TO_SEND=null, ERROR_EMAIL=null, SENT_BCC=null WHERE ID=" . $ID); } if (strlen($post_arr["CHARSET"]) > 0) { $from_charset = $post_arr["MSG_CHARSET"] ? $post_arr["MSG_CHARSET"] : SITE_CHARSET; $post_arr["BODY"] = $APPLICATION->ConvertCharset($post_arr["BODY"], $from_charset, $post_arr["CHARSET"]); $post_arr["SUBJECT"] = $APPLICATION->ConvertCharset($post_arr["SUBJECT"], $from_charset, $post_arr["CHARSET"]); $post_arr["FROM_FIELD"] = $APPLICATION->ConvertCharset($post_arr["FROM_FIELD"], $from_charset, $post_arr["CHARSET"]); } //Preparing message header, text, subject $sBody = str_replace("\r\n", "\n", $post_arr["BODY"]); if (COption::GetOptionString("main", "CONVERT_UNIX_NEWLINE_2_WINDOWS", "N") == "Y") { $sBody = str_replace("\n", "\r\n", $sBody); } if (COption::GetOptionString("subscribe", "allow_8bit_chars") != "Y") { $sSubject = CMailTools::EncodeSubject($post_arr["SUBJECT"], $post_arr["CHARSET"]); $sFrom = CMailTools::EncodeHeaderFrom($post_arr["FROM_FIELD"], $post_arr["CHARSET"]); } else { $sSubject = $post_arr["SUBJECT"]; $sFrom = $post_arr["FROM_FIELD"]; } if ($post_arr["BODY_TYPE"] == "html") { //URN2URI $tools = new CMailTools(); $sBody = $tools->ReplaceHrefs($sBody); } $bHasAttachments = false; if ($post_arr["BODY_TYPE"] == "html" && COption::GetOptionString("subscribe", "attach_images") == "Y") { //MIME with attachments $tools = new CMailTools(); $sBody = $tools->ReplaceImages($sBody); if (count($tools->aMatches) > 0) { $bHasAttachments = true; $sBoundary = "----------" . uniqid(""); $sHeader = 'From: ' . $sFrom . $eol . 'X-Bitrix-Posting: ' . $post_arr["ID"] . $eol . 'MIME-Version: 1.0' . $eol . 'Content-Type: multipart/related; boundary="' . $sBoundary . '"' . $eol . 'Content-Transfer-Encoding: 8bit'; $sBody = "--" . $sBoundary . $eol . "Content-Type: " . ($post_arr["BODY_TYPE"] == "html" ? "text/html" : "text/plain") . ($post_arr["CHARSET"] != "" ? "; charset=" . $post_arr["CHARSET"] : "") . $eol . "Content-Transfer-Encoding: 8bit" . $eol . $eol . $sBody . $eol; foreach ($tools->aMatches as $attachment) { $aImage = CFile::GetImageSize($_SERVER["DOCUMENT_ROOT"] . $attachment["SRC"]); if ($aImage === false) { continue; } $filename = $_SERVER["DOCUMENT_ROOT"] . $attachment["SRC"]; $handle = fopen($filename, "rb"); $file = fread($handle, filesize($filename)); fclose($handle); $sBody .= $eol . "--" . $sBoundary . $eol . "Content-Type: " . (function_exists("image_type_to_mime_type") ? image_type_to_mime_type($aImage[2]) : CMailTools::ImageTypeToMimeType($aImage[2])) . "; name=\"" . $attachment["DEST"] . "\"" . $eol . "Content-Transfer-Encoding: base64" . $eol . "Content-ID: <" . $attachment["ID"] . ">" . $eol . $eol . chunk_split(base64_encode($file), 72, $eol); } } } $rsFile = CPosting::GetFileList($ID); $arFile = $rsFile->Fetch(); if ($arFile) { if (!$bHasAttachments) { $bHasAttachments = true; $sBoundary = "----------" . uniqid(""); $sHeader = "From: " . $sFrom . $eol . 'X-Bitrix-Posting: ' . $post_arr["ID"] . $eol . "MIME-Version: 1.0" . $eol . "Content-Type: multipart/related; boundary=\"" . $sBoundary . "\"" . $eol . "Content-Transfer-Encoding: 8bit"; $sBody = "--" . $sBoundary . $eol . "Content-Type: " . ($post_arr["BODY_TYPE"] == "html" ? "text/html" : "text/plain") . ($post_arr["CHARSET"] != "" ? "; charset=" . $post_arr["CHARSET"] : "") . $eol . "Content-Transfer-Encoding: 8bit" . $eol . $eol . $sBody . $eol; } do { if (strlen($post_arr["CHARSET"]) > 0) { $from_charset = $post_arr["MSG_CHARSET"] ? $post_arr["MSG_CHARSET"] : SITE_CHARSET; $file_name = $APPLICATION->ConvertCharset($arFile["ORIGINAL_NAME"], $from_charset, $post_arr["CHARSET"]); } else { $file_name = $arFile["ORIGINAL_NAME"]; } $sBody .= $eol . "--" . $sBoundary . $eol . "Content-Type: " . $arFile["CONTENT_TYPE"] . "; name=\"" . $file_name . "\"" . $eol . "Content-Transfer-Encoding: base64" . $eol . "Content-Disposition: attachment; filename=\"" . CMailTools::EncodeHeaderFrom($file_name, $post_arr["CHARSET"]) . "\"" . $eol . $eol; $arTempFile = CFile::MakeFileArray($arFile["ID"]); $sBody .= chunk_split(base64_encode(file_get_contents($arTempFile["tmp_name"])), 72, $eol); } while ($arFile = $rsFile->Fetch()); } if ($bHasAttachments) { $sBody .= $eol . "--" . $sBoundary . "--" . $eol; } else { //plain message without MIME $sHeader = "From: " . $sFrom . $eol . 'X-Bitrix-Posting: ' . $post_arr["ID"] . $eol . "MIME-Version: 1.0" . $eol . "Content-Type: " . ($post_arr["BODY_TYPE"] == "html" ? "text/html" : "text/plain") . ($post_arr["CHARSET"] != "" ? "; charset=" . $post_arr["CHARSET"] : "") . $eol . "Content-Transfer-Encoding: 8bit"; } $mail_additional_parameters = trim(COption::GetOptionString("subscribe", "mail_additional_parameters")); if ($post_arr["DIRECT_SEND"] == "Y") { //personal delivery $arEvents = array(); $rsEvents = GetModuleEvents("subscribe", "BeforePostingSendMail"); while ($arEvent = $rsEvents->Fetch()) { $arEvents[] = $arEvent; } $rsEmails = $DB->Query($DB->TopSql("\n\t\t\t\tSELECT *\n\t\t\t\tFROM b_posting_email\n\t\t\t\tWHERE POSTING_ID = " . $ID . " AND STATUS='Y'\n\t\t\t", $maxcount)); while ($arEmail = $rsEmails->Fetch()) { //Event part $arFields = array("POSTING_ID" => $ID, "EMAIL" => $arEmail["EMAIL"], "SUBJECT" => $sSubject, "BODY" => $sBody, "HEADER" => $sHeader, "EMAIL_EX" => $arEmail); foreach ($arEvents as $arEvent) { $arFields = ExecuteModuleEventEx($arEvent, array($arFields)); } //Sending if (is_array($arFields)) { $result = bxmail($arFields["EMAIL"], $arFields["SUBJECT"], $arFields["BODY"], $arFields["HEADER"], $mail_additional_parameters); } else { $result = $arFields !== false; } //Result check and iteration if ($result) { $DB->Query("UPDATE b_posting_email SET STATUS='N' WHERE ID = " . $arEmail["ID"]); } else { $DB->Query("UPDATE b_posting_email SET STATUS='E' WHERE ID = " . $arEmail["ID"]); } if ($timeout > 0 && getmicrotime() - $start_time >= $timeout) { break; } self::$current_emails_per_hit++; } } else { //BCC delivery $rsEmails = $DB->Query($DB->TopSql("\n\t\t\t\tSELECT *\n\t\t\t\tFROM b_posting_email\n\t\t\t\tWHERE POSTING_ID = " . $ID . " AND STATUS='Y'\n\t\t\t", COption::GetOptionString("subscribe", "max_bcc_count"))); $aStep = array(); while ($arEmail = $rsEmails->Fetch()) { $aStep[$arEmail["ID"]] = $arEmail["EMAIL"]; } if (count($aStep) > 0) { $BCC = implode(",", $aStep); $sHeaderStep = $sHeader . $eol . "Bcc: " . $BCC; $result = bxmail($post_arr["TO_FIELD"], $sSubject, $sBody, $sHeaderStep, $mail_additional_parameters); if ($result) { $DB->Query("UPDATE b_posting_email SET STATUS='N' WHERE ID in (" . implode(", ", array_keys($aStep)) . ")"); } else { $DB->Query("UPDATE b_posting_email SET STATUS='E' WHERE ID in (" . implode(", ", array_keys($aStep)) . ")"); $this->LAST_ERROR .= GetMessage("class_post_err_mail") . "<br>"; } } } //set status and delivered and error emails $arStatuses = $this->GetEmailStatuses($ID); if (!array_key_exists("Y", $arStatuses)) { $STATUS = array_key_exists("E", $arStatuses) ? "E" : "S"; $DATE = $DB->GetNowFunction(); } else { $STATUS = "P"; $DATE = "null"; } CPosting::UnLock($ID); $DB->Query("UPDATE b_posting SET STATUS='" . $STATUS . "', DATE_SENT=" . $DATE . " WHERE ID=" . $ID); return $STATUS == "P" ? "CONTINUE" : true; }
public function __replace_img($matches) { $io = CBXVirtualIo::GetInstance(); $src = $matches[3]; if ($src == "") { return $matches[0]; } if (array_key_exists($src, $this->aMatches)) { $uid = $this->aMatches[$src]["ID"]; return $matches[1] . $matches[2] . "cid:" . $uid . $matches[4] . $matches[5]; } $filePath = $io->GetPhysicalName($_SERVER["DOCUMENT_ROOT"] . $src); if (!file_exists($filePath)) { return $matches[0]; } if ($this->maxFileSize > 0 && filesize($filePath) > $this->maxFileSize) { return $matches[0]; } $aImage = CFile::GetImageSize($filePath, true); if (!is_array($aImage)) { return $matches[0]; } if (function_exists("image_type_to_mime_type")) { $contentType = image_type_to_mime_type($aImage[2]); } else { $contentType = CMailTools::ImageTypeToMimeType($aImage[2]); } $uid = uniqid(md5($src)); $this->aMatches[$src] = array("SRC" => $src, "PATH" => $filePath, "CONTENT_TYPE" => $contentType, "DEST" => bx_basename($src), "ID" => $uid); return $matches[1] . $matches[2] . "cid:" . $uid . $matches[4] . $matches[5]; }