public function sendMessageAction($data)
{
/*
* @TODO: The old code has been moved to the controller. Refactor later
*/
if(!$this->checkModules())
{
return false;
}
if (!\CCrmPerms::IsAccessEnabled())
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_PERMISSION_DENIED')));
return false;
}
$ID = isset($data['ID']) ? intval($data['ID']) : 0;
$isNew = $ID <= 0;
$userID = \CCrmSecurityHelper::GetCurrentUser()->GetID();
$responsibleId = (int) $userID;
$mailboxOwnerId = null;
if ($userID <= 0)
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_USER_NOT_FOUND')));
return false;
}
$now = convertTimeStamp(time() + \CTimeZone::getOffset(), 'FULL', SITE_ID);
$subject = isset($data['subject']) ? strval($data['subject']) : '';
if ($subject == '')
{
$subject = Loc::getMessage('CRM_MAIL_CONTROLLER_MESSAGE_DEFAULT_SUBJECT', ['#DATE#'=> $now]);
}
$arErrors = [];
$socNetLogDestTypes = [
\CCrmOwnerType::LeadName => 'leads',
\CCrmOwnerType::DealName => 'deals',
\CCrmOwnerType::ContactName => 'contacts',
\CCrmOwnerType::CompanyName => 'companies',
];
$acceptableTypes = [
\CCrmOwnerType::LeadName,
\CCrmOwnerType::DealName,
\CCrmOwnerType::ContactName,
\CCrmOwnerType::CompanyName,
];
$to = array();
$cc = array();
$bcc = array();
$countCc = 0;
$countBcc = 0;
$countTo = 0;
// Bindings & Communications -->
$arBindings = array();
$arComms = array();
$commData = $data['communications'] ?? [];
foreach (array('to', 'cc', 'bcc') as $field)
{
if (!empty($data[$field]) && is_array($data[$field]))
{
foreach ($data[$field] as $item)
{
try
{
$item = \Bitrix\Main\Web\Json::decode($item);
if (!in_array($item['entityType'], $acceptableTypes, true))
{
$item['entityType'] = array_search($item['entityType'], $socNetLogDestTypes);
}
$item['type'] = 'EMAIL';
$item['value'] = $item['email'];
$item['__field'] = $field;
$commData[] = $item;
if($field === 'to')
{
$countTo++;
}
else if($field === 'cc')
{
$countCc++;
}
else if($field === 'bcc')
{
$countBcc++;
}
}
catch (\Exception $e)
{
}
}
}
}
$emailsLimitToSendMessage = Helper\LicenseManager::getEmailsLimitToSendMessage();
if($emailsLimitToSendMessage !== -1 && ($countTo > $emailsLimitToSendMessage || $countCc > $emailsLimitToSendMessage || $countBcc > $emailsLimitToSendMessage))
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_TARIFF_RESTRICTION',["#COUNT#" => $emailsLimitToSendMessage])));
return false;
}
if (count($commData) > 10)
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_MESSAGE_TO_MANY_RECIPIENTS')));
return false;
}
$sourceList = \CCrmStatus::getStatusList('SOURCE');
if (isset($sourceList['EMAIL']))
{
$sourceId = 'EMAIL';
}
else if (isset($sourceList['OTHER']))
{
$sourceId = 'OTHER';
}
$contactTypes = \CCrmStatus::getStatusList('CONTACT_TYPE');
if (isset($contactTypes['CLIENT']))
{
$contactType = 'CLIENT';
}
else if (isset($contactTypes['OTHER']))
{
$contactType = 'OTHER';
}
foreach ($commData as &$commDatum)
{
$commID = isset($commData['id']) ? intval($commData['id']) : 0;
$commEntityType = isset($commDatum['entityType'])? mb_strtoupper(strval($commDatum['entityType'])) : '';
$commEntityID = isset($commDatum['entityId']) ? intval($commDatum['entityId']) : 0;
$commType = isset($commDatum['type'])? mb_strtoupper(strval($commDatum['type'])) : '';
if($commType === '')
{
$commType = 'EMAIL';
}
$commValue = isset($commDatum['value']) ? strval($commDatum['value']) : '';
if($commType === 'EMAIL' && $commValue !== '')
{
if(!check_email($commValue))
{
$arErrors[] = new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_MESSAGE_INVALID_EMAIL', ['#VALUE#' => $commValue]));
continue;
}
$rcptFieldName = 'to';
if (isset($commDatum['__field']))
{
$commDatum['__field'] = mb_strtolower($commDatum['__field']);
if (in_array($commDatum['__field'], array('to', 'cc', 'bcc')))
$rcptFieldName = $commDatum['__field'];
}
${$rcptFieldName}[] = mb_strtolower(trim($commValue));
}
if (isset($commDatum['isEmail']) && $commDatum['isEmail'] == 'Y' && mb_strtolower(trim($commValue)))
{
$newEntityTypeId = \Bitrix\Crm\Settings\ActivitySettings::getCurrent()->getOutgoingEmailOwnerTypeId();
if (\CCrmOwnerType::Contact == $newEntityTypeId && \CCrmContact::checkCreatePermission())
{
$contactFields = array(
'NAME' => $commDatum['params']['name'] ?? '',
'LAST_NAME' => $commDatum['params']['lastName'] ?? '',
'RESPONSIBLE_ID' => $userID,
'FM' => array(
'EMAIL' => array(
'n1' => array(
'VALUE_TYPE' => 'WORK',
'VALUE' => mb_strtolower(trim($commValue))
)
)
),
);
if ('' != $contactType)
{
$contactFields['TYPE_ID'] = $contactType;
}
if ('' != $sourceId)
{
$contactFields['SOURCE_ID'] = $sourceId;
}
if ($contactFields['NAME'] == '' && $contactFields['LAST_NAME'] == '')
$contactFields['NAME'] = mb_strtolower(trim($commValue));
$contactEntity = new \CCrmContact();
$contactId = $contactEntity->add(
$contactFields, true,
array(
'DISABLE_USER_FIELD_CHECK' => true,
'REGISTER_SONET_EVENT' => true,
'CURRENT_USER' => $userID,
)
);
if ($contactId > 0)
{
$commEntityType = \CCrmOwnerType::ContactName;
$commEntityID = $contactId;
$bizprocErrors = array();
\CCrmBizProcHelper::autostartWorkflows(
\CCrmOwnerType::Contact, $contactId,
\CCrmBizProcEventType::Create,
$bizprocErrors
);
}
}
else if (\CCrmLead::checkCreatePermission())
{
$leadFields = array(
'TITLE' => $subject,
'NAME' => $commDatum['params']['name'] ?? '',
'LAST_NAME' => $commDatum['params']['lastName'] ?? '',
'STATUS_ID' => 'NEW',
'OPENED' => 'Y',
'FM' => array(
'EMAIL' => array(
'n1' => array(
'VALUE_TYPE' => 'WORK',
'VALUE' => mb_strtolower(trim($commValue))
)
)
),
);
if ('' != $sourceId)
{
$leadFields['SOURCE_ID'] = $sourceId;
}
$leadEntity = new \CCrmLead(false);
$leadId = $leadEntity->add(
$leadFields, true,
array(
'DISABLE_USER_FIELD_CHECK' => true,
'REGISTER_SONET_EVENT' => true,
'CURRENT_USER' => $userID,
)
);
if ($leadId > 0)
{
$commEntityType = \CCrmOwnerType::LeadName;
$commEntityID = $leadId;
$bizprocErrors = [];
\CCrmBizProcHelper::autostartWorkflows(
\CCrmOwnerType::Lead, $leadId,
\CCrmBizProcEventType::Create,
$bizprocErrors
);
$starter = new \Bitrix\Crm\Automation\Starter(\CCrmOwnerType::Lead, $leadId);
$starter->setUserIdFromCurrent()->runOnAdd();
}
}
}
$key = md5(sprintf(
'%s_%u_%s_%s',
$commEntityType,
$commEntityID,
$commType,
mb_strtolower(trim($commValue))
));
$arComms[$key] = array(
'ID' => $commID,
'TYPE' => $commType,
'VALUE' => $commValue,
'ENTITY_ID' => $commEntityID,
'ENTITY_TYPE_ID' => \CCrmOwnerType::ResolveID($commEntityType)
);
if($commEntityType !== '')
{
$bindingKey = $commEntityID > 0 ? "{$commEntityType}_{$commEntityID}" : uniqid("{$commEntityType}_");
if(!isset($arBindings[$bindingKey]))
{
$arBindings[$bindingKey] = array(
'OWNER_TYPE_ID' => \CCrmOwnerType::ResolveID($commEntityType),
'OWNER_ID' => $commEntityID
);
}
}
}
unset($commDatum);
$to = array_unique($to);
$cc = array_unique($cc);
$bcc = array_unique($bcc);
$blackListed =
Mail\Internal\BlacklistTable::query()
->setSelect(["CODE"])
->whereIn("CODE",$array = array_merge_recursive($to,$cc,$bcc))
->exec()
->fetchAll()
;
if (!empty($blackListed = array_column($blackListed,"CODE")))
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_EMAILS_IN_BLACKLISTED', ['#EMAILS#' => implode("; ",$blackListed)])));
return false;
}
elseif (empty($to))
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_MESSAGE_EMPTY_TO_FIELD')));
return false;
}
elseif (!empty($arErrors))
{
$this->addErrors($arErrors);
return false;
}
$ownerTypeName = isset($data['ownerType'])? mb_strtoupper(strval($data['ownerType'])) : '';
$ownerTypeID = !empty($ownerTypeName) ? \CCrmOwnerType::resolveId($ownerTypeName) : 0;
$ownerID = isset($data['ownerId']) ? intval($data['ownerId']) : 0;
$bindData = $data['bindings'] ?? [];
if (!empty($data['docs']) && is_array($data['docs']))
{
foreach ($data['docs'] as $item)
{
try
{
$item = \Bitrix\Main\Web\Json::decode($item);
$item['entityType'] = array_search($item['entityType'], $socNetLogDestTypes);
$bindData[] = $item;
}
catch (\Exception $e)
{
}
}
}
foreach ($bindData as $item)
{
$item['entityTypeId'] = \CCrmOwnerType::resolveID($item['entityType']);
if ($item['entityTypeId'] > 0 && $item['entityId'] > 0)
{
$key = sprintf('%u_%u', $item['entityType'], $item['entityId']);
if (\CCrmOwnerType::Deal == $item['entityTypeId'] && !isset($arBindings[$key]))
{
$ownerTypeName = \CCrmOwnerType::resolveName($item['entityTypeId']);
$ownerTypeID = $item['entityTypeId'];
$ownerID = (int) $item['entityId'];
$arBindings[$key] = array(
'OWNER_TYPE_ID' => $item['entityTypeId'],
'OWNER_ID' => $item['entityId']
);
}
}
}
$nonRcptOwnerTypes = array(
\CCrmOwnerType::Lead,
\CCrmOwnerType::Order,
\CCrmOwnerType::Deal,
\CCrmOwnerType::DealRecurring,
\CCrmOwnerType::Quote,
);
if (
'Y' !== ($data['ownerRcpt'] ?? null)
&& (in_array($ownerTypeID, $nonRcptOwnerTypes) || \CCrmOwnerType::isUseDynamicTypeBasedApproach($ownerTypeID))
&& $ownerID > 0
)
{
$key = sprintf('%s_%u', $ownerTypeName, $ownerID);
if (!isset($arBindings[$key]))
{
$arBindings[$key] = array(
'OWNER_TYPE_ID' => $ownerTypeID,
'OWNER_ID' => $ownerID,
);
}
}
$ownerBinded = false;
if ($ownerTypeID > 0 && $ownerID > 0)
{
foreach ($arBindings as $item)
{
if ($ownerTypeID == $item['OWNER_TYPE_ID'] && $ownerID == $item['OWNER_ID'])
{
$ownerBinded = true;
break;
}
}
}
if ($ownerBinded)
{
$checkedOwnerType = $ownerTypeID;
if ($ownerTypeID == \CCrmOwnerType::DealRecurring)
{
$checkedOwnerType = \CCrmOwnerType::Deal;
}
if (!\CCrmActivity::checkUpdatePermission($checkedOwnerType, $ownerID))
{
$errorMsg = Loc::getMessage('CRM_MAIL_CONTROLLER_PERMISSION_DENIED');
$entityTitle = \CCrmOwnerType::getCaption($ownerTypeID, $ownerID, false);
if (\CCrmOwnerType::Contact == $ownerTypeID)
$errorMsg = Loc::getMessage('CRM_MAIL_CONTROLLER_CONTACT_UPDATE_PERMISSION_DENIED', array('#TITLE#' => $entityTitle));
else if (\CCrmOwnerType::Company == $ownerTypeID)
$errorMsg = Loc::getMessage('CRM_MAIL_CONTROLLER_COMPANY_UPDATE_PERMISSION_DENIED', array('#TITLE#' => $entityTitle));
else if (\CCrmOwnerType::Lead == $ownerTypeID)
$errorMsg = Loc::getMessage('CRM_MAIL_CONTROLLER_LEAD_UPDATE_PERMISSION_DENIED', array('#TITLE#' => $entityTitle));
else if (\CCrmOwnerType::Deal == $ownerTypeID || \CCrmOwnerType::DealRecurring == $ownerTypeID)
$errorMsg = Loc::getMessage('CRM_MAIL_CONTROLLER_DEAL_UPDATE_PERMISSION_DENIED', array('#TITLE#' => $entityTitle));
$this->addError(new Error($errorMsg));
return false;
}
}
else
{
$ownerTypeID = 0;
$ownerID = 0;
$typesPriority = array(
\CCrmOwnerType::Deal => 1,
\CCrmOwnerType::Order => 2,
\CCrmOwnerType::Contact => 3,
\CCrmOwnerType::Company => 4,
\CCrmOwnerType::Lead => 5,
);
foreach ($arBindings as $item)
{
if ($ownerTypeID <= 0 || $typesPriority[$item['OWNER_TYPE_ID']] < $typesPriority[$ownerTypeID])
{
if (\CCrmActivity::checkUpdatePermission($item['OWNER_TYPE_ID'], $item['OWNER_ID']))
{
$ownerTypeID = $item['OWNER_TYPE_ID'];
$ownerID = $item['OWNER_ID'];
$ownerBinded = true;
}
}
}
if (!$ownerBinded)
{
$this->addError(new Error(Loc::getMessage(
empty($arBindings)
? 'CRM_MAIL_CONTROLLER_MESSAGE_EMAIL_EMPTY_TO_FIELD'
: 'CRM_MAIL_CONTROLLER_PERMISSION_DENIED'
)));
return false;
}
}
// single deal binding
$dealBinded = \CCrmOwnerType::Deal == $ownerTypeID;
foreach ($arBindings as $key => $item)
{
if (\CCrmOwnerType::Deal == $item['OWNER_TYPE_ID'])
{
if ($dealBinded)
unset($arBindings[$key]);
$dealBinded = true;
}
}
$crmEmail = \CCrmMailHelper::extractEmail(\COption::getOptionString('crm', 'mail', ''));
$from = '';
$reply = '';
$rawCc = $cc;
if (isset($data['from']))
$from = trim(strval($data['from']));
if ($from == '')
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_MESSAGE_EMAIL_EMPTY_FROM_FIELD')));
return false;
}
else
{
$fromEmail = $from;
$fromAddress = new \Bitrix\Main\Mail\Address($fromEmail);
if ($fromAddress->validate())
{
$fromEmail = $fromAddress->getEmail();
\CBitrixComponent::includeComponentClass('bitrix:main.mail.confirm');
if (!in_array($fromEmail, array_column(\MainMailConfirmComponent::prepareMailboxes(), 'email')))
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_MESSAGE_EMAIL_PERMISSION_DENIED_FROM_FIELD')));
return false;
}
if ($fromAddress->getName())
{
$fromEncoded = sprintf(
'%s <%s>',
sprintf('=?%s?B?%s?=', SITE_CHARSET, base64_encode($fromAddress->getName())),
$fromEmail
);
}
}
else
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_MESSAGE_INVALID_EMAIL', ['#VALUE#' => $from])));
return false;
}
if (\CModule::includeModule('mail'))
{
/**
* @todo Explicitly enter the ID. This will increase the productivity of selection.
*/
$mailboxHelper = \Bitrix\Mail\Helper\Mailbox::findBy(null, $fromEmail);
if (!empty($mailboxHelper))
{
$mailboxOwnerId = $mailboxHelper->getMailboxOwnerId();
}
}
if (empty($mailboxHelper))
{
if ($crmEmail != '' && $crmEmail != $fromEmail)
{
$reply = $fromEmail . ', ' . $crmEmail;
}
$injectUrn = true;
}
if ('Y' === ($data['from_copy'] ?? null))
{
$cc[] = $fromEmail;
}
}
$messageBody = '';
$contentType = isset($data['content_type']) && \CCrmContentType::isDefined($data['content_type'])
? (int)$data['content_type'] : \CCrmContentType::BBCode;
$parentId = isset($data['REPLIED_ID']) ? (int)$data['REPLIED_ID'] : 0;
$messageQuote = '';
if ($parentId > 0)
{
$messageQuote = $this->getMessageAsQuote($parentId);
}
if (isset($data['message']))
{
$messageBody = (string)$data['message'];
if (\CCrmContentType::Html == $contentType)
{
$messageBody = Helper\Message::sanitizeHtml($messageBody);
}
else
{
if (\CCrmContentType::PlainText == $contentType)
{
$messageBody = sprintf(
'%s',
preg_replace('/[\r\n]+/' . BX_UTF_PCRE_MODIFIER, '
', htmlspecialcharsbx($messageBody))
);
}
elseif (\CCrmContentType::BBCode == $contentType)
{
//Convert BBCODE to HTML
$parser = new \CTextParser();
$parser->allow['SMILES'] = 'N';
$messageBody = '' . $parser->convertText($messageBody) . '';
}
}
}
$messageBody = nl2br($messageBody);
$messageBody .= $messageQuote;
if (($messageHtml = $messageBody) != '')
{
\CCrmActivity::addEmailSignature($messageHtml, \CCrmContentType::Html);
}
if ($parentId > 0 && !$dealBinded)
{
$parentBindings = \CCrmActivity::getBindings($parentId);
foreach ($parentBindings as $item)
{
$key = sprintf('%u_%u', \CCrmOwnerType::resolveName($item['OWNER_TYPE_ID']), $item['OWNER_ID']);
if (\CCrmOwnerType::Deal == $item['OWNER_TYPE_ID'] && !isset($arBindings[$key]))
{
$arBindings[$key] = array(
'OWNER_TYPE_ID' => $item['OWNER_TYPE_ID'],
'OWNER_ID' => $item['OWNER_ID'],
);
break;
}
}
}
$arBindings = array_merge(
array(
sprintf('%u_%u', \CCrmOwnerType::resolveName($ownerTypeID), $ownerID) => array(
'OWNER_TYPE_ID' => $ownerTypeID,
'OWNER_ID' => $ownerID,
),
),
$arBindings
);
$arFields = [
'OWNER_ID' => $ownerID,
'OWNER_TYPE_ID' => $ownerTypeID,
'TYPE_ID' => \CCrmActivityType::Email,
'SUBJECT' => $subject,
'START_TIME' => $now,
'END_TIME' => $now,
'COMPLETED' => 'Y',
'AUTHOR_ID' => $mailboxOwnerId,
'RESPONSIBLE_ID' => $responsibleId,
'EDITOR_ID' => $responsibleId,
'PRIORITY' => !empty($data['important']) ? \CCrmActivityPriority::High : \CCrmActivityPriority::Medium,
'DESCRIPTION' => ($description = $messageHtml),
'DESCRIPTION_TYPE' => \CCrmContentType::Html,
'DIRECTION' => \CCrmActivityDirection::Outgoing,
'LOCATION' => '',
'NOTIFY_TYPE' => \CCrmActivityNotifyType::None,
'BINDINGS' => array_values($arBindings),
'COMMUNICATIONS' => $arComms,
'PARENT_ID' => $parentId,
];
$arFileIDs = [];
$storageTypeID = \CCrmActivityStorageType::Disk;
$arFields['STORAGE_TYPE_ID'] = $storageTypeID;
$fileTokens = isset($data['fileTokens']) && is_array($data['fileTokens']) ? $data['fileTokens'] : [];
$currentFilesIds = array_values(
array_unique(
array_filter(
array_map(static function($item) {
if (is_numeric($item))
{
return (int) $item;
}
}, $fileTokens)
)
)
);
$pendingFilesIds = array_values(
array_unique(
array_filter(
array_map(static function($item) {
if (!is_numeric($item) && is_string($item))
{
return $item;
}
}, $fileTokens)
)
)
);
$fileController = new Uploader(
new \Bitrix\Crm\FileUploader\MailUploaderController([
'ownerId' => (int) $data['ownerId'],
'ownerType' => $data['ownerType'],
])
);
if(count($currentFilesIds))
{
$currentFilesIds = $this->checkMessageBFileIds(
$parentId,
new ItemIdentifier(\CCrmOwnerType::resolveId($data['ownerType']), (int)$data['ownerId']),
$currentFilesIds
);
}
$pendingFiles = $fileController->getPendingFiles($pendingFilesIds);
foreach ($currentFilesIds as $id)
{
$copyFileId = \CFile::CloneFile($id);
$fileData = \CFile::getFileArray($copyFileId);
if($fileData)
{
$diskFileId = \Bitrix\Crm\Integration\DiskManager::saveFile($fileData);
if($diskFileId)
{
$arFileIDs[] = $diskFileId;
}
}
}
foreach ($pendingFiles as $pendingFile)
{
$fileData = \CFile::getFileArray($pendingFile->getFileId());
if($fileData)
{
$diskFileId = \Bitrix\Crm\Integration\DiskManager::saveFile($fileData);
if($diskFileId)
{
$pendingFile->makePersistent();
$arFileIDs[] = $diskFileId;
}
else
{
$pendingFile->remove();
}
}
else
{
$this->addError(new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_ERROR_IN_FILES')));
return false;
}
}
$arFileIDs = array_filter($arFileIDs);
if(!empty($arFileIDs) || !$isNew)
{
$arFields['STORAGE_ELEMENT_IDS'] = \Bitrix\Crm\Integration\StorageManager::filterFiles($arFileIDs, $storageTypeID, $userID);
if (!is_array($arFileIDs) || !is_array($arFields['STORAGE_ELEMENT_IDS']))
{
addMessage2Log(
sprintf(
"crm.activity.editor\ajax.php: Invalid email attachments list\r\n(%s) -> (%s)",
$arFileIDs,
$arFields['STORAGE_ELEMENT_IDS']
),
'crm',
0
);
}
else if (count($arFileIDs) > count($arFields['STORAGE_ELEMENT_IDS']))
{
addMessage2Log(
sprintf(
"crm.activity.editor\ajax.php: Email attachments list had been filtered\r\n(%s) -> (%s)",
join(',', $arFileIDs),
join(',', $arFields['STORAGE_ELEMENT_IDS'])
),
'crm',
0
);
}
}
$totalSize = 0;
$arRawFiles = array();
if (isset($arFields['STORAGE_ELEMENT_IDS']) && !empty($arFields['STORAGE_ELEMENT_IDS']))
{
foreach ((array) $arFields['STORAGE_ELEMENT_IDS'] as $item)
{
$arRawFiles[$item] = \Bitrix\Crm\Integration\StorageManager::makeFileArray($item, $storageTypeID);
$totalSize += $arRawFiles[$item]['size'];
if (\CCrmContentType::Html == $contentType)
{
$fileInfo = \Bitrix\Crm\Integration\StorageManager::getFileInfo(
$item, $storageTypeID, false,
array('OWNER_TYPE_ID' => \CCrmOwnerType::Activity, 'OWNER_ID' => $ID)
);
$description = preg_replace(
sprintf('/(https?:\/\/)?bxacid:n?%u/i', $item),
htmlspecialcharsbx($fileInfo['VIEW_URL']),
$description
);
}
}
}
$maxSize = Helper\Message::getMaxAttachedFilesSize();
if ($maxSize > 0 && $maxSize <= ceil($totalSize / 3) * 4) // base64 coef.
{
$this->addError(new Error(Loc::getMessage(
'CRM_MAIL_CONTROLLER_MESSAGE_MAX_SIZE_EXCEED',
['#SIZE#' => \CFile::formatSize(Helper\Message::getMaxAttachedFilesSizeAfterEncoding())]
)));
return false;
}
if ($isNew)
{
if(!($ID = \CCrmActivity::Add($arFields, false, false, array('REGISTER_SONET_EVENT' => true))))
{
$this->addError(new Error(\CCrmActivity::GetLastErrorMessage()));
return false;
}
}
else
{
if(!\CCrmActivity::Update($ID, $arFields, false, false))
{
$this->addError(new Error(\CCrmActivity::GetLastErrorMessage()));
return false;
}
}
$hostname = \COption::getOptionString('main', 'server_name', '') ?: 'localhost';
if (defined('BX24_HOST_NAME') && BX24_HOST_NAME != '')
$hostname = BX24_HOST_NAME;
else if (defined('SITE_SERVER_NAME') && SITE_SERVER_NAME != '')
$hostname = SITE_SERVER_NAME;
$urn = \CCrmActivity::prepareUrn($arFields);
$messageId = sprintf('', $urn, $hostname);
\CCrmActivity::update($ID, array(
'DESCRIPTION' => $description,
'URN' => $urn,
'SETTINGS' => array(
'IS_BATCH_EMAIL' => Config\Option::get('main', 'track_outgoing_emails_read', 'Y') == 'Y' ? false : null,
'MESSAGE_HEADERS' => array(
'Message-Id' => $messageId,
'Reply-To' => $reply ?: $fromEmail,
),
'EMAIL_META' => array(
'__email' => $fromEmail,
'from' => $from,
'replyTo' => $reply,
'to' => join(', ', $to),
'cc' => join(', ', $rawCc),
'bcc' => join(', ', $bcc),
),
),
), false, false, array('REGISTER_SONET_EVENT' => true));
if (!empty($_REQUEST['save_as_template']))
{
$templateFields = array(
'TITLE' => $subject,
'IS_ACTIVE' => 'Y',
'OWNER_ID' => $userID,
'SCOPE' => \CCrmMailTemplateScope::Personal,
'ENTITY_TYPE_ID' => 0,
'EMAIL_FROM' => $from,
'SUBJECT' => $subject,
'BODY_TYPE' => \CCrmContentType::Html,
'BODY' => $messageBody,
'UF_ATTACHMENT' => array_map(
function ($item)
{
return is_scalar($item) ? sprintf('n%u', $item) : $item;
},
$arFields['STORAGE_ELEMENT_IDS']
),
'SORT' => 100,
);
\CCrmMailTemplate::add($templateFields);
}
//Save user email in settings -->
if($from !== \CUserOptions::GetOption('crm', 'activity_email_addresser', ''))
{
\CUserOptions::SetOption('crm', 'activity_email_addresser', $from);
}
//<-- Save user email in settings
if(!empty($arErrors))
{
$this->addErrors($arErrors);
return false;
}
// sending email
$rcpt = array();
$rcptCc = array();
$rcptBcc = array();
foreach ($to as $item)
$rcpt[] = Mail\Mail::encodeHeaderFrom($item, SITE_CHARSET);
foreach ($cc as $item)
$rcptCc[] = Mail\Mail::encodeHeaderFrom($item, SITE_CHARSET);
foreach ($bcc as $item)
$rcptBcc[] = Mail\Mail::encodeHeaderFrom($item, SITE_CHARSET);
$outgoingSubject = $subject;
$outgoingBody = $messageHtml ?: '';
if (!empty($injectUrn))
{
switch (\CCrmEMailCodeAllocation::getCurrent())
{
case \CCrmEMailCodeAllocation::Subject:
$outgoingSubject = \CCrmActivity::injectUrnInSubject($urn, $outgoingSubject);
break;
case \CCrmEMailCodeAllocation::Body:
$outgoingBody = \CCrmActivity::injectUrnInBody($urn, $outgoingBody, 'html');
break;
}
}
$attachments = array();
foreach ($arRawFiles as $key => $item)
{
$contentId = sprintf(
'bxacid.%s@%s.crm',
hash('crc32b', $item['external_id'].$item['size'].$item['name']),
hash('crc32b', $hostname)
);
$attachments[] = array(
'ID' => $contentId,
'NAME' => $item['ORIGINAL_NAME'] ?: $item['name'],
'PATH' => $item['tmp_name'],
'CONTENT_TYPE' => $item['type'],
);
$outgoingBody = preg_replace(
sprintf('/(https?:\/\/)?bxacid:n?%u/i', $key),
sprintf('cid:%s', $contentId),
$outgoingBody
);
}
$outgoingParams = array(
'CHARSET' => 'UTF-8',
'CONTENT_TYPE' => 'html',
'ATTACHMENT' => $attachments,
'TO' => join(', ', $rcpt),
'SUBJECT' => $outgoingSubject,
'BODY' => $outgoingBody,
'HEADER' => array(
'From' => $fromEncoded ?: $fromEmail,
'Reply-To' => $reply ?: $fromEmail,
//'To' => join(', ', $rcpt),
'Cc' => join(', ', $rcptCc),
'Bcc' => join(', ', $rcptBcc),
//'Subject' => $outgoingSubject,
'Message-Id' => $messageId,
),
);
$context = new Mail\Context();
$context->setCategory(Mail\Context::CAT_EXTERNAL);
$context->setPriority(count($commData) > 2 ? Mail\Context::PRIORITY_LOW : Mail\Context::PRIORITY_NORMAL);
$context->setCallback(
(new Mail\Callback\Config())
->setModuleId('crm')
->setEntityType('act')
->setEntityId($urn)
);
$sendResult = Mail\Mail::send(array_merge(
$outgoingParams,
array(
'TRACK_READ' => array(
'MODULE_ID' => 'crm',
'FIELDS' => array('urn' => $urn),
'URL_PAGE' => '/pub/mail/read.php',
),
'TRACK_CLICK' => array(
'MODULE_ID' => 'crm',
'FIELDS' => array('urn' => $urn),
'URL_PAGE' => '/pub/mail/click.php',
),
'CONTEXT' => $context,
)
));
if (!$sendResult)
{
if ($isNew)
{
if (\CModule::includeModule('bitrix24'))
{
if (
method_exists(\Bitrix\Bitrix24\MailCounter::class, 'isLimited')
&& \Bitrix\Bitrix24\MailCounter::isLimited()
)
{
$arErrors[] = new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_MESSAGE_CREATION_LIMITED'));
\CCrmActivity::delete($ID);
$this->addErrors($arErrors);
return false;
}
elseif (
method_exists(\Bitrix\Bitrix24\MailCounter::class, 'isCustomLimited')
&& \Bitrix\Bitrix24\MailCounter::isCustomLimited())
{
$arErrors[] = new Error(Loc::getMessage('CRM_MAIL_CONTROLLER_MESSAGE_CUSTOM_LIMITED'));
\CCrmActivity::delete($ID);
$this->addErrors($arErrors);
return false;
}
}
$arErrors[] = new Error(Loc::getMessage('CRM_ACTIVITY_EMAIL_CREATION_CANCELED'));
}
$this->addErrors($arErrors);
return false;
}
addEventToStatFile('crm', 'send_email_message', $_REQUEST['context'], trim(trim($messageId), '<>'));
$needUpload = !empty($mailboxHelper);
if ($context->getSmtp() && in_array(mb_strtolower($context->getSmtp()->getHost()), array('smtp.gmail.com', 'smtp.office365.com')))
{
$needUpload = false;
}
if ($needUpload)
{
class_exists('Bitrix\Mail\Helper');
$outgoing = new \Bitrix\Mail\DummyMail(array_merge(
$outgoingParams,
array(
'HEADER' => array_merge(
$outgoingParams['HEADER'],
array(
'To' => $outgoingParams['TO'],
'Subject' => $outgoingParams['SUBJECT'],
)
),
)
));
$mailboxHelper->uploadMessage($outgoing);
}
// Try add event to entity
$CCrmEvent = new \CCrmEvent();
$eventText = '';
$eventText .= GetMessage('CRM_TITLE_EMAIL_SUBJECT').': '.$subject."\n\r";
$eventText .= GetMessage('CRM_TITLE_EMAIL_FROM').': '.$from."\n\r";
if (!empty($to))
$eventText .= getMessage('CRM_TITLE_EMAIL_TO').': '.implode(',', $to)."\n\r";
if (!empty($rawCc))
$eventText .= 'Cc: '.implode(',', $rawCc)."\n\r";
if (!empty($bcc))
$eventText .= 'Bcc: '.implode(',', $bcc)."\n\r";
$eventText .= "\n\r";
$eventText .= $description;
$eventBindings = array();
foreach($arBindings as $item)
{
$bindingEntityID = $item['OWNER_ID'];
$bindingEntityTypeID = $item['OWNER_TYPE_ID'];
$bindingEntityTypeName = \CCrmOwnerType::resolveName($bindingEntityTypeID);
$eventBindings["{$bindingEntityTypeName}_{$bindingEntityID}"] = array(
'ENTITY_TYPE' => $bindingEntityTypeName,
'ENTITY_ID' => $bindingEntityID
);
}
$CCrmEvent->Add(
array(
'ENTITY' => $eventBindings,
'EVENT_ID' => 'MESSAGE',
'EVENT_TEXT_1' => $eventText,
'FILES' => array_values($arRawFiles),
)
);
// <-- Sending Email
$commData = array();
$communications = \CCrmActivity::GetCommunications($ID);
foreach($communications as &$arComm)
{
\CCrmActivity::PrepareCommunicationInfo($arComm);
$commData[] = array(
'type' => $arComm['TYPE'],
'value' => $arComm['VALUE'],
'entityId' => $arComm['ENTITY_ID'],
'entityType' => \CCrmOwnerType::ResolveName($arComm['ENTITY_TYPE_ID']),
'entityTitle' => $arComm['TITLE'],
'entityUrl' => \CCrmOwnerType::GetEntityShowPath($arComm['ENTITY_TYPE_ID'], $arComm['ENTITY_ID'])
);
}
unset($arComm);
$userName = '';
if($userID > 0)
{
$dbResUser = \CUser::GetByID($userID);
$userName = is_array(($user = $dbResUser->Fetch()))
? \CUser::FormatName(\CSite::GetNameFormat(false), $user, true, false) : '';
}
$nowStr = ConvertTimeStamp(MakeTimeStamp($now), 'FULL', SITE_ID);
\CCrmActivity::PrepareStorageElementIDs($arFields);
\CCrmActivity::PrepareStorageElementInfo($arFields);
$jsonFields = array(
'ID' => $ID,
'typeID' => \CCrmActivityType::Email,
'ownerID' => $arFields['OWNER_ID'],
'ownerType' => \CCrmOwnerType::ResolveName($arFields['OWNER_TYPE_ID']),
'ownerTitle' => \CCrmOwnerType::GetCaption($arFields['OWNER_TYPE_ID'], $arFields['OWNER_ID']),
'ownerUrl' => \CCrmOwnerType::GetEntityShowPath($arFields['OWNER_TYPE_ID'], $arFields['OWNER_ID']),
'subject' => $subject,
'description' => $description,
'descriptionHtml' => $description,
'location' => '',
'start' => $nowStr,
'end' => $nowStr,
'deadline' => $nowStr,
'completed' => true,
'notifyType' => \CCrmActivityNotifyType::None,
'notifyValue' => 0,
'priority' => \CCrmActivityPriority::Medium,
'responsibleName' => $userName,
'responsibleUrl' =>
\CComponentEngine::MakePathFromTemplate(
'/company/personal/user/#user_id#/',
array('user_id' => $userID)
),
'storageTypeID' => $storageTypeID,
'files' => isset($arFields['FILES']) ? $arFields['FILES'] : array(),
'webdavelements' => isset($arFields['WEBDAV_ELEMENTS']) ? $arFields['WEBDAV_ELEMENTS'] : array(),
'diskfiles' => isset($arFields['DISK_FILES']) ? $arFields['DISK_FILES'] : array(),
'communications' => $commData
);
return ['ACTIVITY' => $jsonFields];
}