CCrmActivityEmailSender::TrySendEmail

  1. Bitrix24 API (v. 23.675.0)
  2. crm
  3. CCrmActivityEmailSender
  4. TrySendEmail
  • Модуль: crm
  • Путь к файлу: ~/bitrix/modules/crm/classes/general/crm_activity.php
  • Класс: \CCrmActivityEmailSender
  • Вызов: CCrmActivityEmailSender::TrySendEmail
static function TrySendEmail($ID, &$arFields, &$arErrors)
{
	if (!CModule::IncludeModule('subscribe'))
	{
		$arErrors[] = array('CODE' => self::ERR_CANT_LOAD_SUBSCRIBE);
		return false;
	}

	$ID = intval($ID);
	if($ID <= 0 && isset($arFields['ID']))
	{
		$ID = intval($arFields['ID']);
	}

	if($ID <= 0 || !is_array($arFields))
	{
		$arErrors[] = array('CODE' => self::ERR_INVALID_DATA);
		return false;
	}

	$typeID = isset($arFields['TYPE_ID']) ? intval($arFields['TYPE_ID']) : CCrmActivityType::Undefined;
	if($typeID !== CCrmActivityType::Email)
	{
		$arErrors[] = array('CODE' => self::ERR_INVALID_DATA);
		return false;
	}

	$urn = CCrmActivity::PrepareUrn($arFields);
	if(!($urn !== ''
		&& CCrmActivity::Update($ID, array('URN'=> $urn), false, false)))
	{
		$arErrors[] = array('CODE' => self::ERR_CANT_UPDATE_ACTIVITY);
		return false;
	}

	$messageId = sprintf(
		'', $urn,
		defined('BX24_HOST_NAME') ? BX24_HOST_NAME : (
			defined('SITE_SERVER_NAME') && SITE_SERVER_NAME
				? SITE_SERVER_NAME : \COption::getOptionString('main', 'server_name', '')
		)
	);

	$settings = isset($arFields['SETTINGS']) && is_array($arFields['SETTINGS']) ? $arFields['SETTINGS'] : array();

	// Creating Email -->

	if (CModule::includeModule('mail'))
	{
		$res = \Bitrix\Mail\MailboxTable::getList(array(
			'select' => array('*', 'LANG_CHARSET' => 'SITE.CULTURE.CHARSET'),
			'filter' => array(
				'=LID'    => SITE_ID,
				'=ACTIVE' => 'Y',
				array(
					'LOGIC' => 'OR',
					'=USER_ID' => $arFields['RESPONSIBLE_ID'],
					array(
						'USER_ID'      => 0,
						'=SERVER_TYPE' => 'imap',
					),
				),
			),
			'order' => array('TIMESTAMP_X' => 'ASC'), // @TODO: order by ID
		));

		while ($mailbox = $res->fetch())
		{
			if (!empty($mailbox['OPTIONS']['flags']) && in_array('crm_connect', (array) $mailbox['OPTIONS']['flags']))
			{
				$mailbox['EMAIL_FROM'] = null;
				if (check_email($mailbox['NAME'], true))
					$mailbox['EMAIL_FROM'] = mb_strtolower($mailbox['NAME']);
				elseif(check_email($mailbox['LOGIN'], true))
					$mailbox['EMAIL_FROM'] = mb_strtolower($mailbox['LOGIN']);

				if ($mailbox['USER_ID'] > 0)
					$userImap = $mailbox;
				else
					$crmImap = $mailbox;
			}
		}

		$defaultFrom = \Bitrix\Mail\User::getDefaultEmailFrom();
	}

	$crmEmail = \CCrmMailHelper::extractEmail(\COption::getOptionString('crm', 'mail', ''));

	$from  = '';
	$reply = '';
	$to    = array();
	$cc    = '';

	if (isset($settings['MESSAGE_FROM']))
		$from = trim(strval($settings['MESSAGE_FROM']));

	if ($from == '')
	{
		if (!empty($userImap))
		{
			$from = $userImap['EMAIL_FROM'] ?: $defaultFrom;
			$userImap['need_sync'] = true;
		}
		elseif (!empty($crmImap))
		{
			$from = $crmImap['EMAIL_FROM'] ?: $defaultFrom;
			$crmImap['need_sync'] = true;
		}
		else
		{
			$from = $crmEmail;
			$cc   = $crmEmail;
		}

		if ($from == '')
			$arErrors[] = array('CODE' => self::ERR_CANT_FIND_EMAIL_FROM);
	}
	else
	{
		$fromAddresses = explode(',', $from);
		foreach ($fromAddresses as $fromAddress)
		{
			if (!check_email($fromAddress))
			{
				$arErrors[] = array(
					'CODE' => self::ERR_INVALID_EMAIL,
					'DATA' => array('EMAIL' => $fromAddress)
				);
				continue;
			}

			// copied from check_email
			if (preg_match('/.*?[<\[\(](.+?)[>\]\)].*/i', $fromAddress, $matches))
				$fromAddress = $matches[1];
			$fromList[] = mb_strtolower(trim($fromAddress));
		}

		if (!empty($userImap['EMAIL_FROM']) && in_array($userImap['EMAIL_FROM'], $fromList))
			$userImap['need_sync'] = true;
		if (!empty($crmImap['EMAIL_FROM']) && in_array($crmImap['EMAIL_FROM'], $fromList))
			$crmImap['need_sync'] = true;

		$cc = join(', ', array_diff(
			$fromList,
			array(
				!empty($userImap['EMAIL_FROM']) ? $userImap['EMAIL_FROM'] : '',
				!empty($crmImap['EMAIL_FROM']) ? $crmImap['EMAIL_FROM'] : '',
			)
		));

		if (empty($userImap['need_sync']) && empty($crmImap['need_sync']))
		{
			if (!empty($userImap['EMAIL_FROM']))
				$reply = join(', ', $fromList) . ', ' . $userImap['EMAIL_FROM'];
			else if (!empty($crmImap['EMAIL_FROM']))
				$reply = join(', ', $fromList) . ', ' . $crmImap['EMAIL_FROM'];
			else if ($crmEmail != '' && !in_array($crmEmail, $fromList))
				$reply = join(', ', $fromList) . ', ' . $crmEmail;
		}
	}

	//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


	$to = array();
	$commData = isset($arFields['COMMUNICATIONS']) ? $arFields['COMMUNICATIONS'] : array();
	foreach($commData as &$commDatum)
	{
		$commType = isset($commDatum['TYPE'])? mb_strtoupper(strval($commDatum['TYPE'])) : '';
		$commValue = isset($commDatum['VALUE']) ? strval($commDatum['VALUE']) : '';

		if($commType !== 'EMAIL' || $commValue === '')
		{
			continue;
		}

		if(!check_email($commValue))
		{
			$arErrors[] = array(
				'CODE' => self::ERR_INVALID_EMAIL,
				'DATA' => array('EMAIL' => $commValue)
			);
			continue;
		}

		$to[] = mb_strtolower(trim($commValue));
	}
	unset($commDatum);

	if(count($to) == 0)
	{
		$arErrors[] = array('CODE' => self::ERR_CANT_FIND_EMAIL_TO);
	}

	if(!empty($arErrors))
	{
		return false;
	}

	// Try to resolve posting charset -->
	$postingCharset = '';
	$siteCharset = defined('LANG_CHARSET') ? LANG_CHARSET : (defined('SITE_CHARSET') ? SITE_CHARSET : 'windows-1251');
	$arSupportedCharset = explode(',', COption::GetOptionString('subscribe', 'posting_charset'));
	if(count($arSupportedCharset) === 0)
	{
		$postingCharset = $siteCharset;
	}
	else
	{
		foreach($arSupportedCharset as $curCharset)
		{
			if(strcasecmp($curCharset, $siteCharset) === 0)
			{
				$postingCharset = $curCharset;
				break;
			}
		}

		if($postingCharset === '')
		{
			$postingCharset = $arSupportedCharset[0];
		}
	}
	//<-- Try to resolve posting charset
	$subject = isset($arFields['SUBJECT']) ? $arFields['SUBJECT'] : '';
	$description = isset($arFields['DESCRIPTION']) ? $arFields['DESCRIPTION'] : '';
	$descriptionType = isset($arFields['DESCRIPTION_TYPE']) ? intval($arFields['DESCRIPTION_TYPE']) : CCrmContentType::PlainText;

	$descriptionHtml = '';
	if($descriptionType === CCrmContentType::Html)
	{
		$descriptionHtml = $description;
	}
	elseif($descriptionType === CCrmContentType::BBCode)
	{
		$parser = new CTextParser();
		$parser->allow['SMILES'] = 'N';
		$descriptionHtml = ''.$parser->convertText($description).'';
	}
	elseif($descriptionType === CCrmContentType::PlainText)
	{
		$descriptionHtml = htmlspecialcharsbx($description);
	}

	if (isset($settings['DISABLE_SENDING_MESSAGE_COPY']) && $settings['DISABLE_SENDING_MESSAGE_COPY'] === 'Y')
	{
		$cc = '';
	}

	$postingData = array(
		'STATUS' => 'D',
		'FROM_FIELD' => $from,
		'TO_FIELD' => $cc,
		'BCC_FIELD' => implode(',', $to),
		'SUBJECT' => $subject,
		'BODY_TYPE' => 'html',
		'BODY' => $descriptionHtml,
		'DIRECT_SEND' => 'Y',
		'SUBSCR_FORMAT' => 'html',
		'CHARSET' => $postingCharset
	);

	CCrmActivity::InjectUrnInMessage(
		$postingData,
		$urn,
		CCrmEMailCodeAllocation::GetCurrent()
	);

	$posting = new CPosting();
	$postingID = $posting->Add($postingData);
	if($postingID === false)
	{
		$arErrors[] = array('CODE' => self::ERR_CANT_ADD_POSTING, 'MESSAGE' => $posting->LAST_ERROR);
		return false;
	}

	$arUpdateFields = array(
		'COMPLETED' => 'Y',
		'ASSOCIATED_ENTITY_ID'=> $postingID,
		'SETTINGS' => $settings
	);

	$arUpdateFields['SETTINGS']['MESSAGE_HEADERS'] = array('Message-Id' => $messageId);
	if ($reply != '')
		$arUpdateFields['SETTINGS']['MESSAGE_HEADERS']['Reply-To'] = $reply;

	$arUpdateFields['SETTINGS']['IS_MESSAGE_SENT'] = true;

	if(!CCrmActivity::Update($ID, $arUpdateFields, false, false))
	{
		$arErrors[] = array('CODE' => self::ERR_CANT_UPDATE_ACTIVITY);
		return false;
	}
	// <-- Creating Email

	$arFields['COMPLETED'] = $arUpdateFields['COMPLETED'];
	$arFields['ASSOCIATED_ENTITY_ID'] = $arUpdateFields['ASSOCIATED_ENTITY_ID'];
	$arFields['SETTINGS'] = $arUpdateFields['SETTINGS'];

	// Attaching files -->
	$storageTypeID = isset($arFields['STORAGE_TYPE_ID'])
		? intval($arFields['STORAGE_TYPE_ID']) : StorageType::Undefined;
	$storageElementsID = isset($arFields['STORAGE_ELEMENT_IDS'])
		&& is_array($arFields['STORAGE_ELEMENT_IDS'])
		? $arFields['STORAGE_ELEMENT_IDS'] : array();

	$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;

	$arRawFiles = StorageManager::makeFileArray($storageElementsID, $storageTypeID);
	foreach($arRawFiles as $arRawFile)
	{
		$contentId = sprintf(
			'bxacid.%s@%s.crm',
			hash('crc32b', $arRawFile['external_id'].$arRawFile['size'].$arRawFile['name']),
			hash('crc32b', $hostname)
		);

		$arRawFile['name'] = sprintf('%s_%s', $arRawFile['name'], $contentId);
		if(!$posting->SaveFile($postingID, $arRawFile))
		{
			$arErrors[] = array('CODE' => self::ERR_CANT_SAVE_POSTING_FILE, 'MESSAGE' => $posting->LAST_ERROR);
			return false;
		}
	}
	// <-- Attaching files

	if (!empty($userImap['need_sync']) || !empty($crmImap['need_sync']))
	{
		$attachments = array();
		foreach ($arRawFiles as $item)
		{
			$attachments[] = array(
				'ID'           => $item['external_id'],
				'NAME'         => $item['ORIGINAL_NAME'] ?: $item['name'],
				'PATH'         => $item['tmp_name'],
				'CONTENT_TYPE' => $item['type'],
			);
		}

		class_exists('Bitrix\Mail\Helper');

		$rcpt = array();
		foreach ($to as $item)
			$rcpt[] = \Bitrix\Mail\DummyMail::encodeHeaderFrom($item, SITE_CHARSET);
		$rcpt = join(', ', $rcpt);

		$outgoing = new \Bitrix\Mail\DummyMail(array(
			'CONTENT_TYPE' => 'html',
			'CHARSET'      => SITE_CHARSET,
			'HEADER'       => array(
				'From'       => $from,
				'To'         => $rcpt,
				'Subject'    => $subject,
				'Message-Id' => $messageId,
			),
			'BODY'         => $descriptionHtml,
			'ATTACHMENT'   => $attachments
		));

		if (!empty($userImap['need_sync']))
			\Bitrix\Mail\Helper::addImapMessage($userImap, (string) $outgoing, $err);
		if (!empty($crmImap['need_sync']))
			\Bitrix\Mail\Helper::addImapMessage($crmImap, (string) $outgoing, $err);
	}

	// Sending Email -->
	if($posting->ChangeStatus($postingID, 'P'))
	{
		$rsAgents = CAgent::GetList(
			array('ID'=>'DESC'),
			array(
				'MODULE_ID' => 'subscribe',
				'NAME' => 'CPosting::AutoSend('.$postingID.',%',
			)
		);

		if(!$rsAgents->Fetch())
		{
			CAgent::AddAgent('CPosting::AutoSend('.$postingID.',true);', 'subscribe', 'N', 0);
		}
	}

	// Try add event to entity
	$CCrmEvent = new CCrmEvent();

	$bindings = \CCrmActivity::GetBindings($ID);
	if(!empty($bindings))
	{
		$eventText  = '';
		$eventText .= GetMessage('CRM_ACTIVITY_EMAIL_SUBJECT').': '.$subject."\n\r";
		$eventText .= GetMessage('CRM_ACTIVITY_EMAIL_FROM').': '.$from."\n\r";
		$eventText .= GetMessage('CRM_ACTIVITY_EMAIL_TO').': '.implode(',', $to)."\n\r\n\r";
		$eventText .= $description;

		$eventBindings = array();
		foreach($bindings 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' => $arRawFiles
			)
		);
	}
	// <-- Sending Email
	return true;
}

Добавить комментарий