• Модуль: mail
  • Путь к файлу: ~/bitrix/modules/mail/lib/helper/mailbox.php
  • Класс: BitrixMailHelperMailbox
  • Вызов: Mailbox::syncOutgoingMessage
protected function syncOutgoingMessage($excerpt)
{
	global $DB;

	$lockSql = sprintf(
		"UPDATE b_mail_message_upload_queue SET SYNC_LOCK = %u, SYNC_STAGE = %u, ATTEMPTS = ATTEMPTS + 1
			WHERE ID = '%s' AND MAILBOX_ID = %u AND SYNC_LOCK < %u",
		$syncLock = time(),
		max(1, $excerpt['UPLOAD_STAGE']),
		$DB->forSql($excerpt['ID']),
		$excerpt['MAILBOX_ID'],
		$syncLock - static::getTimeout()
	);
	if (!$DB->query($lockSql)->affectedRowsCount())
	{
		return;
	}

	$outgoingBody = $excerpt['__BODY_HTML'];

	$excerpt['__files'] = MailInternalsMailMessageAttachmentTable::getList(array(
		'select' => array(
			'ID', 'FILE_ID', 'FILE_NAME',
		),
		'filter' => array(
			'=MESSAGE_ID' => $excerpt['__ID'],
		),
	))->fetchAll();

	$attachments = array();
	if (!empty($excerpt['__files']) && is_array($excerpt['__files']))
	{
		$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;
		}

		foreach ($excerpt['__files'] as $item)
		{
			$file = CFile::makeFileArray($item['FILE_ID']);

			$contentId = sprintf(
				'bxacid.%s@%s.mail',
				hash('crc32b', $file['external_id'].$file['size'].$file['name']),
				hash('crc32b', $hostname)
			);

			$attachments[] = array(
				'ID'           => $contentId,
				'NAME'         => $item['FILE_NAME'],
				'PATH'         => $file['tmp_name'],
				'CONTENT_TYPE' => $file['type'],
			);

			$outgoingBody = preg_replace(
				sprintf('/aid:%u/i', $item['ID']),
				sprintf('cid:%s', $contentId),
				$outgoingBody
			);
		}
	}

	foreach (array('FROM', 'REPLY_TO', 'TO', 'CC', 'BCC') as $field)
	{
		$field = sprintf('__FIELD_%s', $field);

		if (mb_strlen($excerpt[$field]) == 255 && '' != $excerpt['__HEADER'] && empty($parsedHeader))
		{
			$parsedHeader = CMailMessage::parseHeader($excerpt['__HEADER'], LANG_CHARSET);

			$excerpt['__FIELD_FROM'] = $parsedHeader->getHeader('FROM');
			$excerpt['__FIELD_REPLY_TO'] = $parsedHeader->getHeader('REPLY-TO');
			$excerpt['__FIELD_TO'] = $parsedHeader->getHeader('TO');
			$excerpt['__FIELD_CC'] = $parsedHeader->getHeader('CC');
			$excerpt['__FIELD_BCC'] = join(', ', array_merge(
				(array) $parsedHeader->getHeader('X-Original-Rcpt-to'),
				(array) $parsedHeader->getHeader('BCC')
			));
		}

		$excerpt[$field] = explode(',', $excerpt[$field]);

		foreach ($excerpt[$field] as $k => $item)
		{
			unset($excerpt[$field][$k]);

			$address = new MainMailAddress($item);

			if ($address->validate())
			{
				if ($address->getName())
				{
					$excerpt[$field][] = sprintf(
						'%s <%s>',
						sprintf('=?%s?B?%s?=', SITE_CHARSET, base64_encode($address->getName())),
						$address->getEmail()
					);
				}
				else
				{
					$excerpt[$field][] = $address->getEmail();
				}
			}
		}

		$excerpt[$field] = join(', ', $excerpt[$field]);
	}

	$outgoingParams = [
		'CHARSET'      => LANG_CHARSET,
		'CONTENT_TYPE' => 'html',
		'ATTACHMENT'   => $attachments,
		'TO'           => $excerpt['__FIELD_TO'],
		'SUBJECT'      => $excerpt['__SUBJECT'],
		'BODY'         => $outgoingBody,
		'HEADER'       => [
			'From'       => $excerpt['__FIELD_FROM'],
			'Reply-To'   => $excerpt['__FIELD_REPLY_TO'],
			'Cc'         => $excerpt['__FIELD_CC'],
			'Bcc'        => $excerpt['__FIELD_BCC'],
			'Message-Id' => sprintf('<%s>', $excerpt['__MSG_ID']),
			'X-Bitrix-Mail-Message-UID' => $excerpt['ID'],
		],
	];

	if(isset($excerpt['__IN_REPLY_TO']))
	{
		$outgoingParams['HEADER']['In-Reply-To'] = sprintf('<%s>', $excerpt['__IN_REPLY_TO']);
	}

	$context = new MainMailContext();
	$context->setCategory(MainMailContext::CAT_EXTERNAL);
	$context->setPriority(MainMailContext::PRIORITY_NORMAL);

	$eventManager = BitrixMainEventManager::getInstance();
	$eventKey = $eventManager->addEventHandler(
		'main',
		'OnBeforeMailSend',
		function () use (&$excerpt)
		{
			if ($excerpt['UPLOAD_STAGE'] >= 2)
			{
				return new MainEventResult(MainEventResult::ERROR);
			}
		}
	);

	$success = MainMailMail::send(array_merge(
		$outgoingParams,
		array(
			'TRACK_READ' => array(
				'MODULE_ID' => 'mail',
				'FIELDS'    => array('msgid' => $excerpt['__MSG_ID']),
				'URL_PAGE' => '/pub/mail/read.php',
			),
			//'TRACK_CLICK' => array(
			//	'MODULE_ID' => 'mail',
			//	'FIELDS'    => array('msgid' => $excerpt['__MSG_ID']),
			//),
			'CONTEXT' => $context,
		)
	));

	$eventManager->removeEventHandler('main', 'OnBeforeMailSend', $eventKey);

	if ($excerpt['UPLOAD_STAGE'] < 2 && !$success)
	{
		return false;
	}

	$needUpload = true;
	if ($context->getSmtp() && $context->getSmtp()->getFrom() == $this->mailbox['EMAIL'])
	{
		$needUpload = !in_array('deny_upload', (array) $this->mailbox['OPTIONS']['flags']);
	}

	if ($needUpload)
	{
		if ($excerpt['UPLOAD_STAGE'] < 2)
		{
			MailInternalsMessageUploadQueueTable::update(
				array(
					'ID' => $excerpt['ID'],
					'MAILBOX_ID' => $excerpt['MAILBOX_ID'],
				),
				array(
					'SYNC_STAGE' => 2,
					'ATTEMPTS' => 1,
				)
			);
		}

		class_exists('BitrixMailHelper');

		$message = new MailDummyMail(array_merge(
			$outgoingParams,
			array(
				'HEADER' => array_merge(
					$outgoingParams['HEADER'],
					array(
						'To'      => $outgoingParams['TO'],
						'Subject' => $outgoingParams['SUBJECT'],
					)
				),
			)
		));

		if ($this->uploadMessage($message, $excerpt))
		{
			MailInternalsMessageUploadQueueTable::delete(array(
				'ID' => $excerpt['ID'],
				'MAILBOX_ID' => $excerpt['MAILBOX_ID'],
			));
		}
	}
	else
	{
		MailInternalsMessageUploadQueueTable::update(
			array(
				'ID' => $excerpt['ID'],
				'MAILBOX_ID' => $excerpt['MAILBOX_ID'],
			),
			array(
				'SYNC_STAGE' => -1,
				'SYNC_LOCK' => 0,
			)
		);
	}

	return;
}