%PDF- %PDF-
| Direktori : /home/bitrix/www/bitrix/modules/bizproc/install/activities/bitrix/mailactivity/ |
| Current File : /home/bitrix/www/bitrix/modules/bizproc/install/activities/bitrix/mailactivity/mailactivity.php |
<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
use Bitrix\Main\Loader;
use Bitrix\Main\Mail;
use Bitrix\Disk;
class CBPMailActivity extends CBPActivity
{
const DEFAULT_SEPARATOR = ',';
const FILE_TYPE_FILE = 'file';
const FILE_TYPE_DISK = 'disk';
public function __construct($name)
{
parent::__construct($name);
$this->arProperties = array(
"Title" => "",
"MailUserFrom" => "",
"MailUserFromArray" => "",
"MailUserTo" => "",
"MailUserToArray" => "",
"MailSubject" => "",
"MailText" => "",
"MailMessageType" => "plain",
"MailMessageEncoded" => 0,
"MailCharset" => "windows-1251",
"DirrectMail" => "Y",
"MailSite" => null,
"MailSeparator" => static::DEFAULT_SEPARATOR,
"File" => null,
"FileType" => static::FILE_TYPE_FILE,
);
}
public function Execute()
{
$separator = $this->MailSeparator;
if (empty($separator))
{
$separator = static::DEFAULT_SEPARATOR;
}
$fromList = $this->getFromList($separator);
if (empty($fromList))
{
$this->WriteToTrackingService(GetMessage("BPMA_EMPTY_PROP1"), 0, CBPTrackingType::Error);
return CBPActivityExecutionStatus::Closed;
}
$strMailUserTo = $this->getMailUserTo($separator);
if (empty($strMailUserTo))
{
$this->WriteToTrackingService(GetMessage("BPMA_EMPTY_PROP2"), 0, CBPTrackingType::Error);
return CBPActivityExecutionStatus::Closed;
}
$charset = $this->MailCharset;
$mailText = $this->getMailText();
if (!$this->IsPropertyExists("DirrectMail") || $this->DirrectMail == "Y")
{
global $APPLICATION;
$strMailUserTo = $APPLICATION->ConvertCharset($strMailUserTo, SITE_CHARSET, $charset);
$strMailUserTo = Mail\Mail::encodeMimeString($strMailUserTo, $charset);
$mailSubject = $APPLICATION->ConvertCharset($this->MailSubject, SITE_CHARSET, $charset);
$mailText = $APPLICATION->ConvertCharset(CBPHelper::ConvertTextForMail($mailText), SITE_CHARSET, $charset);
$context = new Mail\Context();
$context->setCategory(Mail\Context::CAT_EXTERNAL);
$context->setPriority(Mail\Context::PRIORITY_LOW);
Mail\Mail::send([
'CHARSET' => $charset,
'CONTENT_TYPE' => $this->MailMessageType == "html" ? "html" : "plain",
'ATTACHMENT' => $this->getAttachments(),
'TO' => $strMailUserTo,
'SUBJECT' => $mailSubject,
'BODY' => $mailText,
'HEADER' => array(
'From' => $this->encodeFrom($fromList[0], $charset),
'Reply-To' => $this->encodeReplyTo($fromList, $charset, $separator),
),
'CONTEXT' => $context,
]);
}
else
{
$siteId = null;
if ($this->IsPropertyExists("MailSite"))
{
$siteId = $this->MailSite;
}
if (strlen($siteId) <= 0)
{
$siteId = SITE_ID;
}
$arFields = array(
"SENDER" => $this->encodeFrom($fromList[0], $charset),
"REPLY_TO" => $this->encodeFrom($fromList[0], $charset),//$this->encodeReplyTo($fromList, $charset, $separator),
"RECEIVER" => $strMailUserTo,
"TITLE" => $this->MailSubject,
"MESSAGE" => CBPHelper::ConvertTextForMail($mailText),
);
$files = $this->getFileIds();
$eventName = ($this->MailMessageType == "html") ? "BIZPROC_HTML_MAIL_TEMPLATE" : "BIZPROC_MAIL_TEMPLATE";
$event = new CEvent;
$event->Send($eventName, $siteId, $arFields, "N", '', $files);
}
return CBPActivityExecutionStatus::Closed;
}
public static function ValidateProperties($arTestProperties = array(), CBPWorkflowTemplateUser $user = null)
{
$arErrors = array();
if ((!array_key_exists("MailUserFrom", $arTestProperties) || strlen($arTestProperties["MailUserFrom"]) <= 0)
&& (!array_key_exists("MailUserFromArray", $arTestProperties) || count($arTestProperties["MailUserFromArray"]) <= 0))
$arErrors[] = array("code" => "NotExist", "parameter" => "MailUserFrom", "message" => GetMessage("BPMA_EMPTY_PROP1"));
if ((!array_key_exists("MailUserTo", $arTestProperties) || strlen($arTestProperties["MailUserTo"]) <= 0)
&& (!array_key_exists("MailUserToArray", $arTestProperties) || count($arTestProperties["MailUserToArray"]) <= 0))
$arErrors[] = array("code" => "NotExist", "parameter" => "MailUserTo", "message" => GetMessage("BPMA_EMPTY_PROP2"));
if (!array_key_exists("MailSubject", $arTestProperties) || strlen($arTestProperties["MailSubject"]) <= 0)
$arErrors[] = array("code" => "NotExist", "parameter" => "MailSubject", "message" => GetMessage("BPMA_EMPTY_PROP3"));
if (!array_key_exists("MailCharset", $arTestProperties) || strlen($arTestProperties["MailCharset"]) <= 0)
$arErrors[] = array("code" => "NotExist", "parameter" => "MailCharset", "message" => GetMessage("BPMA_EMPTY_PROP4"));
if (!array_key_exists("MailMessageType", $arTestProperties))
$arErrors[] = array("code" => "NotExist", "parameter" => "MailMessageType", "message" => GetMessage("BPMA_EMPTY_PROP5"));
elseif (!in_array($arTestProperties["MailMessageType"], array("plain", "html")))
$arErrors[] = array("code" => "NotInRange", "parameter" => "MailMessageType", "message" => GetMessage("BPMA_EMPTY_PROP6"));
if (!array_key_exists("MailText", $arTestProperties) || strlen($arTestProperties["MailText"]) <= 0)
$arErrors[] = array("code" => "NotExist", "parameter" => "MailText", "message" => GetMessage("BPMA_EMPTY_PROP7"));
return array_merge($arErrors, parent::ValidateProperties($arTestProperties, $user));
}
public static function GetPropertiesDialog($documentType, $activityName, $arWorkflowTemplate, $arWorkflowParameters, $arWorkflowVariables, $arCurrentValues = null, $formName = "", $popupWindow = null, $siteId = '')
{
$dialog = new \Bitrix\Bizproc\Activity\PropertiesDialog(__FILE__, array(
'documentType' => $documentType,
'activityName' => $activityName,
'workflowTemplate' => $arWorkflowTemplate,
'workflowParameters' => $arWorkflowParameters,
'workflowVariables' => $arWorkflowVariables,
'currentValues' => $arCurrentValues,
'formName' => $formName,
'siteId' => $siteId
));
$dialog->setMap(array(
'MailUserFrom' => array(
'Name' => GetMessage('BPMA_MAIL_USER_FROM'),
'FieldName' => 'mail_user_from',
'Type' => 'string',
'Required' => true,
'Getter' => static::getMailUserPropertyGetter()
),
'MailUserTo' => array(
'Name' => GetMessage('BPMA_MAIL_USER_TO'),
'FieldName' => 'mail_user_to',
'Type' => 'user',
'Required' => true,
'Multiple' => true,
'Getter' => static::getMailUserPropertyGetter(),
'Default' => \Bitrix\Bizproc\Automation\Helper::getResponsibleUserExpression($documentType)
),
'MailSubject' => array(
'Name' => GetMessage('BPMA_MAIL_SUBJECT'),
'Description' => GetMessage('BPMA_MAIL_SUBJECT'),
'FieldName' => 'mail_subject',
'Type' => 'string',
'Required' => true
),
'MailText' => array(
'Name' => GetMessage('BPSNMA_MESSAGE'),
'FieldName' => 'mail_text',
'Type' => 'text',
'Required' => true
),
'MailMessageType' => array(
'Name' => GetMessage('BPSNMA_MESSAGE'),
'FieldName' => 'mail_message_type',
'Type' => 'select',
'Options' => array(
'plain' => 'plain',
'html' => 'html'
),
'Default' => 'plain'
),
'MailMessageEncoded' => array(
'Name' => GetMessage('BPSNMA_MESSAGE'),
'FieldName' => 'mail_message_encoded',
'Type' => 'int',
'Default' => 0
),
'MailCharset' => array(
'Name' => GetMessage('BPSNMA_MESSAGE'),
'FieldName' => 'mail_charset',
'Type' => 'string',
),
'DirrectMail' => array(
'Name' => GetMessage('BPSNMA_MESSAGE'),
'FieldName' => 'dirrect_mail',
'Type' => 'string',
),
'MailSite' => array(
'Name' => GetMessage('BPSNMA_MESSAGE'),
'FieldName' => 'mail_site',
'Type' => 'string',
),
'MailSeparator' => array(
'Name' => GetMessage('BPSNMA_MESSAGE'),
'FieldName' => 'mail_separator',
'Type' => 'string',
'Default' => static::DEFAULT_SEPARATOR
),
'File' => array(
'Name' => GetMessage('BPMA_ATTACHMENT'),
'FieldName' => 'file',
'Type' => 'file',
'Multiple' => true
),
'FileType' => array(
'Name' => GetMessage('BPMA_ATTACHMENT_TYPE'),
'FieldName' => 'file_type',
'Type' => 'select',
'Options' => array(
static::FILE_TYPE_FILE => GetMessage('BPMA_ATTACHMENT_FILE'),
static::FILE_TYPE_DISK => GetMessage('BPMA_ATTACHMENT_DISK')
)
),
));
$mailboxes = static::getMailboxes();
if (!empty($mailboxes))
{
$dialog->setRuntimeData(array(
'mailboxes' => $mailboxes
));
}
return $dialog;
}
public static function GetPropertiesDialogValues($documentType, $activityName, &$arWorkflowTemplate, &$arWorkflowParameters, &$arWorkflowVariables, $arCurrentValues, &$arErrors)
{
$arErrors = array();
$arMap = array(
"mail_user_from" => "MailUserFrom",
"mail_user_to" => "MailUserTo",
"mail_subject" => "MailSubject",
"mail_text" => "MailText",
"mail_message_type" => "MailMessageType",
"mail_charset" => "MailCharset",
"dirrect_mail" => "DirrectMail",
"mail_site" => "MailSite",
'mail_separator' => 'MailSeparator',
'file' => 'File',
'file_type' => 'FileType',
);
$properties = array();
foreach ($arMap as $key => $value)
{
if ($key == "mail_user_from" || $key == "mail_user_to")
continue;
$properties[$value] = $arCurrentValues[$key];
}
if ($properties['FileType'] === static::FILE_TYPE_DISK)
{
$properties['File'] = [];
foreach ((array)$arCurrentValues["file"] as $attachmentId)
{
$attachmentId = (int)$attachmentId;
if ($attachmentId > 0)
{
$properties['File'][] = $attachmentId;
}
}
}
else
{
$properties['File'] = isset($arCurrentValues["file"])
? $arCurrentValues["file"] : $arCurrentValues["file_text"];
}
if (strlen($properties["MailSite"]) <= 0)
$properties["MailSite"] = $arCurrentValues["mail_site_x"];
$properties["MailSeparator"] = trim($properties["MailSeparator"]);
if (strlen($properties["MailSeparator"]) <= 0)
$properties["MailSeparator"] = static::DEFAULT_SEPARATOR;
list($mailUserFromArray, $mailUserFrom) = CBPHelper::UsersStringToArray($arCurrentValues["mail_user_from"], $documentType, $arErrors, array(__CLASS__, "CheckEmailUserValue"));
if (count($arErrors) > 0)
return false;
$properties["MailUserFrom"] = implode(", ", $mailUserFrom);
$properties["MailUserFromArray"] = $mailUserFromArray;
list($mailUserToArray, $mailUserTo) = CBPHelper::UsersStringToArray($arCurrentValues["mail_user_to"], $documentType, $arErrors, array(__CLASS__, "CheckEmailUserValue"));
if (count($arErrors) > 0)
return false;
$properties["MailUserTo"] = implode(", ", $mailUserTo);
$properties["MailUserToArray"] = $mailUserToArray;
$arErrors = self::ValidateProperties($properties, new CBPWorkflowTemplateUser(CBPWorkflowTemplateUser::CurrentUser));
if (count($arErrors) > 0)
return false;
$properties['MailMessageEncoded'] = 0;
if ($properties['MailMessageType'] === 'html')
{
$request = \Bitrix\Main\Application::getInstance()->getContext()->getRequest();
$rawData = $request->getPostList()->getRaw('mail_text');
if ($rawData === null)
{
$rawData = (array)$request->getPostList()->getRaw('form_data');
$rawData = $rawData['mail_text'];
}
if ($request->isAjaxRequest())
{
\CUtil::decodeURIComponent($rawData);
}
//TODO: fix for WAF, needs refactoring.
$rawData = \Bitrix\Bizproc\Automation\Helper::unConvertExpressions($rawData, $documentType);
$properties['MailText'] = self::encodeMailText($rawData);
$properties['MailMessageEncoded'] = 1;
}
$arCurrentActivity = &CBPWorkflowTemplateLoader::FindActivityByName($arWorkflowTemplate, $activityName);
$arCurrentActivity["Properties"] = $properties;
return true;
}
private function getFiles()
{
$files = [];
if ($this->FileType === static::FILE_TYPE_DISK)
{
if (Loader::includeModule('disk'))
{
$diskFiles = \CBPHelper::MakeArrayFlat((array)$this->File);
foreach ($diskFiles as $diskFileId)
{
/** @var Disk\File $file */
$file = Disk\File::loadById($diskFileId);
if ($file)
{
$id = (int)$file->getFileId();
$name = $file->getName();
$files[$id] = ['id' => $id, 'name' => $name];
}
}
}
}
else
{
$fileIds = \CBPHelper::MakeArrayFlat((array)$this->ParseValue($this->getRawProperty('File'), 'file'));
$fileIds = array_filter($fileIds);
foreach ($fileIds as $id)
{
$files[$id] = ['id' => $id];
}
}
return array_values($files);
}
private function getFileIds()
{
$files = $this->getFiles();
return array_column($files, 'id');
}
private function getAttachments()
{
$files = $this->getFiles();
$attachments = [];
foreach ($files as $file)
{
$fileId = $file['id'];
$fileName = isset($file['name']) ? $file['name'] : '';
if (!is_int($fileId))
continue;
$file = \CFile::makeFileArray($fileId);
$contentId = sprintf(
'bxacid.%s@mailactivity.bizproc',
hash('crc32b', $file['external_id'].$file['size'].$file['name'])
);
$attachments[] = array(
'ID' => $contentId,
'NAME' => $fileName ?: $file['name'],
'PATH' => $file['tmp_name'],
'CONTENT_TYPE' => $file['type'],
);
}
return $attachments;
}
public static function CheckEmailUserValue($user)
{
if (check_email($user))
return $user;
return null;
}
private function encodeFrom(array $from, $charset)
{
$name = $from['name'] ? \Bitrix\Main\Text\Encoding::convertEncoding($from['name'], SITE_CHARSET, $charset) : '';
$email = $from['email'];
if ($name)
{
$name = str_replace(array('\\', '"', '<', '>'), array('/', '\'', '(', ')'), $name);
return sprintf(
'%s <%s>',
Mail\Mail::encodeSubject($name, $charset),
$email
);
}
return $email;
}
private function encodeReplyTo(array $fromList, $charset, $separator = self::DEFAULT_SEPARATOR)
{
$reply = [];
foreach ($fromList as $from)
{
$reply[] = $this->encodeFrom($from, $charset);
}
return implode($separator, $reply);
}
private static function extractEmails($ar)
{
$arEmails = array();
$arUsers = array();
if (!is_array($ar))
$ar = array($ar);
$ar = CBPHelper::MakeArrayFlat($ar);
foreach ($ar as $item)
{
$arItem = explode(",", $item);
$flag = true;
foreach ($arItem as $itemTmp)
{
if (check_email($itemTmp))
{
$flag = false;
break;
}
}
if ($flag)
$arUsers[] = $item;
else
$arEmails[] = $item;
}
return array($arUsers, $arEmails);
}
private static function getMailboxes()
{
$mailboxes = [];
CBitrixComponent::includeComponentClass('bitrix:main.mail.confirm');
if (
class_exists('MainMailConfirmComponent')
&& method_exists('MainMailConfirmComponent', 'prepareMailboxes')
)
{
$mailboxes = (array)MainMailConfirmComponent::prepareMailboxes();
}
return $mailboxes;
}
private static function getMailUserPropertyGetter()
{
return function($dialog, $property, $arCurrentActivity, $compatible = false)
{
/** @var \Bitrix\Bizproc\Activity\PropertiesDialog $dialog */
$k = $property['Id'];
$result = $arCurrentActivity["Properties"][$k."Array"];
if ($compatible)
{
$result = [CBPHelper::UsersArrayToString(
$arCurrentActivity["Properties"][$k."Array"],
$dialog->getWorkflowTemplate(),
$dialog->getDocumentType()
)];
}
if (strlen($arCurrentActivity["Properties"][$k]) > 0)
$result[] = $arCurrentActivity["Properties"][$k];
return $compatible ? implode(', ', array_filter($result)) : $result;
};
}
private function getFromList($separator = self::DEFAULT_SEPARATOR)
{
$fromList = [];
list($mailUserFromArray, $mailUserFromArrayString) = static::extractEmails($this->MailUserFromArray);
$arMailUserFromArray = CBPHelper::ExtractUsers($mailUserFromArray, $this->GetDocumentId(), false);
foreach ($arMailUserFromArray as $user)
{
$dbUser = CUser::GetList(($b = ""), ($o = ""), array("ID_EQUAL_EXACT" => $user));
if ($arUser = $dbUser->Fetch())
{
$userName = '';
$userEmail = preg_replace("#[\r\n]+#", "", $arUser["EMAIL"]);
if (strlen($arUser["NAME"]) > 0 || strlen($arUser["LAST_NAME"]) > 0)
{
$userName = preg_replace(
"#['\r\n]+#",
"",
CUser::FormatName(
COption::GetOptionString("bizproc", "name_template", CSite::GetNameFormat(false), SITE_ID),
$arUser,
false, false
)
);
}
$fromList[] = ['name' => $userName, 'email' => $userEmail];
}
}
$mailUserFromTmp = str_replace(', ', $separator, $this->MailUserFrom);
if (strlen($mailUserFromTmp) > 0)
{
$address = new Mail\Address($mailUserFromTmp);
if ($address->validate())
{
$fromList[] = [
'name' => $address->getName(),
'email' => $address->getEmail()
];
}
}
if (!empty($mailUserFromArrayString))
{
foreach ($mailUserFromArrayString as $s)
{
$address = new Mail\Address($s);
if ($address->validate())
{
$fromList[] = [
'name' => $address->getName(),
'email' => $address->getEmail()
];
}
}
}
return $fromList;
}
private function getMailUserTo($separator = self::DEFAULT_SEPARATOR)
{
$strMailUserTo = "";
list($MailUserToArray, $MailUserToArrayString) = static::extractEmails($this->MailUserToArray);
$arMailUserToArray = CBPHelper::ExtractUsers($MailUserToArray, $this->GetDocumentId(), false);
foreach ($arMailUserToArray as $user)
{
$dbUser = CUser::GetList(($b = ""), ($o = ""), array("ID_EQUAL_EXACT" => $user));
if ($arUser = $dbUser->Fetch())
{
if (strlen($strMailUserTo) > 0)
{
$strMailUserTo .= $separator;
}
$strMailUserTo .= preg_replace("#[\r\n]+#", "", $arUser["EMAIL"]);
}
}
$mailUserToTmp = str_replace(', ', $separator, $this->MailUserTo);
if (strlen($mailUserToTmp) > 0)
{
if (strlen($strMailUserTo) > 0)
$strMailUserTo .= $separator;
$strMailUserTo .= preg_replace("#[\r\n]+#", "", $mailUserToTmp);
}
if (!empty($MailUserToArrayString))
{
foreach ($MailUserToArrayString as $s)
{
if (strlen($strMailUserTo) > 0)
$strMailUserTo .= $separator;
$strMailUserTo .= $s;
}
}
return $strMailUserTo;
}
private function getMailText()
{
$mailText = $this->getRawProperty('MailText');
if ($this->MailMessageEncoded)
{
$mailText = self::decodeMailText($mailText);
}
$mailText = $this->ParseValue($mailText, 'text');
return $mailText;
}
private static function encodeMailText($text)
{
return 'base64,' . base64_encode($text);
}
public static function decodeMailText($text)
{
if (strpos($text, 'base64,') === 0)
{
$text = substr($text, 7);
return base64_decode($text);
}
//compatible encode type
return htmlspecialcharsback($text);
}
}