/** * Handler of before delete event * @param Entity\Event $event * @return Entity\EventResult */ public static function onBeforeDelete(Entity\Event $event) { $result = new Entity\EventResult(); $data = $event->getParameters(); $chainListDb = MailingChainTable::getList(array('select' => array('ID', 'SUBJECT', 'MAILING_ID', 'MAILING_NAME' => 'MAILING.NAME'), 'filter' => array('TEMPLATE_TYPE' => 'USER', 'TEMPLATE_ID' => $data['primary']['ID']), 'order' => array('MAILING_NAME' => 'ASC', 'ID'))); if ($chainListDb->getSelectedRowsCount() > 0) { $template = static::getRowById($data['primary']['ID']); $messageList = array(); while ($chain = $chainListDb->fetch()) { $messageList[$chain['MAILING_NAME']] = '[' . $chain['ID'] . '] ' . htmlspecialcharsbx($chain['SUBJECT']) . "\n"; } $message = Loc::getMessage('SENDER_ENTITY_TEMPLATE_DELETE_ERROR_TEMPLATE', array('#NAME#' => $template['NAME'])) . "\n"; foreach ($messageList as $mailingName => $messageItem) { $message .= Loc::getMessage('SENDER_ENTITY_TEMPLATE_DELETE_ERROR_MAILING', array('#NAME#' => $mailingName)) . "\n" . $messageItem . "\n"; } $result->addError(new Entity\EntityError($message)); } return $result; }
?> </td> </tr> <?php if ($MAILING_ID > 0) { ?> <tr> <td><?php echo GetMessage("sender_stat_flt_mailing_chain"); ?> :</td> <td valign="middle"> <?php $arr = array(); $mailingChainDb = \Bitrix\Sender\MailingChainTable::getList(array('select' => array('REFERENCE' => 'SUBJECT', 'REFERENCE_ID' => 'ID'), 'filter' => array('MAILING_ID' => $MAILING_ID))); while ($arMailingChain = $mailingChainDb->fetch()) { $arr['reference'][] = $arMailingChain['REFERENCE']; $arr['reference_id'][] = $arMailingChain['REFERENCE_ID']; } echo SelectBoxFromArray("find_mailing_chain_id", $arr, $ID, false, ""); ?> </td> </tr> <?php } $oFilter->Buttons(array("table_id" => $sTableID, "url" => $APPLICATION->GetCurPage(), "form" => "find_form")); $oFilter->End(); ?> </form>
$dataPrimary = array('ID' => $ID); switch ($_REQUEST['action']) { case "delete": @set_time_limit(0); $DB->StartTransaction(); $dataDeleteDb = \Bitrix\Sender\MailingChainTable::delete($dataPrimary); if (!$dataDeleteDb->isSuccess()) { $DB->Rollback(); $lAdmin->AddGroupError(GetMessage("sender_mailing_chain_adm_del_error"), $ID); } $DB->Commit(); break; } } } $groupListDb = \Bitrix\Sender\MailingChainTable::getList(array('select' => array('ID', 'MAILING_ID', 'POSTING_ID', 'CREATED_BY', 'STATUS', 'REITERATE', 'LAST_EXECUTED', 'EMAIL_FROM', 'AUTO_SEND_TIME', 'DAYS_OF_MONTH', 'DAYS_OF_WEEK', 'TIMES_OF_DAY', 'NAME' => 'SUBJECT'), 'filter' => $arFilter, 'order' => array($by => $order))); $rsData = new CAdminResult($groupListDb, $sTableID); $rsData->NavStart(); $lAdmin->NavText($rsData->GetNavPrint(GetMessage("sender_mailing_chain_adm_nav"))); $lAdmin->AddHeaders(array(array("id" => "ID", "content" => "ID", "sort" => "ID", "align" => "right", "default" => true), array("id" => "NAME", "content" => GetMessage("sender_mailing_chain_adm_field_name"), "sort" => "NAME", "default" => true), array("id" => "CREATED_BY", "content" => GetMessage("sender_mailing_chain_adm_field_created_by"), "sort" => "CREATED_BY", "default" => true), array("id" => "STATUS", "content" => GetMessage("sender_mailing_chain_adm_field_status"), "sort" => "STATUS", "default" => true), array("id" => "EMAIL_FROM", "content" => GetMessage("sender_mailing_chain_adm_field_email_from"), "sort" => "EMAIL_FROM", "default" => false), array("id" => "REITERATE", "content" => GetMessage("sender_mailing_chain_adm_field_reiterate"), "sort" => "REITERATE", "default" => false), array("id" => "AUTO_SEND_TIME", "content" => GetMessage("sender_mailing_chain_adm_field_auto_send_time"), "sort" => "AUTO_SEND_TIME", "default" => false))); while ($arRes = $rsData->NavNext(true, "f_")) { $row =& $lAdmin->AddRow($f_ID, $arRes); $row->AddViewField("NAME", '<a href="/bitrix/admin/sender_mailing_chain_edit.php?MAILING_ID=' . $MAILING_ID . '&ID=' . $f_ID . '&lang=' . LANG . '">' . $f_NAME . '</a>'); $arUser = \Bitrix\Main\UserTable::getRowById(intval($f_CREATED_BY)); $row->AddViewField("CREATED_BY", '<a href="/bitrix/admin/user_edit.php?lang=' . LANGUAGE_ID . '&ID=' . $f_CREATED_BY . '">' . htmlspecialcharsbx($arUser['NAME'] . " " . $arUser['LAST_NAME']) . "</a>"); $arStatus = MailingChainTable::getStatusList(); $row->AddViewField("STATUS", $arStatus[$f_STATUS]); $row->AddViewField("REITERATE", $f_REITERATE == 'Y' ? GetMessage("MAIN_YES") : GetMessage("MAIN_NO")); $arActions = array(); $arActions[] = array("ICON" => "edit", "DEFAULT" => true, "TEXT" => GetMessage("sender_mailing_chain_adm_action_edit"), "ACTION" => $lAdmin->ActionRedirect("sender_mailing_chain_edit.php?MAILING_ID=" . $MAILING_ID . "&ID=" . $f_ID)); if ($POST_RIGHT >= "W") {
/** * @param $mailingChainId * @param array $params * @return string * @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\DB\Exception */ protected static function sendInternal($mailingChainId, array $params) { if (static::$currentMailingChainFields !== null) { if (static::$currentMailingChainFields['ID'] != $mailingChainId) { static::$currentMailingChainFields = null; } } if (static::$currentMailingChainFields === null) { $mailingChainDb = MailingChainTable::getList(array('select' => array('*', 'SITE_ID' => 'MAILING.SITE_ID'), 'filter' => array('ID' => $mailingChainId))); if (!($mailingChain = $mailingChainDb->fetch())) { return PostingRecipientTable::SEND_RESULT_ERROR; } $charset = false; $siteDb = \Bitrix\Main\SiteTable::getList(array('select' => array('SERVER_NAME', 'NAME', 'CULTURE_CHARSET' => 'CULTURE.CHARSET'), 'filter' => array('LID' => $mailingChain['SITE_ID']))); if ($site = $siteDb->fetch()) { $charset = $site['CULTURE_CHARSET']; $serverName = $site['SERVER_NAME']; } else { throw new \Bitrix\Main\DB\Exception(Loc::getMessage('SENDER_POSTING_MANAGER_ERR_SITE', array('#SITE_ID#' => $mailingChain['SITE_ID']))); } if (!$charset) { throw new \Bitrix\Main\DB\Exception(Loc::getMessage('SENDER_POSTING_MANAGER_ERR_CHARSET', array('#SITE_ID#' => "[" . $mailingChain['SITE_ID'] . "]" . $site['NAME']))); } $attachmentList = array(); $attachmentDb = \Bitrix\Sender\MailingAttachmentTable::getList(array('select' => array('FILE_ID'), 'filter' => array('CHAIN_ID' => $mailingChainId))); while ($attachment = $attachmentDb->fetch()) { $attachmentList[] = $attachment['FILE_ID']; } static::$currentMailingChainFields = array(); static::$currentMailingChainFields['EVENT'] = array('FILE' => $attachmentList); static::$currentMailingChainFields['ID'] = $mailingChain['ID']; static::$currentMailingChainFields['MESSAGE'] = array('BODY_TYPE' => 'html', 'EMAIL_FROM' => $mailingChain['EMAIL_FROM'], 'EMAIL_TO' => '#EMAIL_TO#', 'SUBJECT' => $mailingChain['SUBJECT'], 'MESSAGE' => $mailingChain['MESSAGE'], 'MESSAGE_PHP' => \Bitrix\Main\Mail\Internal\EventMessageTable::replaceTemplateToPhp($mailingChain['MESSAGE'])); static::$currentMailingChainFields['SITE'] = array($mailingChain['SITE_ID']); static::$currentMailingChainFields['CHARSET'] = $charset; static::$currentMailingChainFields['SERVER_NAME'] = $serverName; static::$currentMailingChainFields['LINK_PROTOCOL'] = \Bitrix\Main\Config\Option::get("sender", "link_protocol", 'http'); } $messageParams = array('EVENT' => static::$currentMailingChainFields['EVENT'], 'FIELDS' => $params['FIELDS'], 'MESSAGE' => static::$currentMailingChainFields['MESSAGE'], 'SITE' => static::$currentMailingChainFields['SITE'], 'CHARSET' => static::$currentMailingChainFields['CHARSET']); if (!empty($params['FIELDS']['UNSUBSCRIBE_LINK'])) { if (substr($params['FIELDS']['UNSUBSCRIBE_LINK'], 0, 4) !== 'http') { if (!empty(static::$currentMailingChainFields['SERVER_NAME'])) { $serverName = static::$currentMailingChainFields['SERVER_NAME']; } else { $serverName = \Bitrix\Main\Config\Option::get("main", "server_name", $GLOBALS["SERVER_NAME"]); } $linkProtocol = static::$currentMailingChainFields['LINK_PROTOCOL']; $params['FIELDS']['UNSUBSCRIBE_LINK'] = $linkProtocol . '://' . $serverName . $params['FIELDS']['UNSUBSCRIBE_LINK']; } } $message = Mail\EventMessageCompiler::createInstance($messageParams); $message->compile(); $mailHeaders = $message->getMailHeaders(); if (!empty($params['FIELDS']['UNSUBSCRIBE_LINK'])) { $unsubUrl = $params['FIELDS']['UNSUBSCRIBE_LINK']; $mailHeaders['List-Unsubscribe'] = '<' . $unsubUrl . '>'; } // send mail $result = Mail\Mail::send(array('TO' => $message->getMailTo(), 'SUBJECT' => $message->getMailSubject(), 'BODY' => $message->getMailBody(), 'HEADER' => $mailHeaders, 'CHARSET' => $message->getMailCharset(), 'CONTENT_TYPE' => $message->getMailContentType(), 'MESSAGE_ID' => '', 'ATTACHMENT' => $message->getMailAttachment(), 'LINK_PROTOCOL' => static::$currentMailingChainFields['LINK_PROTOCOL'], 'LINK_DOMAIN' => static::$currentMailingChainFields['SERVER_NAME'], 'TRACK_READ' => isset($params['TRACK_READ']) ? $params['TRACK_READ'] : null, 'TRACK_CLICK' => isset($params['TRACK_CLICK']) ? $params['TRACK_CLICK'] : null)); if ($result) { return PostingRecipientTable::SEND_RESULT_SUCCESS; } else { return PostingRecipientTable::SEND_RESULT_ERROR; } }
public static function actualizeHandlers($chainId, array $fieldsNew = null, array $fieldsOld = null) { $settingsNew = null; $settingsOld = null; if ($fieldsNew) { $settingsNew = new TriggerSettings($fieldsNew); } if ($fieldsOld) { $settingsOld = new TriggerSettings($fieldsOld); } // if old item was closed trigger if ($settingsOld && $settingsOld->isClosedTrigger()) { // delete agent $agentName = TriggerManager::getClosedEventAgentName($settingsOld->getEventModuleId(), $settingsOld->getEventType(), $chainId); $agent = new \CAgent(); $agentListDb = $agent->GetList(array(), array('MODULE_ID' => 'sender', 'NAME' => $agentName)); while ($agentItem = $agentListDb->Fetch()) { $agent->Delete($agentItem['ID']); } } // if new item is closed trigger if ($settingsNew && $settingsNew->isClosedTrigger()) { // check active state of mailing $chainDb = MailingChainTable::getList(array('select' => array('ID'), 'filter' => array('=ID' => $chainId, '=MAILING.ACTIVE' => 'Y'))); if (!$chainDb->fetch()) { return; } // add new agent $agentName = TriggerManager::getClosedEventAgentName($settingsNew->getEventModuleId(), $settingsNew->getEventType(), $chainId); // set date of next exec $agentTime = $settingsNew->getClosedTriggerTime(); $agentInterval = $settingsNew->getClosedTriggerInterval(); if ($agentInterval <= 0) { $agentInterval = 1440; } $agentTimeArray = explode(":", $agentTime); $agentDate = new \Bitrix\Main\Type\DateTime(); $agentDate->setTime((int) $agentTimeArray[0], (int) $agentTimeArray[1]); // set next exec on next day if exec was today if ($agentDate->getTimestamp() < time()) { $agentDate->add("1 days"); } // add agent $agent = new \CAgent(); $agent->AddAgent($agentName, 'sender', 'N', $agentInterval * 60, '', 'Y', $agentDate->toString()); return; } // actualize deleted/changed event if ($settingsOld && !$settingsOld->isClosedTrigger() && $settingsOld->getFullEventType()) { // if delete operation(no the NEW) // or change operation(the NEW is not equal to the OLD) if (!$settingsNew || $settingsOld->getFullEventType() != $settingsNew->getFullEventType()) { TriggerManager::actualizeHandler(array('MODULE_ID' => $settingsOld->getEventModuleId(), 'EVENT_TYPE' => $settingsOld->getEventType(), 'CALLED_BEFORE_CHANGE' => true)); } } // actualize new event if ($settingsNew && $settingsNew->getFullEventType()) { $calledBeforeChange = $fieldsOld ? false : true; TriggerManager::actualizeHandler(array('MODULE_ID' => $settingsNew->getEventModuleId(), 'EVENT_TYPE' => $settingsNew->getEventType(), 'CALLED_BEFORE_CHANGE' => $calledBeforeChange)); } }
/** * @return string * @throws \Bitrix\Main\ArgumentException */ public static function checkPeriod($isAgentExec = true) { $isAgentExecInSetting = \COption::GetOptionString("sender", "reiterate_method") !== 'cron'; if ($isAgentExec && !$isAgentExecInSetting || !$isAgentExec && $isAgentExecInSetting) { return ""; } $dateTodayPhp = new \DateTime(); $datetimeToday = Type\DateTime::createFromPhp(clone $dateTodayPhp); $dateToday = clone $dateTodayPhp; $dateToday = Type\Date::createFromPhp($dateToday->setTime(0, 0, 0)); $dateTomorrow = clone $dateTodayPhp; $dateTomorrow = Type\Date::createFromPhp($dateTomorrow->setTime(0, 0, 0))->add('1 DAY'); $arDateFilter = array($dateToday, $dateTomorrow); $chainDb = MailingChainTable::getList(array('select' => array('ID', 'LAST_EXECUTED', 'POSTING_ID', 'DAYS_OF_MONTH', 'DAYS_OF_WEEK', 'TIMES_OF_DAY'), 'filter' => array('=REITERATE' => 'Y', '=MAILING.ACTIVE' => 'Y', 'STATUS' => MailingChainTable::STATUS_WAIT))); while ($arMailingChain = $chainDb->fetch()) { $lastExecuted = $arMailingChain['LAST_EXECUTED']; /* @var \Bitrix\Main\Type\DateTime $lastExecuted*/ if ($lastExecuted && $lastExecuted->getTimestamp() >= $dateToday->getTimestamp()) { continue; } $timeOfExecute = static::getDateExecute($dateTodayPhp, $arMailingChain["DAYS_OF_MONTH"], $arMailingChain["DAYS_OF_WEEK"], $arMailingChain["TIMES_OF_DAY"]); if ($timeOfExecute) { $arUpdateMailChain = array('LAST_EXECUTED' => $datetimeToday); $postingDb = PostingTable::getList(array('select' => array('ID'), 'filter' => array('=MAILING_CHAIN_ID' => $arMailingChain['ID'], '><DATE_CREATE' => $arDateFilter))); $arPosting = $postingDb->fetch(); if (!$arPosting) { $postingId = MailingChainTable::initPosting($arMailingChain['ID']); } else { $postingId = $arPosting['ID']; $arUpdateMailChain['POSTING_ID'] = $postingId; PostingTable::initGroupRecipients($postingId); } if ($postingId) { $arUpdateMailChain['STATUS'] = MailingChainTable::STATUS_SEND; $arUpdateMailChain['AUTO_SEND_TIME'] = Type\DateTime::createFromPhp($timeOfExecute); } MailingChainTable::update(array('ID' => $arMailingChain['ID']), $arUpdateMailChain); } } return static::getAgentNamePeriod(); }
public static function updateChainTrigger($id) { // get first item of chain $chainDb = MailingChainTable::getList(array('select' => array('ID', 'TRIGGER_FIELDS' => 'MAILING.TRIGGER_FIELDS'), 'filter' => array('=MAILING_ID' => $id, '=IS_TRIGGER' => 'Y', '=PARENT_ID' => null))); $chain = $chainDb->fetch(); if (!$chain) { return; } $chainId = $chain['ID']; // get trigger settings from mailing $triggerFields = $chain['TRIGGER_FIELDS']; if (!is_array($triggerFields)) { $triggerFields = array(); } // init TriggerSettings objects $settingsList = array(); foreach ($triggerFields as $key => $point) { if (empty($point['CODE'])) { continue; } $point['IS_EVENT_OCCUR'] = true; $point['IS_PREVENT_EMAIL'] = false; $point['SEND_INTERVAL_UNIT'] = 'M'; $point['IS_CLOSED_TRIGGER'] = $point['IS_CLOSED_TRIGGER'] == 'Y' ? true : false; switch ($key) { case 'END': $point['IS_TYPE_START'] = false; break; case 'START': default: $point['IS_TYPE_START'] = true; } $settingsList[] = new \Bitrix\Sender\TriggerSettings($point); } // prepare fields for save $mailingTriggerList = array(); foreach ($settingsList as $settings) { /* @var \Bitrix\Sender\TriggerSettings $settings */ $trigger = \Bitrix\Sender\TriggerManager::getOnce($settings->getEndpoint()); if ($trigger) { $triggerFindId = $trigger->getFullEventType() . "/" . (int) $settings->isTypeStart(); $mailingTriggerList[$triggerFindId] = array('IS_TYPE_START' => $settings->isTypeStart(), 'NAME' => $trigger->getName(), 'EVENT' => $trigger->getFullEventType(), 'ENDPOINT' => $settings->getArray()); } } // add new, update exists, delete old rows $triggerDb = MailingTriggerTable::getList(array('select' => array('EVENT', 'MAILING_CHAIN_ID', 'IS_TYPE_START'), 'filter' => array('=MAILING_CHAIN_ID' => $chainId))); while ($trigger = $triggerDb->fetch()) { $triggerFindId = $trigger['EVENT'] . "/" . (int) $trigger['IS_TYPE_START']; if (!isset($mailingTriggerList[$triggerFindId])) { MailingTriggerTable::delete($trigger); } else { MailingTriggerTable::update($trigger, $mailingTriggerList[$triggerFindId]); unset($mailingTriggerList[$triggerFindId]); } } foreach ($mailingTriggerList as $triggerFindId => $settings) { $settings['MAILING_CHAIN_ID'] = $chainId; MailingTriggerTable::add($settings); } TriggerManager::actualizeHandlerForChild(); }
$arError[] = GetMessage("rub_save_error"); } if (!empty($arError)) { $message = new CAdminMessage(implode('<br>', $arError)); } $bVarsFromForm = true; } } //Edit/Add part ClearVars(); $str_SORT = 100; $str_ACTIVE = "Y"; $str_VISIBLE = "Y"; $arMailngChainAttachment = array(); if ($ID > 0) { $rubric = new CDBResult(\Bitrix\Sender\MailingChainTable::getList(array('select' => array('*'), 'filter' => array('ID' => $ID)))); if (!$rubric->ExtractFields("str_")) { $ID = 0; } if ($ID > 0) { $postingDb = \Bitrix\Sender\PostingTable::getList(array('select' => array('*'), 'filter' => array('ID' => $ID, '!DATE_SENT' => null), 'order' => array('DATE_SENT' => 'DESC'), 'limit' => 1)); $arPosting = $postingDb->fetch(); $str_DATE_SENT = $arPosting['DATE_SENT']; $attachmentFileDb = \Bitrix\Sender\MailingAttachmentTable::getList(array('select' => array('FILE_ID'), 'filter' => array('CHAIN_ID' => $ID))); while ($ar = $attachmentFileDb->fetch()) { if ($arFileFetch = CFile::GetFileArray($ar['FILE_ID'])) { $arMailngChainAttachment[] = $arFileFetch; } } } }
/** * @param $mailingChainId * @param array $arParams * @return string * @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\DB\Exception */ protected static function sendInternal($mailingChainId, array $arParams) { if (static::$currentMailingChainFields !== null) { if (static::$currentMailingChainFields['ID'] != $mailingChainId) { static::$currentMailingChainFields = null; } } if (static::$currentMailingChainFields === null) { $mailingChainDb = MailingChainTable::getList(array('select' => array('*', 'SITE_ID' => 'MAILING.SITE_ID'), 'filter' => array('ID' => $mailingChainId))); if (!($arMailingChain = $mailingChainDb->fetch())) { return PostingRecipientTable::SEND_RESULT_ERROR; } $charset = false; $siteDb = \Bitrix\Main\SiteTable::getList(array('select' => array('NAME', 'CULTURE_CHARSET' => 'CULTURE.CHARSET'), 'filter' => array('LID' => $arMailingChain['SITE_ID']))); if ($arSiteDb = $siteDb->fetch()) { $charset = $arSiteDb['CULTURE_CHARSET']; } else { throw new \Bitrix\Main\DB\Exception(Loc::getMessage('SENDER_POSTING_MANAGER_ERR_SITE', array('#SITE_ID#' => $arMailingChain['SITE_ID']))); } if (!$charset) { throw new \Bitrix\Main\DB\Exception(Loc::getMessage('SENDER_POSTING_MANAGER_ERR_CHARSET', array('#SITE_ID#' => "[" . $arMailingChain['SITE_ID'] . "]" . $arSiteDb['NAME']))); } static::$currentMailingChainFields = array(); static::$currentMailingChainFields['ID'] = $arMailingChain['ID']; static::$currentMailingChainFields['MESSAGE'] = array('BODY_TYPE' => 'html', 'EMAIL_FROM' => $arMailingChain['EMAIL_FROM'], 'EMAIL_TO' => '#EMAIL_TO#', 'SUBJECT' => $arMailingChain['SUBJECT'], 'MESSAGE' => $arMailingChain['MESSAGE'], 'MESSAGE_PHP' => \Bitrix\Main\Mail\Internal\EventMessageTable::replaceTemplateToPhp($arMailingChain['MESSAGE'])); static::$currentMailingChainFields['SITE'] = array($arMailingChain['SITE_ID']); static::$currentMailingChainFields['CHARSET'] = $charset; } $arMessageParams = array('FIELDS' => $arParams['FIELDS'], 'MESSAGE' => static::$currentMailingChainFields['MESSAGE'], 'SITE' => static::$currentMailingChainFields['SITE'], 'CHARSET' => static::$currentMailingChainFields['CHARSET']); $message = Mail\EventMessageCompiler::createInstance($arMessageParams); $message->compile(); // send mail $result = Mail\Mail::send(array('TO' => $message->getMailTo(), 'SUBJECT' => $message->getMailSubject(), 'BODY' => $message->getMailBody(), 'HEADER' => $message->getMailHeaders(), 'CHARSET' => $message->getMailCharset(), 'CONTENT_TYPE' => $message->getMailContentType(), 'MESSAGE_ID' => '', 'ATTACHMENT' => $message->getMailAttachment(), 'TRACK_READ' => isset($arParams['TRACK_READ']) ? $arParams['TRACK_READ'] : null, 'TRACK_CLICK' => isset($arParams['TRACK_CLICK']) ? $arParams['TRACK_CLICK'] : null)); if ($result) { return PostingRecipientTable::SEND_RESULT_SUCCESS; } else { return PostingRecipientTable::SEND_RESULT_ERROR; } }
/** * @param \Bitrix\Main\Event $event * @return void */ public static function onAfterPostingSendRecipient(\Bitrix\Main\Event $event) { $data = $event->getParameter(0); if (!$data || !$data['SEND_RESULT'] || empty($data['POSTING']['MAILING_CHAIN_ID'])) { return; } $chainId = $data['POSTING']['MAILING_CHAIN_ID']; $dataRecipient = $data['RECIPIENT']; static $mailingParams = array(); if (!isset($mailingParams[$chainId])) { $mailingParams[$chainId] = array(); $childChainDb = MailingChainTable::getList(array('select' => array('ID', 'MAILING_ID', 'PARENT_ID', 'POSTING_ID'), 'filter' => array('=MAILING.ACTIVE' => 'Y', '=IS_TRIGGER' => 'Y', '=STATUS' => array(MailingChainTable::STATUS_WAIT, MailingChainTable::STATUS_SEND), '=PARENT_ID' => $chainId))); while ($childChain = $childChainDb->fetch()) { // add posting $postingAddDb = PostingTable::add(array('MAILING_ID' => $childChain['MAILING_ID'], 'MAILING_CHAIN_ID' => $childChain['ID'])); if (!$postingAddDb->isSuccess()) { continue; } $mailingParams[$chainId][] = array('POSTING_ID' => $postingAddDb->getId(), 'CHAIN' => $childChain); } } if (empty($mailingParams[$chainId])) { return; } foreach ($mailingParams[$chainId] as $mailingParamsItem) { $postingId = $mailingParamsItem['POSTING_ID']; $childChain = $mailingParamsItem['CHAIN']; // check email as unsubscribed if (Subscription::isUnsubscibed($childChain['MAILING_ID'], $data['RECIPIENT']['EMAIL'])) { continue; } $recipient = array('POSTING_ID' => $postingId); $recipient['STATUS'] = PostingRecipientTable::SEND_RESULT_NONE; $recipient['EMAIL'] = $dataRecipient['EMAIL']; if (!empty($dataRecipient['FIELDS'])) { $recipient['FIELDS'] = $dataRecipient['FIELDS']; } if (!empty($dataRecipient['ROOT_ID'])) { $recipient['ROOT_ID'] = $dataRecipient['ROOT_ID']; } else { $recipient['ROOT_ID'] = $dataRecipient['ID']; } if (!empty($dataRecipient['NAME'])) { $recipient['NAME'] = $dataRecipient['NAME']; } if (!empty($dataRecipient['USER_ID'])) { $recipient['USER_ID'] = $dataRecipient['USER_ID']; } // add recipient PostingTable::addRecipient($recipient, true); if (empty($mailingParams[$chainId]['CHAIN']['POSTING_ID'])) { $chainUpdateDb = MailingChainTable::update(array('ID' => $childChain['ID']), array('POSTING_ID' => $postingId)); if ($chainUpdateDb->isSuccess()) { $mailingParams[$chainId]['CHAIN']['POSTING_ID'] = $postingId; } } } }
/** * Send posting. * * @param $id * @param int $timeout * @param int $maxMailCount * @return bool|string * @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\DB\Exception * @throws \Bitrix\Main\Db\SqlQueryException * @throws \Exception */ public static function send($id, $timeout = 0, $maxMailCount = 0) { $start_time = getmicrotime(); @set_time_limit(0); static::$emailSentPerIteration = 0; $postingDb = PostingTable::getList(array('select' => array('ID', 'STATUS', 'MAILING_ID', 'MAILING_CHAIN_ID', 'MAILING_CHAIN_REITERATE' => 'MAILING_CHAIN.REITERATE', 'MAILING_CHAIN_IS_TRIGGER' => 'MAILING_CHAIN.IS_TRIGGER'), 'filter' => array('=ID' => $id, '=MAILING.ACTIVE' => 'Y', '=MAILING_CHAIN.STATUS' => MailingChainTable::STATUS_SEND))); $postingData = $postingDb->fetch(); // posting not found if (!$postingData) { return static::SEND_RESULT_ERROR; } // if posting in new status, then import recipients from groups and set right status for sending $isInitGroupRecipients = false; $isChangeStatusToPart = false; if ($postingData["STATUS"] == PostingTable::STATUS_NEW) { $isInitGroupRecipients = true; $isChangeStatusToPart = true; } if ($postingData["STATUS"] != PostingTable::STATUS_PART && $postingData["MAILING_CHAIN_IS_TRIGGER"] == 'Y') { $isInitGroupRecipients = false; $isChangeStatusToPart = true; } if ($isInitGroupRecipients) { PostingTable::initGroupRecipients($postingData['ID']); } if ($isChangeStatusToPart) { PostingTable::update(array('ID' => $postingData['ID']), array('STATUS' => PostingTable::STATUS_PART)); $postingData["STATUS"] = PostingTable::STATUS_PART; } // posting not in right status if ($postingData["STATUS"] != PostingTable::STATUS_PART) { return static::SEND_RESULT_ERROR; } // lock posting for exclude double parallel sending if (static::lockPosting($id) === false) { throw new \Bitrix\Main\DB\Exception(Loc::getMessage('SENDER_POSTING_MANAGER_ERR_LOCK')); } $isStopped = false; $checkStatusCounter = 0; static::$checkStatusStep = intval(Option::get('sender', 'send_check_status_step', static::$checkStatusStep)); // select all recipients of posting, only not processed $recipientDataDb = PostingRecipientTable::getList(array('filter' => array('=POSTING_ID' => $postingData['ID'], '=STATUS' => PostingRecipientTable::SEND_RESULT_NONE), 'limit' => $maxMailCount)); while ($recipientData = $recipientDataDb->fetch()) { // check pause or stop status if (++$checkStatusCounter >= static::$checkStatusStep) { $checkStatusDb = MailingChainTable::getList(array('select' => array('ID'), 'filter' => array('=ID' => $postingData["MAILING_CHAIN_ID"], '=STATUS' => MailingChainTable::STATUS_SEND))); if (!$checkStatusDb->fetch()) { break; } $checkStatusCounter = 0; } // create name from email $recipientEmail = $recipientData["EMAIL"]; if (empty($recipientData["NAME"])) { $recipientEmailParts = explode('@', $recipientEmail); $recipientName = $recipientEmailParts[0]; } else { $recipientName = $recipientData["NAME"]; } // prepare params for send $sendParams = array('FIELDS' => array('EMAIL_TO' => $recipientEmail, 'NAME' => $recipientName, 'USER_ID' => $recipientData["USER_ID"], 'SENDER_CHAIN_ID' => $postingData["MAILING_CHAIN_ID"], 'SENDER_CHAIN_CODE' => 'sender_chain_item_' . $postingData["MAILING_CHAIN_ID"], 'UNSUBSCRIBE_LINK' => Subscription::getLinkUnsub(array('MAILING_ID' => $postingData['MAILING_ID'], 'EMAIL' => $recipientEmail, 'RECIPIENT_ID' => $recipientData["ID"]))), 'TRACK_READ' => array('MODULE_ID' => "sender", 'FIELDS' => array('RECIPIENT_ID' => $recipientData["ID"])), 'TRACK_CLICK' => array('MODULE_ID' => "sender", 'FIELDS' => array('RECIPIENT_ID' => $recipientData["ID"]), 'URL_PARAMS' => array('bx_sender_conversion_id' => $recipientData["ID"]))); if (is_array($recipientData['FIELDS']) && count($recipientData) > 0) { $sendParams['FIELDS'] = $sendParams['FIELDS'] + $recipientData['FIELDS']; } // set sending result to recipient try { $mailSendResult = static::sendInternal($postingData['MAILING_CHAIN_ID'], $sendParams); } catch (\Bitrix\Main\Mail\StopException $e) { $isStopped = true; break; } PostingRecipientTable::update(array('ID' => $recipientData["ID"]), array('STATUS' => $mailSendResult, 'DATE_SENT' => new Type\DateTime())); // send event $eventData = array('SEND_RESULT' => $mailSendResult == PostingRecipientTable::SEND_RESULT_SUCCESS, 'RECIPIENT' => $recipientData, 'POSTING' => $postingData); $event = new Event('sender', 'OnAfterPostingSendRecipient', array($eventData)); $event->send(); // limit executing script by time if ($timeout > 0 && getmicrotime() - $start_time >= $timeout) { break; } // increment sending statistic static::$emailSentPerIteration++; } //set status and delivered and error emails $statusList = PostingTable::getRecipientCountByStatus($id); if ($isStopped) { $STATUS = PostingTable::STATUS_ABORT; $DATE = new Type\DateTime(); } elseif (!array_key_exists(PostingRecipientTable::SEND_RESULT_NONE, $statusList)) { if (array_key_exists(PostingRecipientTable::SEND_RESULT_ERROR, $statusList)) { $STATUS = PostingTable::STATUS_SENT_WITH_ERRORS; } else { $STATUS = PostingTable::STATUS_SENT; } $DATE = new Type\DateTime(); } else { $STATUS = PostingTable::STATUS_PART; $DATE = null; } // unlock posting for exclude double parallel sending static::unlockPosting($id); // update status of posting $postingUpdateFields = array('STATUS' => $STATUS, 'DATE_SENT' => $DATE, 'COUNT_SEND_ALL' => 0); $recipientStatusToPostingFieldMap = PostingTable::getRecipientStatusToPostingFieldMap(); foreach ($recipientStatusToPostingFieldMap as $recipientStatus => $postingFieldName) { if (!array_key_exists($recipientStatus, $statusList)) { $postingCountFieldValue = 0; } else { $postingCountFieldValue = $statusList[$recipientStatus]; } $postingUpdateFields['COUNT_SEND_ALL'] += $postingCountFieldValue; $postingUpdateFields[$postingFieldName] = $postingCountFieldValue; } PostingTable::update(array('ID' => $id), $postingUpdateFields); // return status to continue or end of sending if ($STATUS == PostingTable::STATUS_PART) { return static::SEND_RESULT_CONTINUE; } else { return static::SEND_RESULT_SENT; } }