54 case self::ERR_API_DEFAULT:
56 case self::ERR_API_DENIED:
58 case self::ERR_API_NAME_OCCUPIED:
59 return GetMessage(
'MAIL_ERR_API_NAME_OCCUPIED');
60 case self::ERR_API_USER_NOTFOUND:
61 return GetMessage(
'MAIL_ERR_API_USER_NOTFOUND');
62 case self::ERR_API_EMPTY_DOMAIN:
63 return GetMessage(
'MAIL_ERR_API_EMPTY_DOMAIN');
64 case self::ERR_API_EMPTY_NAME:
66 case self::ERR_API_EMPTY_PASSWORD:
67 return GetMessage(
'MAIL_ERR_API_EMPTY_PASSWORD');
68 case self::ERR_API_SHORT_PASSWORD:
69 return GetMessage(
'MAIL_ERR_API_SHORT_PASSWORD');
70 case self::ERR_API_BAD_NAME:
72 case self::ERR_API_BAD_PASSWORD:
73 return GetMessage(
'MAIL_ERR_API_BAD_PASSWORD');
74 case self::ERR_API_PASSWORD_LIKELOGIN:
75 return GetMessage(
'MAIL_ERR_API_PASSWORD_LIKELOGIN');
76 case self::ERR_API_LONG_NAME:
78 case self::ERR_API_LONG_PASSWORD:
79 return GetMessage(
'MAIL_ERR_API_LONG_PASSWORD');
80 case self::ERR_API_OP_DENIED:
82 case self::ERR_API_OLD_TOKEN:
83 return getMessage(
'MAIL_ERR_API_OLD_TOKEN');
84 case self::ERR_API_DOMAIN_OCCUPIED:
85 return GetMessage(
'MAIL_ERR_API_DOMAIN_OCCUPIED');
86 case self::ERR_API_BAD_DOMAIN:
88 case self::ERR_API_PROHIBITED_DOMAIN:
89 return GetMessage(
'MAIL_ERR_API_PROHIBITED_DOMAIN');
90 case self::ERR_ENTRY_NOT_FOUND:
101 $selectResult = CMailbox::getList(
array(),
array(
'USER_ID' => intval(
$arFields[
'ID']),
'ACTIVE' =>
'Y'));
102 while ($mailbox = $selectResult->fetch())
103 CMailbox::update($mailbox[
'ID'],
array(
'ACTIVE' =>
'N'));
109 $selectResult = CMailbox::getList(
array(),
array(
'USER_ID' => intval($id)));
110 while ($mailbox = $selectResult->fetch())
111 CMailbox::delete($mailbox[
'ID']);
118 if (!is_scalar(
$name))
119 throw new \Bitrix\Main\ArgumentTypeException(
'name');
193 parent::__construct(
$res);
198 if(
$res = parent::Fetch())
200 if(!
Bitrix\Main\Loader::includeModule(
'mail'))
205 $entity = \Bitrix\Mail\MailboxTable::getEntity();
207 foreach (
$res as $alias => $value)
209 if (!
$entity->hasField($alias))
214 foreach (
$entity->getField($alias)->getFetchDataModifiers() as $modifier)
216 $res[$alias] = call_user_func_array($modifier,
array(
$res[$alias], $this,
$res, $alias));
243 "SELECT MB.*, C.CHARSET as LANG_CHARSET, ".
244 " ".$DB->DateToCharFunction(
"MB.TIMESTAMP_X").
" as TIMESTAMP_X ".
245 "FROM b_mail_mailbox MB, b_lang L, b_culture C ".
246 "WHERE MB.LID=L.LID AND C.ID=L.CULTURE_ID";
264 $key = mb_strtoupper($filter_keys[
$i]);
266 $strNegative =
false;
267 if (mb_substr(
$key, 0, 1) ==
'!')
274 if (mb_substr(
$key, 0, 1) ==
'=')
284 case 'DELETE_MESSAGES':
298 $arSqlSearch[] =
GetFilterQuery(
'MB.'.
$key, ($strNegative ==
'Y' ?
'~' :
'').
$val, $strExact ==
'Y' ?
'N' :
'Y');
302 $arSqlSearch[] =
'MB.' .
$key . ($strNegative ==
'Y' ?
' != ' :
' = ') . intval(
$val);
307 $is_filtered =
false;
311 if($arSqlSearch[
$i] <>
'')
314 $strSqlSearch .=
" AND (".$arSqlSearch[
$i].
") ";
318 $arSqlOrder = Array();
319 foreach($arOrder as $by=>
$order)
323 $order =
"desc".($DB->type ==
"ORACLE"?
" NULLS LAST":
"");
325 $order =
"asc".($DB->type ==
"ORACLE"?
" NULLS FIRST":
"");
327 switch(mb_strtoupper($by))
337 case "DELETE_MESSAGES":
342 $arSqlOrder[] =
" MB.".$by.
" ".
$order.
" ";
345 $arSqlOrder[] =
" MB.ID ".$order.
" ";
350 $arSqlOrder = array_unique($arSqlOrder);
356 $strSqlOrder =
" ORDER BY ";
360 $strSqlOrder .= $arSqlOrder[
$i];
363 $strSql .= $strSqlSearch.$strSqlOrder;
367 $res->is_filtered = $is_filtered;
373 return CMailBox::GetList(Array(), Array(
"ID"=>
$ID));
384 "FROM b_mail_mailbox MB ".
387 $dbr =
$DB->Query($strSql);
388 while(
$ar = $dbr->Fetch())
397 foreach($mbx as $mailboxId)
400 if(!$mb->Connect($mailboxId))
413 $bUserCreated =
false;
417 $bUserCreated =
true;
421 "SELECT MB.ID, MB.PERIOD_CHECK ".
422 "FROM b_mail_mailbox MB ".
428 $dbr =
$DB->Query($strSql);
429 if(
$ar = $dbr->Fetch())
433 if(intval(
$ar[
"PERIOD_CHECK"])>0)
434 $strReturn =
"CMailbox::CheckMailAgent(".$ID.
");";
479 $dbres = CMailBox::GetList(
array(),
array(
'ACTIVE' =>
'Y',
'SERVER_TYPE' =>
'smtp',
'SERVER' =>
$arFields[
'SERVER'],
'PORT' =>
$arFields[
'PORT']));
480 while($arres = $dbres->Fetch())
482 if (
$ID ===
false || $arres[
'ID'] !=
$ID)
497 $arMsg[] =
array(
'id' =>
'LID',
'text' =>
GetMessage(
'MAIL_CL_ERR_BAD_LANG'));
503 $arMsg[] =
array(
'id' =>
'LID',
'text' =>
GetMessage(
'MAIL_CL_ERR_BAD_LANG_NX'));
506 if (in_array(mb_strtolower(
$arFields[
'SERVER_TYPE']),
array(
'imap',
'controller',
'domain',
'crdomain')))
515 $arMb_tmp = CMailBox::GetList(
array(),
array(
'ID' =>
$ID))->fetch();
516 $LID_tmp = $arMb_tmp[
'LID'];
519 'filter' =>
array(
'=SITE_ID' => $LID_tmp,
'=ID' =>
$arFields[
'SERVICE_ID'])
524 $arMsg[] =
array(
'id' =>
'SERVICE_ID',
'text' =>
GetMessage(
'MAIL_CL_ERR_BAD_SERVICE_ID'));
528 else if (
$ID ===
false)
531 $arMsg[] =
array(
'id' =>
'SERVICE_ID',
'text' =>
GetMessage(
'MAIL_CL_ERR_BAD_SERVICE_ID_NX'));
564 if (!in_array(
$arFields[
"SERVER_TYPE"],
array(
"pop3",
"smtp",
"imap",
"controller",
"domain",
"crdomain")))
570 $ID = \Bitrix\Mail\MailboxTable::add(
$arFields)->getId();
574 $mailboxSyncManager = new \Bitrix\Mail\Helper\Mailbox\MailboxSyncManager(
$arFields[
'USER_ID']);
575 $mailboxSyncManager->setDefaultSyncData(
$ID);
577 if (in_array(
$arFields[
'SERVER_TYPE'],
array(
'imap',
'controller',
'domain',
'crdomain')))
579 \CAgent::addAgent(sprintf(
'Bitrix\Mail\Helper::syncMailboxAgent(%u);',
$ID),
'mail',
'N', (
int)
$arFields[
'PERIOD_CHECK'] * 60);
580 \CAgent::addAgent(sprintf(
'Bitrix\Mail\Helper::cleanupMailboxAgent(%u);',
$ID),
'mail',
'N', 3600 * 24);
584 CAgent::addAgent(sprintf(
'CMailbox::CheckMailAgent(%u);',
$ID),
'mail',
'N', (
int)
$arFields[
'PERIOD_CHECK']*60);
610 if (
is_set(
$arFields,
"SERVER_TYPE") && !in_array(
$arFields[
"SERVER_TYPE"],
array(
"pop3",
"smtp",
"imap",
"controller",
"domain",
"crdomain")))
616 $mbox = \Bitrix\Mail\MailboxTable::getRowById(
$ID);
623 $userChanged = isset(
$arFields[
'USER_ID']) && $mbox[
'USER_ID'] !=
$arFields[
'USER_ID'];
626 if ($userChanged || $siteChanged)
628 if ($mbox[
'ACTIVE'] ==
'Y')
630 if ($mbox[
'USER_ID'] > 0)
632 $mailboxSyncManager = new \Bitrix\Mail\Helper\Mailbox\MailboxSyncManager($mbox[
'USER_ID']);
633 $mailboxSyncManager->deleteSyncData($mbox[
'ID']);
638 if ($newActive ==
'Y')
645 $mailboxSyncManager = new \Bitrix\Mail\Helper\Mailbox\MailboxSyncManager($newUserId);
646 $mailboxSyncManager->setDefaultSyncData($mbox[
'ID']);
651 if ($mbox[
'USER_ID'] != 0 || isset(
$arFields[
'USER_ID']) &&
$arFields[
'USER_ID'] != 0)
653 CUserCounter::Clear($mbox[
'USER_ID'],
'mail_unseen', $mbox[
'LID']);
655 CUserCounter::Clear($mbox[
'USER_ID'],
'mail_unseen',
$arFields[
'LID']);
659 CUserCounter::Clear(
$arFields[
'USER_ID'],
'mail_unseen', $mbox[
'LID']);
666 \CAgent::removeAgent(sprintf(
'CMailbox::CheckMailAgent(%u);',
$ID),
'mail');
667 \CAgent::removeAgent(sprintf(
'Bitrix\Mail\Helper::syncMailboxAgent(%u);',
$ID),
'mail');
668 \CAgent::removeAgent(sprintf(
'Bitrix\Mail\Helper::cleanupMailboxAgent(%u);',
$ID),
'mail');
672 if (in_array($serverType,
array(
'imap',
'controller',
'domain',
'crdomain')))
674 \CAgent::addAgent(sprintf(
'Bitrix\Mail\Helper::syncMailboxAgent(%u);',
$ID),
'mail',
'N', (
int) $periodCheck*60);
675 \CAgent::addAgent(sprintf(
'Bitrix\Mail\Helper::cleanupMailboxAgent(%u);',
$ID),
'mail',
'N', 3600 * 24);
678 if ($serverType ==
'pop3' && (
int) $periodCheck > 0)
679 CAgent::addAgent(sprintf(
'CMailbox::CheckMailAgent(%u);',
$ID),
'mail',
'N', (
int) $periodCheck*60);
698 $db_msg = Bitrix\Mail\MailMessageTable::getList(
array(
699 'select' =>
array(
'ID'),
700 'filter' =>
array(
'MAILBOX_ID' =>
$ID)
702 while($msg = $db_msg->Fetch())
709 while($flt = $db_flt->Fetch())
715 $db_mbox = \CMailbox::getList(
array(
'ID' =>
$ID,
'ACTIVE' =>
'Y'));
716 if ($mbox = $db_mbox->fetch())
718 if ($mbox[
'USER_ID'] > 0)
720 \CUserCounter::clear($mbox[
'USER_ID'],
'mail_unseen', $mbox[
'LID']);
721 $mailboxSyncManager = new \Bitrix\Mail\Helper\Mailbox\MailboxSyncManager($mbox[
'USER_ID']);
722 $mailboxSyncManager->deleteSyncData(
$ID);
726 \CAgent::removeAgent(sprintf(
'CMailbox::CheckMailAgent(%u);',
$ID),
'mail');
727 \CAgent::removeAgent(sprintf(
'Bitrix\Mail\Helper::syncMailboxAgent(%u);',
$ID),
'mail');
728 \CAgent::removeAgent(sprintf(
'Bitrix\Mail\Helper::cleanupMailboxAgent(%u);',
$ID),
'mail');
730 $strSql =
"DELETE FROM b_mail_log WHERE MAILBOX_ID=".$ID;
731 if(!
$DB->Query($strSql,
true))
734 $strSql =
"DELETE FROM b_mail_message_uid WHERE MAILBOX_ID=".$ID;
735 if(!
$DB->Query($strSql,
true))
741 $strSql =
"DELETE FROM b_mail_blacklist WHERE MAILBOX_ID=".$ID;
742 if(!
$DB->Query($strSql,
true))
745 \Bitrix\Mail\Internals\MailboxAccessTable::deleteByFilter([
'=MAILBOX_ID' =>
$ID,]);
746 $DB->query(sprintf(
'DELETE FROM b_mail_mailbox_dir WHERE MAILBOX_ID = %u',
$ID));
747 $DB->query(sprintf(
'DELETE FROM b_mail_counter WHERE MAILBOX_ID = %u',
$ID));
748 $DB->query(sprintf(
'DELETE FROM b_mail_entity_options WHERE MAILBOX_ID = %u',
$ID));
752 \Bitrix\Mail\MailboxTable::delete(
$ID);
767 $command = preg_replace(
"/[\\n\\r]/",
"", $command);
769 fputs($this->pop3_conn, $command.
"\r\n");
771 if($this->mailbox_id>0)
775 "MAILBOX_ID"=>$this->mailbox_id,
777 "MESSAGE"=>
"> ".nl2br(preg_replace(
"'PASS .*'",
"PASS ******", $command))
786 if(!$this->resp)
return false;
789 socket_set_timeout($this->pop3_conn, 20);
790 $res = rtrim(fgets($this->pop3_conn, 1024),
"\r\n");
794 $this->last_result = (
$res[0]==
"+");
795 $this->response =
$res;
797 if($this->mailbox_id>0)
801 "MAILBOX_ID"=>$this->mailbox_id,
802 "STATUS_GOOD"=>($this->last_result?
"Y":
"N"),
808 if($bMultiline &&
$res[0]==
"+")
815 $s = fgets($this->pop3_conn, 1024);
816 while($s <>
'' && $s!=
".\r\n")
818 if(mb_substr($s, 0, 2) ==
"..")
819 $s = mb_substr($s, 1);
821 $s = fgets($this->pop3_conn, 1024);
824 $this->response_body =
$res;
844 if (($use_tls ==
'Y' || $use_tls ==
'S') && !preg_match(
'#^(tls|ssl)://#', $server))
845 $server =
'ssl://' . $server;
847 $skip_cert = $use_tls !=
'Y';
851 sprintf(
'%s:%s', $server, $port),
854 STREAM_CLIENT_CONNECT,
855 stream_context_create(
array(
'ssl' =>
array(
'verify_peer' => !$skip_cert,
'verify_peer_name' => !$skip_cert)))
858 return array(
false,
GetMessage(
"MAIL_CL_TIMEOUT").
" $errstr ($errno)");
876 $arStat = explode(
" ", $stat);
877 return array(
true, $arStat[1]);
885 "SELECT MB.*, C.CHARSET as LANG_CHARSET ".
886 "FROM b_mail_mailbox MB, b_lang L, b_culture C ".
887 "WHERE MB.LID=L.LID AND C.ID=L.CULTURE_ID ".
888 " AND MB.ID=".$mailbox_id;
889 $dbr =
$DB->Query($strSql);
891 if(!$arMAILBOX_PARAMS = $dbr->Fetch())
894 if ($arMAILBOX_PARAMS[
'SYNC_LOCK'] > time()-600)
897 $DB->query(
'UPDATE b_mail_mailbox SET SYNC_LOCK = '.time().
' WHERE ID = '.
$mailbox_id);
901 $DB->query(
'UPDATE b_mail_mailbox SET SYNC_LOCK = 0 WHERE ID = '.
$mailbox_id);
906 private function _connect(
$mailbox_id, $arMAILBOX_PARAMS)
913 if ($arMAILBOX_PARAMS[
"SERVER"] ==
'pop.gmail.com')
914 $arMAILBOX_PARAMS[
"LOGIN"] =
'recent:' . $arMAILBOX_PARAMS[
"LOGIN"];
916 $server = $arMAILBOX_PARAMS[
"SERVER"];
917 if (($arMAILBOX_PARAMS[
'USE_TLS'] ==
'Y' || $arMAILBOX_PARAMS[
'USE_TLS'] ==
'S') && !preg_match(
'#^(tls|ssl)://#', $server))
918 $server =
'ssl://' . $server;
920 $skip_cert = $arMAILBOX_PARAMS[
'USE_TLS'] !=
'Y';
924 sprintf(
'%s:%s', $server, $arMAILBOX_PARAMS[
"PORT"]),
927 STREAM_CLIENT_CONNECT,
928 stream_context_create(
array(
'ssl' =>
array(
'verify_peer' => !$skip_cert,
'verify_peer_name' => !$skip_cert)))
935 "MESSAGE"=>
GetMessage(
"MAIL_CL_CONNECT_TO").
" ".$arMAILBOX_PARAMS[
"SERVER"]
952 if($arMAILBOX_PARAMS[
"CHARSET"]!=
'')
953 $this->charset = $arMAILBOX_PARAMS[
"CHARSET"];
955 $this->charset = $arMAILBOX_PARAMS[
"LANG_CHARSET"];
956 $this->use_md5 = $arMAILBOX_PARAMS[
"USE_MD5"];
958 $session_id = md5(uniqid(
""));
962 if($this->use_md5==
"Y" && preg_match(
"'(<.+>)'", $greeting, $reg))
964 $this->
SendCommand(
"APOP ".$arMAILBOX_PARAMS[
"LOGIN"].
" ".md5($reg[1].$arMAILBOX_PARAMS[
"PASSWORD"]));
970 $this->
SendCommand(
"USER ".$arMAILBOX_PARAMS[
"LOGIN"]);
973 $this->
SendCommand(
"PASS ".$arMAILBOX_PARAMS[
"PASSWORD"]);
983 $arStat = explode(
" ", $stat);
984 $this->mess_count = $arStat[1];
985 if($this->mess_count>0)
987 $this->mess_size = $arStat[2];
990 if($arMAILBOX_PARAMS[
"MAX_MSG_SIZE"]>0)
996 preg_match_all(
"'([0-9]+)[ ]+?(.+)'", $list, $arLIST_temp, PREG_SET_ORDER);
999 $arLIST[intval($arLIST_temp[
$i][1])] = intval($arLIST_temp[
$i][2]);
1007 preg_match_all(
"'([0-9]+)[ ]+?(.+)'", $uidl, $arUIDL_temp, PREG_SET_ORDER);
1010 $cnt =
count($arUIDL_temp);
1011 for (
$i = 0;
$i < $cnt;
$i++)
1012 $arUIDL[md5($arUIDL_temp[
$i][2])] = $arUIDL_temp[
$i][1];
1019 $this->response, $cnt, $this->mess_count
1023 $arOldUIDL =
array();
1024 if (
count($arUIDL) > 0)
1026 $strSql =
'SELECT ID FROM b_mail_message_uid WHERE MAILBOX_ID = ' .
$mailbox_id;
1030 if (isset($arUIDL[
$ar_res[
'ID']]))
1031 unset($arUIDL[
$ar_res[
'ID']]);
1032 else if (!$skipOldUIDL)
1037 while (
count($arOldUIDL) > 0)
1039 $ids =
"'" . join(
"','", array_splice($arOldUIDL, 0, 1000)) .
"'";
1048 $strSql =
'DELETE FROM b_mail_message_uid WHERE MAILBOX_ID = ' .
$mailbox_id .
' AND ID IN (' . $ids .
')';
1049 $DB->query($strSql);
1052 $this->new_mess_count = 0;
1053 $this->deleted_mess_count = 0;
1054 $session_id = md5(uniqid(
""));
1056 foreach($arUIDL as $msguid=>$msgnum)
1058 if($arMAILBOX_PARAMS[
"MAX_MSG_SIZE"]<=0 || $arLIST[$msgnum]<=$arMAILBOX_PARAMS[
"MAX_MSG_SIZE"])
1061 if($arMAILBOX_PARAMS[
"DELETE_MESSAGES"]==
"Y")
1064 $this->deleted_mess_count++;
1067 $this->new_mess_count++;
1068 if($arMAILBOX_PARAMS[
"MAX_MSG_COUNT"]>0 && $arMAILBOX_PARAMS[
"MAX_MSG_COUNT"]<=$this->new_mess_count)
1091 $strSql =
"INSERT INTO b_mail_message_uid(ID, MAILBOX_ID, SESSION_ID, DATE_INSERT, MESSAGE_ID) VALUES('".$DB->ForSql($msguid).
"', ".intval(
$mailbox_id).
", '".
$DB->ForSql($session_id).
"', ".
$DB->GetNowFunction().
", 0)";
1092 $DB->Query($strSql);
1097 $strSql =
"UPDATE b_mail_message_uid SET MESSAGE_ID = " . intval($message_id) .
" WHERE ID = '" .
$DB->forSql($msguid) .
"' AND MAILBOX_ID = " . intval(
$mailbox_id);
1098 $DB->Query($strSql);
1127 if(mb_strtoupper(
$type) ==
"B")
1130 $str = quoted_printable_decode(str_replace(
"_",
" ",
$str));
1143 $str = preg_replace(
'/(=\?.*?\?(?:B|Q)\?.*?\?=)\s+((?1))/i',
'\1\2',
$str, -1,
$n);
1147 $handler =
function ($m) use ($charset_to)
1149 return \CMailHeader::convertHeader($m[1], $m[2], $m[3], $charset_to);
1153 $str = preg_replace_callback(
'/=\?(.*?)\?(B|Q)\?(.*?)\?=/i', $handler,
$str, -1,
$n);
1155 if (
$n == 0 && $charset_document <>
'')
1165 $this->charset = defined(
'BX_MAIL_DEFAULT_CHARSET') && BX_MAIL_DEFAULT_CHARSET !=
'' ? BX_MAIL_DEFAULT_CHARSET :
$charset;
1166 if(preg_match(
"'content-type:.*?charset\s*=\s*([^\r\n;]+)'is", $message_header,
$res))
1167 $this->charset = mb_strtolower(trim(
$res[1],
' "'));
1169 $message_header = preg_replace(
'/\r\n([\x20\t])/i',
'\1', $message_header);
1171 $ar_message_header_tmp = explode(
"\r\n", $message_header);
1173 for (
$i = 0, $num =
count($ar_message_header_tmp);
$i < $num;
$i++)
1175 $this->arHeaderLines[] = \CMailHeader::decodeHeader($ar_message_header_tmp[
$i],
$charset, $this->charset);
1178 $this->arHeader = Array();
1179 for(
$i = 0, $num =
count($this->arHeaderLines);
$i < $num;
$i++)
1181 $p = mb_strpos($this->arHeaderLines[
$i],
":");
1184 $header_name = mb_strtoupper(trim(mb_substr($this->arHeaderLines[
$i], 0,
$p)));
1185 $header_value = trim(mb_substr($this->arHeaderLines[
$i],
$p + 1));
1186 $this->arHeader[$header_name] = $header_value;
1190 $full_content_type = $this->arHeader[
"CONTENT-TYPE"];
1191 if($full_content_type ==
'')
1192 $full_content_type =
"text/plain";
1194 if(!(
$p = mb_strpos($full_content_type,
";")))
1195 $p = mb_strlen($full_content_type);
1197 $this->content_type = trim(mb_substr($full_content_type, 0,
$p));
1198 if(mb_strpos(mb_strtolower($this->content_type),
"multipart/") === 0)
1200 $this->bMultipart =
true;
1201 if (!preg_match(
"'boundary\s*=\s*(.+?);'i", $full_content_type,
$res))
1202 preg_match(
"'boundary\s*=\s*(.+)'i", $full_content_type,
$res);
1204 $this->boundary = trim(
$res[1],
'"');
1205 if(
$p = mb_strpos($this->content_type,
"/"))
1209 if(
$p < mb_strlen($full_content_type))
1211 if(preg_match(
"'name\s*=\s*([^;]+)'i", $full_content_type,
$res))
1213 $this->filename = trim(
$res[1],
'"');
1217 $cd = $this->arHeader[
"CONTENT-DISPOSITION"] ??
'';
1220 if (preg_match(
"'filename\s*=\s*([^;]+)'i", $cd,
$res))
1225 $this->filename = trim(
$res[1],
'"');
1227 else if (preg_match(
"'filename\s*\*=\s*([^;]+)'i", $cd,
$res))
1232 [$fncharset, $fnstr] = preg_split(
"/'[^']*'/", trim(
$res[1],
'"'));
1233 $this->filename = CMailUtil::ConvertCharset(rawurldecode($fnstr), $fncharset,
$charset);
1235 else if (preg_match(
"'filename\s*\*0=\s*([^;]+)'i", $cd,
$res))
1240 $this->filename = trim(
$res[1],
'"');
1243 while (preg_match(
"'filename\s*\*".(++
$i).
"=\s*([^;]+)'i", $cd,
$res))
1245 $this->filename .= trim(
$res[1],
'"');
1248 else if (preg_match(
"'filename\s*\*0\*=\s*([^;]+)'i", $cd,
$res))
1253 $fnstr = trim(
$res[1],
'"');
1256 while (preg_match(
"'filename\s*\*".(++
$i).
"\*?\s*=([^;]+)'i", $cd,
$res))
1258 $fnstr .= trim(
$res[1],
'"');
1261 [$fncharset, $fnstr] = preg_split(
"/'[^']*'/", $fnstr);
1264 $fnstr = rawurldecode($fnstr);
1270 if(isset($this->arHeader[
"CONTENT-ID"]) && $this->arHeader[
"CONTENT-ID"]!=
'')
1271 $this->content_id = trim($this->arHeader[
"CONTENT-ID"],
'"<>');
1273 $this->strHeader = implode(
"\r\n", $this->arHeaderLines);
1295 return isset($this->arHeader[mb_strtoupper(
$type)]) ? $this->arHeader[mb_strtoupper(
$type)] :
'';
1305 if ($item = parent::fetch())
1307 $item[
'OPTIONS'] = (
array) @unserialize($item[
'OPTIONS'], [
'allowed_classes' =>
false]);
1308 $item[
'FOR_SPAM_TEST'] = sprintf(
'%s %s', $item[
'HEADER'], $item[
'BODY_HTML'] ?: $item[
'BODY']);
1326 $sum =
"case when NEW_MESSAGE='Y' then 1 else 0 end";
1331 "COUNT('x') as CNT, SUM(".$sum.
") as CNT_NEW, COUNT('x')-SUM(".
$sum.
") as CNT_OLD "
1333 "MS.*, MB.NAME as MAILBOX_NAME, MB.LID, ".
1334 " ".$DB->DateToCharFunction(
"MS.DATE_INSERT").
" as DATE_INSERT, ".
1335 " ".
$DB->DateToCharFunction(
"MS.FIELD_DATE").
" as FIELD_DATE "
1337 "FROM b_mail_message MS ".
1338 ($bCnt?
"":
" INNER JOIN b_mail_mailbox MB ON MS.MAILBOX_ID=MB.ID ");
1340 $arSqlSearch = Array();
1347 $key = mb_strtoupper(
$res[
"FIELD"]);
1348 $cOperationType =
$res[
"OPERATION"];
1350 if($cOperationType ==
"?")
1352 if (
$val ==
'')
continue;
1429 $is_filtered =
false;
1433 if($arSqlSearch[
$i] <>
'')
1435 $strSqlSearch .=
" AND (".$arSqlSearch[
$i].
") ";
1436 $is_filtered =
true;
1439 $arSqlOrder = Array();
1440 foreach($arOrder as $by=>
$order)
1442 $by = mb_strtolower($by);
1446 $order =
"desc".($DB->type ==
"ORACLE"?
" NULLS LAST":
"");
1448 $order =
"asc".($DB->type ==
"ORACLE"?
" NULLS FIRST":
"");
1450 if ($by ==
"field_date") $arSqlOrder[] =
" MS.FIELD_DATE ".$order.
" ";
1451 elseif ($by ==
"field_from") $arSqlOrder[] =
" MS.FIELD_FROM ".$order.
" ";
1452 elseif ($by ==
"field_reply_to")$arSqlOrder[] =
" MS.FIELD_REPLY_TO ".$order.
" ";
1453 elseif ($by ==
"field_to") $arSqlOrder[] =
" MS.FIELD_TO ".$order.
" ";
1454 elseif ($by ==
"field_cc") $arSqlOrder[] =
" MS.FIELD_CC ".$order.
" ";
1455 elseif ($by ==
"field_bcc") $arSqlOrder[] =
" MS.FIELD_BCC ".$order.
" ";
1456 elseif ($by ==
"subject") $arSqlOrder[] =
" MS.SUBJECT ".$order.
" ";
1457 elseif ($by ==
"attachments") $arSqlOrder[] =
" MS.ATTACHMENTS ".$order.
" ";
1458 elseif ($by ==
"date_insert") $arSqlOrder[] =
" MS.DATE_INSERT ".$order.
" ";
1459 elseif ($by ==
"msguid") $arSqlOrder[] =
" MS.MSGUID ".$order.
" ";
1460 elseif ($by ==
"mailbox_id") $arSqlOrder[] =
" MS.MAILBOX_ID ".$order.
" ";
1461 elseif ($by ==
"new_message") $arSqlOrder[] =
" MS.NEW_MESSAGE ".$order.
" ";
1462 elseif ($by ==
"mailbox_name" && !$bCnt) $arSqlOrder[] =
" MB.NAME ".$order.
" ";
1463 elseif ($by ==
"spam_rating")
1467 else $arSqlOrder[] =
" MS.ID ".$order.
" ";
1471 $arSqlOrder = array_unique($arSqlOrder);
1477 $strSqlOrder =
" ORDER BY ";
1479 $strSqlOrder .=
",";
1481 $strSqlOrder .= $arSqlOrder[
$i];
1484 $strSql .=
" WHERE 1=1 ".$strSqlSearch.$strSqlOrder;
1486 $dbr =
$DB->Query($strSql);
1487 $dbr = new \CMailMessageDBResult($dbr);
1488 $dbr->is_filtered = $is_filtered;
1502 if(!is_array($arRow))
1503 $res =
$DB->Query(
"SELECT SPAM_RATING, SPAM_LAST_RESULT, HEADER, BODY_HTML, BODY FROM b_mail_message WHERE ID=".intval($msgid));
1507 if(is_array($arRow) ||
$res && (
$ar =
$res->Fetch()))
1509 if (empty(
$ar[
'FOR_SPAM_TEST']))
1511 $ar[
'FOR_SPAM_TEST'] = sprintf(
'%s %s',
$ar[
'HEADER'],
$ar[
'BODY_HTML'] ?:
$ar[
'BODY'] );
1514 if(
$ar[
"SPAM_LAST_RESULT"]==
"Y")
1515 return $ar[
"SPAM_RATING"];
1517 $num = Round($arSpam[
"RATING"], 4);
1518 $DB->Query(
"UPDATE b_mail_message SET SPAM_RATING=".$num.
", SPAM_LAST_RESULT='Y', SPAM_WORDS='".
$DB->ForSql($arSpam[
"WORDS"], 255).
"' WHERE ID=".intval($msgid));
1527 $h->parse($header, $charset);
1533 $encoding = mb_strtolower($header->GetHeader(
'CONTENT-TRANSFER-ENCODING'));
1535 if ($encoding ==
'base64')
1536 $body = base64_decode($body);
1537 elseif ($encoding ==
'quoted-printable')
1538 $body = quoted_printable_decode($body);
1539 elseif ($encoding ==
'x-uue')
1542 $content_type = mb_strtolower($header->content_type);
1543 if (empty($header->filename) && !empty($header->charset))
1545 if (preg_match(
'/plain|html|text/', $content_type) && !preg_match(
'/x-vcard|csv/', $content_type))
1547 $body = Emoji::encode($body);
1553 'CONTENT-TYPE' => $content_type,
1554 'CONTENT-ID' => $header->content_id,
1556 'FILENAME' => $header->filename
1562 $headerP = strpos(
$message,
"\r\n\r\n");
1564 if (
false === $headerP)
1571 $rawHeader = substr(
$message, 0, $headerP);
1572 $body = substr(
$message, $headerP+4);
1582 if ($header->isMultipart())
1585 $startRegex = sprintf(
'/(^|\r\n)--%s\r\n/', preg_quote($header->getBoundary(),
'/'));
1586 if (preg_match($startRegex, $body,
$matches, PREG_OFFSET_CAPTURE))
1591 $endP = strlen($body);
1592 $endRegex = sprintf(
'/\r\n--%s--(\r\n|$)/', preg_quote($header->getBoundary(),
'/'));
1593 if (preg_match($endRegex, $body,
$matches, PREG_OFFSET_CAPTURE))
1598 if (!($startP < $endP))
1603 $data = substr($body, $startP, $endP-$startP);
1606 $rawParts = preg_split(sprintf(
'/\r\n--%s\r\n/', preg_quote($header->getBoundary(),
'/')),
$data);
1607 $tmpParts =
array();
1608 foreach ($rawParts as $part)
1610 if (substr($part, 0, 2) ==
"\r\n")
1611 $part =
"\r\n" . $part;
1619 $tmpParts[] =
array($subHtml, $subText);
1621 $parts = array_merge($parts, $subParts);
1624 if (mb_strtolower($header->MultipartType()) ==
'alternative')
1628 foreach ($tmpParts as $part)
1632 if (!$htmlBody || (mb_strlen($htmlBody) < mb_strlen($part[0])))
1634 $htmlBody = $part[0];
1635 $candidate = $part[1];
1640 if (!$textBody || mb_strlen($textBody) < mb_strlen($part[1]))
1641 $textBody = $part[1];
1645 if (!trim($textBody))
1646 $textBody = $candidate;
1650 foreach ($tmpParts as $part)
1653 $textBody .=
"\r\n\r\n";
1654 $textBody .= $part[1];
1659 $htmlBody .=
"\r\n\r\n";
1661 $htmlBody .= $part[0] ?: $part[1];
1669 $contentType = mb_strtolower($bodyPart[
'CONTENT-TYPE']);
1672 !$bodyPart[
'FILENAME']
1679 $htmlBody = $bodyPart[
'BODY'];
1680 $textBody = html_entity_decode(htmlToTxt($bodyPart[
'BODY']), ENT_QUOTES | ENT_HTML401, $charset);
1684 $textBody = $bodyPart[
'BODY'];
1689 $parts[] = $bodyPart;
1693 return array($header, $htmlBody, $textBody, $parts);
1700 return static::saveMessage($mailboxId,
$message, $header, $html,
$text, $attachments,
$params);
1705 $obHeader = &$header;
1706 $message_body_html = &$bodyHtml;
1707 $message_body = &$bodyText;
1708 $arMessageParts = &$attachments;
1710 $isStrippedTagsToBody =
false;
1711 $isOriginalEmptyBody = empty(trim(strip_tags($message_body_html)));
1713 if (self::isLongMessageBody($message_body))
1719 (mb_strlen($message_body_html) > 0)
1720 && empty(trim(strip_tags($message_body_html)))
1723 $message_body_html =
'';
1724 $isStrippedTagsToBody =
true;
1728 "MAILBOX_ID" => $mailboxId,
1729 "HEADER" => $obHeader->strHeader,
1730 "FIELD_DATE_ORIGINAL" => $obHeader->GetHeader(
"DATE"),
1731 "NEW_MESSAGE" =>
"Y",
1732 "FIELD_FROM" => $obHeader->GetHeader(
"FROM"),
1733 "FIELD_REPLY_TO" => $obHeader->GetHeader(
"REPLY-TO"),
1734 "FIELD_TO" => $obHeader->GetHeader(
"TO"),
1735 "FIELD_CC" => $obHeader->GetHeader(
"CC"),
1736 "FIELD_BCC" => ($obHeader->GetHeader(
'X-Original-Rcpt-to')!=
''?$obHeader->GetHeader(
'X-Original-Rcpt-to').($obHeader->GetHeader(
"BCC")!=
''?
', ':
''):
'').$obHeader->GetHeader(
"BCC"),
1737 "MSG_ID" => trim($obHeader->GetHeader(
"MESSAGE-ID"),
" <>"),
1738 "FIELD_PRIORITY" => intval($obHeader->GetHeader(
"X-PRIORITY")),
1740 "SUBJECT" => $obHeader->GetHeader(
"SUBJECT"),
1741 "BODY" => rtrim($message_body),
1743 'attachments' =>
count($arMessageParts),
1744 'isStrippedTags' => $isStrippedTagsToBody,
1745 'isOriginalEmptyBody' => $isOriginalEmptyBody,
1747 MailMessageTable::FIELD_SANITIZE_ON_VIEW => (
int)(
$params[MailMessageTable::FIELD_SANITIZE_ON_VIEW] ?? 0)
1751 (
$arFields[
'OPTIONS'][
'attachments'] <= 0)
1752 && (empty($message_body) || empty($message_body_html))
1755 $arFields[
'OPTIONS'][
'isEmptyBody'] =
'Y';
1758 $inReplyTo = trim($obHeader->GetHeader(
"IN-REPLY-TO"),
" <>");
1760 if($inReplyTo !==
'')
1765 $datetime = preg_replace(
'/(?<=[\s\d])UT$/i',
'+0000',
$arFields[
'FIELD_DATE_ORIGINAL']);
1766 if (!(isset(
$params[
'replaces']) &&
$params[
'replaces'] > 0) || strtotime($datetime) ||
$params[
'timestamp'])
1768 $timestamp = strtotime($datetime) ?:
$params[
'timestamp'] ?: time();
1769 $arFields[
'FIELD_DATE'] = convertTimeStamp($timestamp + \CTimeZone::getOffset(),
'FULL');
1777 $forSpamTest = sprintf(
'%s %s',
$arFields[
'HEADER'], $message_body_html ?: $message_body);
1782 $arSpam = \CMailFilter::getSpamRating($forSpamTest);
1783 $arFields[
"SPAM_RATING"] = $arSpam[
"RATING"];
1784 $arFields[
"SPAM_WORDS"] = $arSpam[
"WORDS"];
1790 $arFields[
'SEARCH_CONTENT'] = \Bitrix\Mail\Helper\Message::prepareSearchContent(
$arFields);
1794 \CMailMessage::update($message_id =
$params[
'replaces'],
$arFields, $mailboxId);
1803 $message_id = \CMailMessage::add(
$arFields, $mailboxId);
1806 if ($message_id > 0)
1809 $arFields[
'FOR_SPAM_TEST'] = $forSpamTest;
1811 \CMailLog::addMessage(
array(
1812 'MAILBOX_ID' => $mailboxId,
1813 'MESSAGE_ID' => $message_id,
1814 'STATUS_GOOD' =>
'Y',
1815 'LOG_TYPE' => isset(
$params[
'replaces']) &&
$params[
'replaces'] > 0 ?
'RENEW_MESSAGE' :
'NEW_MESSAGE',
1816 'MESSAGE' => sprintf(
1819 ? sprintf(
' [%.3f]',
$arFields[
'SPAM_RATING']) :
''
1830 MessageClosureTable::insertIgnoreFromSql(sprintf(
'VALUES (%1$u, %1$u)', $message_id));
1838 self::makeMessageClosureChain($message_id, $mailboxId, (
string)
$arFields[
'IN_REPLY_TO']);
1841 static $cachedMailboxes = [];
1843 if (!array_key_exists($mailboxId, $cachedMailboxes))
1845 $cachedMailboxes[$mailboxId] = Bitrix\Mail\MailboxTable::getList([
1846 'select' => [
'ID',
'USER_ID',
'OPTIONS'],
1847 'filter' => [
'=ID' => $mailboxId,
'=ACTIVE' =>
'Y'],
1851 $mailbox = $cachedMailboxes[$mailboxId];
1853 if ($mailbox[
'USER_ID'] > 0)
1856 MailContact::getContactsData(
$arFields[
'FIELD_TO'], $mailbox[
'USER_ID'], \
Bitrix\Mail\Internals\MailContactTable::ADDED_TYPE_TO),
1857 MailContact::getContactsData(
$arFields[
'FIELD_FROM'], $mailbox[
'USER_ID'], \
Bitrix\Mail\Internals\MailContactTable::ADDED_TYPE_FROM),
1858 MailContact::getContactsData(
$arFields[
'FIELD_CC'], $mailbox[
'USER_ID'], \
Bitrix\Mail\Internals\MailContactTable::ADDED_TYPE_CC),
1859 MailContact::getContactsData(
$arFields[
'FIELD_REPLY_TO'], $mailbox[
'USER_ID'], \
Bitrix\Mail\Internals\MailContactTable::ADDED_TYPE_REPLY_TO),
1860 MailContact::getContactsData(
$arFields[
'FIELD_BCC'], $mailbox[
'USER_ID'], \
Bitrix\Mail\Internals\MailContactTable::ADDED_TYPE_BCC)
1868 foreach ($arMessageParts as
$i => $part)
1870 $attachFields =
array(
1871 'MESSAGE_ID' => $message_id,
1872 'FILE_NAME' => $part[
'FILENAME'],
1873 'CONTENT_TYPE' => $part[
'CONTENT-TYPE'],
1874 'FILE_DATA' => $part[
'BODY'],
1875 'CONTENT_ID' => $part[
'CONTENT-ID'],
1879 if (!$arMessageParts[
$i][
'ATTACHMENT-ID'])
1881 \CMailMessage::delete($message_id);
1891 if ($message_body_html)
1893 if (isset(
$params[MailMessageTable::FIELD_SANITIZE_ON_VIEW])
1894 &&
$params[MailMessageTable::FIELD_SANITIZE_ON_VIEW])
1896 $arFields[
'BODY_HTML'] = $message_body_html;
1900 Ini::adjustPcreBacktrackLimit(strlen($message_body_html)*2);
1903 'html' => $message_body_html,
1904 'attachments' =>
array(),
1906 foreach ($arMessageParts as $part)
1908 if (!(is_array($part) && $part[
'ATTACHMENT-ID'] > 0))
1913 $msg[
'attachments'][] =
array(
1914 'contentId' => $part[
'CONTENT-ID'],
1915 'uniqueId' => sprintf(
'attachment_%u', $part[
'ATTACHMENT-ID']),
1921 $arFields[
'BODY_HTML'] = \Bitrix\Mail\Helper\Message::sanitizeHtml($message_body_html,
true);
1924 foreach ($arMessageParts as $part)
1926 if (!(is_array($part) && $part[
'ATTACHMENT-ID'] > 0))
1931 $arFields[
'BODY_HTML'] = \Bitrix\Mail\Helper\Message::replaceBodyInlineImgContentId(
1933 (
string)$part[
'CONTENT-ID'],
1934 $part[
'ATTACHMENT-ID'],
1938 \CMailMessage::update($message_id,
array(
'BODY_HTML' =>
$arFields[
'BODY_HTML']), $mailboxId);
1942 self::addDefferedDownload($mailboxId, $message_id);
1960 $messageBindings =
array();
1964 'onBeforeUserFieldSave',
1965 function (\
Bitrix\Main\Event
$event) use (&$messageBindings)
1968 $messageBindings[] =
$params[
'entity_type'];
1974 foreach ([
'BODY',
'BODY_BB',
'BODY_HTML',
'SUBJECT'] as
$key)
1976 if(!empty($arFieldsForFilter[
$key]))
1978 $arFieldsForFilter[
$key] = Emoji::decode($arFieldsForFilter[
$key]);
1982 \CMailFilter::filter($arFieldsForFilter,
'R');
1986 $icalAccess = isset($mailbox[
'OPTIONS'][
'ical_access']) && ($mailbox[
'OPTIONS'][
'ical_access'] ===
'Y');
1987 $event = new \Bitrix\Main\Event(
'mail',
'onMailMessageNew', [
1989 'attachments' => $arMessageParts,
1990 'userId' => isset($mailbox[
'USER_ID']) ? $mailbox[
'USER_ID'] :
null,
1991 'icalAccess' => $icalAccess
1999 (empty(
$arFields[
'IN_REPLY_TO']) ?
'message' :
'reply'),
2000 (empty(
$params[
'outcome']) ?
'incoming' :
'outgoing')
2002 join(
',', array_unique(array_filter($messageBindings))),
2021 private static function makeMessageClosureChain(
int $messageId,
int $mailboxId,
string $inReply): void
2024 MessageClosureTable::insertIgnoreFromSelect(sprintf(
"SELECT DISTINCT %u, C.PARENT_ID
2025 FROM b_mail_message M
2026 INNER JOIN b_mail_message_closure C ON M.ID = C.MESSAGE_ID
2027 WHERE M.MAILBOX_ID = %u AND M.MSG_ID = '%s'",
2030 $helper->forSql($inReply)));
2055 $datetime = preg_replace(
'/(?<=[\s\d])UT$/i',
'+0000',
$arFields[
'FIELD_DATE_ORIGINAL']);
2056 $timestamp = strtotime($datetime) ?: time();
2057 $arFields[
'FIELD_DATE'] = convertTimeStamp($timestamp + \CTimeZone::getOffset(),
'FULL');
2060 if (array_key_exists(
'SUBJECT',
$arFields))
2065 if (array_key_exists(
'OPTIONS',
$arFields))
2071 $sql = sprintf(
"INSERT INTO b_mail_message (%s) VALUES (%s)",
$params[0],
$params[1]);
2072 $length = strlen($sql);
2077 $trimLength = $length - $limit;
2078 self::trimContent(
$arFields, $trimLength, [[
'BODY_HTML',
'BODY'],
'SEARCH_CONTENT',
'HEADER']);
2081 $sql = sprintf(
"INSERT INTO b_mail_message (%s) VALUES (%s)",
$params[0],
$params[1]);
2086 $ID = intval(
$DB->LastID());
2088 static::saveForDeferredDownload(
$ID,
$arFields, $mailboxID);
2093 private static function saveForDeferredDownload(
$ID,
$arFields, $mailboxID)
2096 $mailboxID !==
false
2100 && !
$arFields[
'OPTIONS'][
'isStrippedTags']
2103 self::addDefferedDownload($mailboxID,
$ID);
2107 private static function addDefferedDownload($mailboxID,
$ID): void
2109 \Bitrix\Mail\Internals\MailEntityOptionsTable::add([
2110 'MAILBOX_ID' => $mailboxID,
2111 'ENTITY_TYPE' =>
'MESSAGE',
2113 'PROPERTY_NAME' =>
'UNSYNC_BODY',
2114 'DATE_INSERT' =>
new \Bitrix\Main\Type\DateTime(),
2126 $datetime = preg_replace(
'/(?<=[\s\d])UT$/i',
'+0000',
$arFields[
'FIELD_DATE_ORIGINAL']);
2127 $timestamp = strtotime($datetime) ?: time();
2128 $arFields[
'FIELD_DATE'] = convertTimeStamp($timestamp + \CTimeZone::getOffset(),
'FULL');
2131 if (array_key_exists(
'SUBJECT',
$arFields))
2136 if (array_key_exists(
'OPTIONS',
$arFields))
2142 $sql = sprintf(
"UPDATE b_mail_message SET %s WHERE ID=%s",
$params,
$ID);
2143 $length = strlen($sql);
2148 $trimLength = $length - $limit;
2149 self::trimContent(
$arFields, $trimLength, [[
'BODY_HTML',
'BODY'],
'SEARCH_CONTENT',
'HEADER']);
2152 $sql = sprintf(
"UPDATE b_mail_message SET %s WHERE ID=%s",
$params,
$ID);
2157 static::saveForDeferredDownload(
$ID,
$arFields, $mailboxID);
2162 private static function trimContent(
array &
$fields, $trimLength, $filters)
2176 $totalLength = array_reduce(
2181 return $total + $length;
2186 if ($totalLength === 0)
2193 foreach (
$filter as $subFilter)
2195 $length = strlen(
$fields[$subFilter]);
2196 $ratio = $length / $totalLength;
2197 $over = ceil($trimLength * $ratio);
2198 $newLength = $length - $over;
2199 $fields[$subFilter] = $newLength > 0 ? substr(
$fields[$subFilter], 0, $newLength) :
'';
2200 $overLength += $newLength > 0 ? $over : $length;
2203 $trimLength -= $overLength;
2210 $newLength = $length - $trimLength;
2212 $trimLength -= $newLength > 0 ? $trimLength : $length;
2216 if ($trimLength <= 0)
2230 $res =
$DB->query(
'SELECT FILE_ID FROM b_mail_msg_attachment WHERE MESSAGE_ID = '.$id);
2231 while ($file =
$res->fetch())
2233 if ($file[
'FILE_ID'])
2235 CFile::delete($file[
'FILE_ID']);
2240 $strSql =
"DELETE FROM b_mail_msg_attachment WHERE MESSAGE_ID=".$id;
2241 $DB->Query($strSql);
2243 $DB->query(sprintf(
'DELETE FROM b_mail_message_access WHERE MESSAGE_ID = %u', $id));
2245 $DB->query(sprintf(
'DELETE FROM b_mail_message_closure WHERE MESSAGE_ID = %1$u OR PARENT_ID = %1$u', $id));
2247 $strSql =
"DELETE FROM b_mail_message WHERE ID=".$id;
2248 $DB->Query($strSql);
2258 if(!is_array($arRow))
2259 $res =
$DB->Query(
"SELECT SPAM, HEADER, BODY_HTML, BODY, MAILBOX_ID FROM b_mail_message WHERE ID=".intval(
$ID));
2263 if(is_array($arRow) ||
$res && (
$ar =
$res->Fetch()))
2265 if (empty(
$ar[
'FOR_SPAM_TEST']))
2267 $ar[
'FOR_SPAM_TEST'] = sprintf(
'%s %s',
$ar[
'HEADER'],
$ar[
'BODY_HTML'] ?:
$ar[
'BODY'] );
2272 if(
$ar[
"SPAM"]!=
"Y")
2274 if(
$ar[
"SPAM"]==
"N")
2281 "MAILBOX_ID"=>
$ar[
"MAILBOX_ID"],
2290 if(
$ar[
"SPAM"]!=
"N")
2292 if(
$ar[
"SPAM"]==
"Y")
2299 "MAILBOX_ID"=>
$ar[
"MAILBOX_ID"],
2301 "LOG_TYPE"=>
"NOTSPAM"
2306 $DB->Query(
"UPDATE b_mail_message SET SPAM_LAST_RESULT='N' WHERE ID=".intval(
$ID));
2316 $strSql =
"SELECT ID, MAILBOX_ID, ATTACHMENTS FROM b_mail_message WHERE ID=".intval(
$arFields[
"MESSAGE_ID"]);
2317 $dbr =
$DB->Query($strSql);
2318 if(!($dbr_arr = $dbr->Fetch()))
2321 $n = intval($dbr_arr[
"ATTACHMENTS"])+1;
2324 $arFields[
'FILE_NAME'] = AttachmentHelper::generateFileName(
2325 $dbr_arr[
'MAILBOX_ID'],
2337 $filename = CTempFile::GetFileName(md5(uniqid(
"")).
'.tmp');
2341 $img_arr = CFile::GetImageSize(
$filename);
2342 $arFields[
"IMAGE_WIDTH"] = $img_arr? $img_arr[0]: 0;
2343 $arFields[
"IMAGE_HEIGHT"] = $img_arr? $img_arr[1]: 0;
2355 'MODULE_ID' =>
'mail'
2358 if (!($file_id = CFile::saveFile($file, AttachmentHelper::generateMessageAttachmentPath())))
2373 $strSql =
'UPDATE b_mail_message SET ATTACHMENTS = ' .
$n .
' WHERE ID = ' . intval(
$arFields[
'MESSAGE_ID']);
2374 $DB->query($strSql);
2384 catch (\Exception $e)
2386 Application::getInstance()->getExceptionHandler()->writeToLog($e);
2417 $limit = (int)\
Bitrix\Main\Config\Option::get(
'mail',
'~max_email_body_length',
false);
2418 return ($limit > 0) ? $limit : self::MAX_LENGTH_MESSAGE_BODY;
2426 private static function getClearBody(
string $body): string
2430 $innerBody = trim(preg_replace(
'/(.*?<body[^>]*>)(.*?)(<\/body>.*)/is',
'$2', $body));
2431 $body = $innerBody ?: $body;
2434 $body = preg_replace_callback(
2435 "%<a[^>]*?href=(['\"])(?<href>[^\1]*?)(?1)[^>]*?>(?<text>.*?)<\/a>%ims",
2445 return (
$text ?
"$text:" :
'') .
"\n$href\n";
2451 $body = preg_replace(
'/<br(\s*)?\/?>/i',
"\n", $body);
2453 $body = preg_replace(
'|(<style[^>]*>)(.*?)(<\/style>)|isU',
'', $body);
2454 $body = preg_replace(
'|(<script[^>]*>)(.*?)(<\/script>)|isU',
'', $body);
2457 $body = strip_tags($body);
2461 foreach (explode(
"\n", trim($body)) as $line)
2463 $lines[] = trim($line);
2467 $body = preg_replace(
"/[\\n]{2,}/",
"\n\n", implode(
"\n", $lines));
2470 $body = preg_replace(
"/[ \\t]{2,}/",
" ", $body);
2473 return html_entity_decode($body);
2483 $messageBodyHtml =
'';
2485 $boundaryMatches = [];
2486 preg_match(
'/content-type: multipart\/mixed; [\s\n\t]*boundary=\"(?<boundary>[\w+-]+)\"/i', $body, $boundaryMatches);
2487 if (is_string($boundaryMatches[
'boundary']))
2489 $parts = explode(
'--'. $boundaryMatches[
'boundary'][0], $body);
2490 if (
count($parts) > 1)
2492 foreach ($parts as $part)
2494 preg_match(
'/content-type: (?<contentType>text\/[html|plain]+); *charset="(?<charset>\w+-\d)"/i', $part, $contentTypeMatches);
2495 if (isset($contentTypeMatches[
'contentType']))
2497 preg_match(
'/content-transfer-encoding: (?<encode>[\w]+)/i', $part, $encodeMatches);
2500 if ($partBody ===
null)
2505 if ($encodeMatches[
'encode'] ===
'base64')
2507 $partBody = base64_decode($partBody);
2510 if ($contentTypeMatches[
'contentType'] ===
'text/plain')
2512 $messageBody = $partBody;
2515 if ($contentTypeMatches[
'contentType'] ===
'text/html')
2517 $messageBodyHtml = $partBody;
2524 return [$messageBody, $messageBodyHtml];
2534 if (mb_stripos($messageBody,
'--- Below this line is a copy of the message'))
2536 $mainBodyHtml = $mainBody = explode(
'--- Below this line is a copy of the message', $messageBody)[0];
2538 elseif (mb_stripos($messageBodyHtml,
'<blockquote'))
2540 $mainBody = $mainBodyHtml = self::cutBlockQuote($messageBodyHtml);
2544 $mainBody = $mainBodyHtml = self::cutBlockHtmlQuote($messageBodyHtml);
2546 elseif (mb_stripos($messageBody,
'<blockquote'))
2548 $mainBody = $mainBodyHtml = self::cutBlockQuote($messageBody);
2553 if ($mainBody ===
'' && $mainBodyHtml ===
'')
2556 $mainBody = mb_substr($messageBody, 0, $limit);
2557 $mainBodyHtml = mb_substr($messageBodyHtml, 0, $limit);
2561 $mainBody = (string) $mainBody;
2562 $mainBodyHtml = (string) $mainBodyHtml;
2564 $mainBody = self::getClearBody($mainBody);
2566 return [$mainBody, $mainBodyHtml];
2575 $itemParts = explode(
"\r\n\r\n", $part);
2576 if (!is_array($itemParts) && (
count($itemParts) < 2))
2578 $itemParts = explode(
"\n\n", $part);
2581 if (!is_array($itemParts) && (
count($itemParts) < 2))
2583 $itemParts = explode(
"\r\n\n\r\n", $part);
2586 if (!is_array($itemParts) && (
count($itemParts) < 2))
2588 $itemParts = explode(
"\n\n\n", $part);
2591 if (is_array($itemParts) && (
count($itemParts) >= 2))
2593 return $itemParts[1];
2603 private static function cutBlockQuote(&$messageBodyHtml):
array|string|null
2605 return preg_replace(
'|(<blockquote([^>]*)>)(.*?)(<\/blockquote>)|isU',
'', $messageBodyHtml);
2612 private static function cutBlockHtmlQuote(&$messageBodyHtml): string
2625 parent::__construct(
$res);
2630 if ((
$res = parent::fetch()) &&
$res[
'FILE_ID'] > 0)
2632 if ($file = \CFile::makeFileArray(
$res[
'FILE_ID']))
2634 if (!empty($file[
'tmp_name']) && \
Bitrix\Main\IO\File::isFileExists($file[
'tmp_name']))
2640 $res[
'FILE_DATA'] =
false;
2657 "FROM b_mail_msg_attachment MA ";
2659 $arSqlSearch = Array();
2663 $key = mb_strtoupper(
$res[
"FIELD"]);
2664 $cOperationType =
$res[
"OPERATION"];
2666 if($cOperationType ==
"?")
2668 if (
$val ==
'')
continue;
2675 case "IMAGE_HEIGHT":
2682 case "CONTENT_TYPE":
2695 case "IMAGE_HEIGHT":
2699 case "CONTENT_TYPE":
2707 $is_filtered =
false;
2711 if($arSqlSearch[
$i] <>
'')
2713 $strSqlSearch .=
" AND (".$arSqlSearch[
$i].
") ";
2714 $is_filtered =
true;
2717 $arSqlOrder = Array();
2718 foreach($arOrder as $by=>
$order)
2720 $by = mb_strtolower($by);
2724 $order =
"desc".($DB->type ==
"ORACLE"?
" NULLS LAST":
"");
2726 $order =
"asc".($DB->type ==
"ORACLE"?
" NULLS FIRST":
"");
2728 if ($by ==
"message_id") $arSqlOrder[] =
" MA.MESSAGE_ID ".$order.
" ";
2729 elseif ($by ==
"file_name") $arSqlOrder[] =
" MA.FILE_NAME ".$order.
" ";
2730 elseif ($by ==
"file_size") $arSqlOrder[] =
" MA.FILE_SIZE ".$order.
" ";
2731 elseif ($by ==
"content_type") $arSqlOrder[] =
" MA.CONTENT_TYPE ".$order.
" ";
2732 elseif ($by ==
"image_width") $arSqlOrder[] =
" MA.IMAGE_WIDTH ".$order.
" ";
2733 elseif ($by ==
"image_height") $arSqlOrder[] =
" MA.IMAGE_HEIGHT ".$order.
" ";
2734 else $arSqlOrder[] =
" MA.ID ".$order.
" ";
2738 $arSqlOrder = array_unique($arSqlOrder);
2744 $strSqlOrder =
" ORDER BY ";
2746 $strSqlOrder .=
",";
2748 $strSqlOrder .= $arSqlOrder[
$i];
2751 $strSql .=
" WHERE 1=1 ".$strSqlSearch.$strSqlOrder;
2753 $dbr =
$DB->Query($strSql);
2755 $dbr->is_filtered = $is_filtered;
2769 $res =
$DB->query(
'SELECT FILE_ID FROM b_mail_msg_attachment WHERE MESSAGE_ID = '.$id);
2770 while ($file =
$res->fetch())
2772 if ($file[
'FILE_ID'])
2774 CFile::delete($file[
'FILE_ID']);
2779 $strSql =
"DELETE FROM b_mail_msg_attachment WHERE ID=".$id;
2780 $DB->Query($strSql);
2785 if (!is_array($attachment))
2787 if (
$res = CMailAttachment::getByID($attachment))
2788 $attachment =
$res->fetch();
2791 if (is_array($attachment))
2793 if (!empty($attachment[
'FILE_DATA']))
2794 return $attachment[
'FILE_DATA'];
2796 if ($attachment[
'FILE_ID'] > 0)
2798 if ($file = \CFile::makeFileArray($attachment[
'FILE_ID']))
2800 return (!empty($file[
'tmp_name'])
2801 && \
Bitrix\Main\IO\File::isFileExists($file[
'tmp_name']))
2819 $from = trim(mb_strtolower($from));
2820 $to = trim(mb_strtolower($to));
2829 if (in_array($from,
array(
'utf-8',
'utf8')))
2832 $str = preg_replace_callback(
'/
2834 |[\xC2-\xDF][\x80-\xBF]
2835 |\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]
2836 |\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})
2838 /x', $escape,
$str);
2844 addMessage2Log(sprintf(
'Failed to convert email part. (%s -> %s : %s)', $from, $to,
$error));
2847 if (in_array($to,
array(
'utf-8',
'utf8')))
2850 $str = preg_replace_callback(
'/
2852 |[\xC2-\xDF][\x80-\xBF]
2853 |\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF])
2855 /x', $escape,
$str);
2863 preg_match(
"/begin [0-7]{3} .+?\r?\n(.+)?\r?\nend/is",
$str, $reg);
2867 $str = preg_split(
"/\r?\n/", trim(
$str));
2871 for (
$i = 0;
$i < $strlen;
$i++)
2875 $len= (((ord(mb_substr(
$str[
$i], 0, 1)) -32) - $spaceCharOrd) & 077);
2877 while (($d + 3 <= $len) AND ($pos + 4 <= mb_strlen(
$str[
$i])))
2879 $c0 = (ord(mb_substr(
$str[
$i], $pos, 1)) ^ 0x20);
2880 $c1 = (ord(mb_substr(
$str[
$i], $pos + 1, 1)) ^ 0x20);
2881 $c2 = (ord(mb_substr(
$str[
$i], $pos + 2, 1)) ^ 0x20);
2882 $c3 = (ord(mb_substr(
$str[
$i], $pos + 3, 1)) ^ 0x20);
2883 $res .= chr(((($c0 - $spaceCharOrd) & 077) << 2) | ((($c1 - $spaceCharOrd) & 077) >> 4)).
2884 chr(((($c1 - $spaceCharOrd) & 077) << 4) | ((($c2 - $spaceCharOrd) & 077) >> 2)).
2885 chr(((($c2 - $spaceCharOrd) & 077) << 6) | (($c3 - $spaceCharOrd) & 077));
2891 if (($d + 2 <= $len) && ($pos + 3 <= mb_strlen(
$str[
$i])))
2893 $c0 = (ord(mb_substr(
$str[
$i], $pos, 1)) ^ 0x20);
2894 $c1 = (ord(mb_substr(
$str[
$i], $pos + 1, 1)) ^ 0x20);
2895 $c2 = (ord(mb_substr(
$str[
$i], $pos + 2, 1)) ^ 0x20);
2896 $res .= chr(((($c0 - $spaceCharOrd) & 077) << 2) | ((($c1 - $spaceCharOrd) & 077) >> 4)).
2897 chr(((($c1 - $spaceCharOrd) & 077) << 4) | ((($c2 - $spaceCharOrd) & 077) >> 2));
2903 if (($d + 1 <= $len) && ($pos + 2 <= mb_strlen(
$str[
$i])))
2905 $c0 = (ord(mb_substr(
$str[
$i], $pos, 1)) ^ 0x20);
2906 $c1 = (ord(mb_substr(
$str[
$i], $pos + 1, 1)) ^ 0x20);
2907 $res .= chr(((($c0 - $spaceCharOrd) & 077) << 2) | ((($c1 - $spaceCharOrd) & 077) >> 4));
2916 if(mb_substr(
$key, 0, 1) ==
"!")
2919 $cOperationType =
"N";
2924 $cOperationType =
"GE";
2929 $cOperationType =
"G";
2934 $cOperationType =
"LE";
2939 $cOperationType =
"L";
2944 $cOperationType =
"E";
2947 $cOperationType =
"?";
2949 return Array(
"FIELD"=>
$key,
"OPERATION"=>$cOperationType);
2952 public static function FilterCreate($fname, $vals,
$type, $cOperationType=
false, $bSkipEmpty =
true)
2957 public static function FilterCreateEx($fname, $vals,
$type, &$bFullJoin, $cOperationType=
false, $bSkipEmpty =
true)
2960 if(!is_array($vals))
2966 if(is_bool($cOperationType))
2968 if($cOperationType===
true)
2969 $cOperationType =
"N";
2971 $cOperationType =
"E";
2974 if($cOperationType==
"G")
2975 $strOperation =
">";
2976 elseif($cOperationType==
"GE")
2977 $strOperation =
">=";
2978 elseif($cOperationType==
"LE")
2979 $strOperation =
"<=";
2980 elseif($cOperationType==
"L")
2981 $strOperation =
"<";
2983 $strOperation =
"=";
2986 $bWasLeftJoin =
false;
2996 case "string_equal":
2998 $res[] = ($cOperationType==
"N"?
"NOT":
"").
"(".$fname.
" IS NULL OR ".
$DB->Length($fname).
"<=0)";
3000 $res[] = ($cOperationType==
"N"?
" ".$fname.
" IS NULL OR NOT ":
"").
"(".CIBlock::_Upper($fname).$strOperation.CIBlock::_Upper(
"'".
$DB->ForSql(
$val).
"'").
")";
3004 $res[] = ($cOperationType==
"N"?
"NOT":
"").
"(".$fname.
" IS NULL OR ".
$DB->Length($fname).
"<=0)";
3006 if($strOperation==
"=")
3007 $res[] = ($cOperationType==
"N"?
" ".$fname.
" IS NULL OR NOT ":
"").
"(".(
$DB->type ==
"ORACLE"?CIBlock::_Upper($fname).
" LIKE ".CIBlock::_Upper(
"'".
$DB->ForSqlLike(
$val).
"'").
" ESCAPE '\\'" : $fname.
" ".($strOperation==
"="?
"LIKE":$strOperation).
" '".
$DB->ForSqlLike(
$val).
"'").
")";
3009 $res[] = ($cOperationType==
"N"?
" ".$fname.
" IS NULL OR NOT ":
"").
"(".(
$DB->type ==
"ORACLE"?CIBlock::_Upper($fname).
" ".$strOperation.
" ".CIBlock::_Upper(
"'".
$DB->ForSql(
$val).
"'").
" " : $fname.
" ".$strOperation.
" '".
$DB->ForSql(
$val).
"'").
")";
3013 $res[] = ($cOperationType==
"N"?
"NOT":
"").
"(".$fname.
" IS NULL)";
3015 $res[] = ($cOperationType==
"N"?
" ".$fname.
" IS NULL OR NOT ":
"").
"(".$fname.
" ".$strOperation.
" ".
$DB->CharToDateFunction(
$DB->ForSql(
$val),
"FULL").
")";
3019 $res[] = ($cOperationType==
"N"?
"NOT":
"").
"(".$fname.
" IS NULL)";
3021 $res[] = ($cOperationType==
"N"?
" ".$fname.
" IS NULL OR NOT ":
"").
"(".$fname.
" ".$strOperation.
" '".DoubleVal(
$val).
"')";
3023 case "number_above":
3025 $res[] = ($cOperationType==
"N"?
"NOT":
"").
"(".$fname.
" IS NULL)";
3027 $res[] = ($cOperationType==
"N"?
" ".$fname.
" IS NULL OR NOT ":
"").
"(".$fname.
" ".$strOperation.
" '".
$DB->ForSql(
$val).
"')";
3032 if(
$val <> '' && $cOperationType!=
"N")
3035 $bWasLeftJoin =
true;
3043 $strResult .= ($cOperationType==
"N"?
" AND ":
" OR ");
3044 $strResult .=
"(".$res[
$i].
")";
3047 $strResult =
"(".$strResult.
")";
3049 if($bFullJoin && $bWasLeftJoin && $cOperationType!=
"N")
3060 if (isset(
$a[
$i]) && isset($b[
$i]))
3069 return(pack(
"H*",md5(
$val)));
3076 $key = COption::GetOptionString(
"main",
"pwdhashadd",
"");
3079 while (strlen(
$str) > 0)
3081 $m = substr(
$str, 0, 16);
3094 $key = COption::GetOptionString(
"main",
"pwdhashadd",
"");
3096 while (strlen(
$str) > 0)
3098 $m = substr(
$str, 0, 16);
3103 return(base64_encode(
$res));
3109 $arEMails = explode(
",",
$emails);
3110 foreach($arEMails as $mail)
3121 if(($pos = mb_strpos(
$email,
"<"))!==
false)
3123 if(($pos = mb_strpos(
$email,
">"))!==
false)
3125 return mb_strtolower(
$email);
3130 $use_tls = is_string($use_tls) ? $use_tls : ($use_tls ?
'Y' :
'N');
3132 $imap = new \Bitrix\Mail\Imap(
3134 $use_tls ==
'Y' || $use_tls ==
'S',
3140 if (($unseen = $imap->getUnseen(
'INBOX',
$error)) ===
false)
3162 " COUNT('x') as CNT "
3164 " MF.*, MB.NAME as MAILBOX_NAME, MB.ID as MAILBOX_ID, MB.SERVER_TYPE as MAILBOX_TYPE, MB.DOMAINS as DOMAINS, ".
3165 " ".$DB->DateToCharFunction(
"MF.TIMESTAMP_X").
" as TIMESTAMP_X "
3168 "FROM b_mail_mailbox MB ".(isset(
$arFilter[
"EMPTY"]) &&
$arFilter[
"EMPTY"] ===
"Y"?
"LEFT":
"INNER").
" JOIN b_mail_filter MF ON MB.ID=MF.MAILBOX_ID ";
3172 $arSqlSearch = Array();
3178 if (
$val ==
'')
continue;
3179 $key = mb_strtoupper($filter_keys[
$i]);
3183 case "PHP_CONDITION":
3193 case "PARENT_FILTER_ID":
3195 case "WHEN_MAIL_RECEIVED":
3196 case "WHEN_MANUALLY_RUN":
3197 case "ACTION_STOP_EXEC":
3198 case "ACTION_DELETE_MESSAGE":
3206 $is_filtered =
false;
3210 if($arSqlSearch[
$i] <>
'')
3212 $strSqlSearch .=
" AND (".$arSqlSearch[
$i].
") ";
3213 $is_filtered =
true;
3217 $arSqlOrder = Array();
3218 foreach($arOrder as $by=>
$order)
3222 $order =
"desc".($DB->type ==
"ORACLE"?
" NULLS LAST":
"");
3224 $order =
"asc".($DB->type ==
"ORACLE"?
" NULLS FIRST":
"");
3226 switch(mb_strtoupper($by))
3233 case "PARENT_FILTER_ID":
3234 case "WHEN_MAIL_RECEIVED":
3235 case "WHEN_MANUALLY_RUN":
3236 case "ACTION_STOP_EXEC":
3237 case "ACTION_DELETE_MESSAGE":
3239 $arSqlOrder[] =
" MF.".$by.
" ".
$order.
" ";
3241 case "MAILBOX_NAME":
3242 $arSqlOrder[] =
" MB.NAME ".$order.
" ";
3243 $arSqlOrder[] =
" MF.ID ".$order.
" ";
3246 $arSqlOrder[] =
" MF.ID ".$order.
" ";
3251 $arSqlOrder = array_unique($arSqlOrder);
3257 $strSqlOrder =
" ORDER BY ";
3259 $strSqlOrder .=
",";
3261 $strSqlOrder .= $arSqlOrder[
$i];
3264 $strSql .=
" WHERE 1=1 ".$strSqlSearch.$strSqlOrder;
3267 $res->is_filtered = $is_filtered;
3281 global $php_errormsg;
3282 ini_set(
"track_errors",
"on");
3283 $php_errormsg_prev = $php_errormsg;
3288 if($php_errormsg !=
"")
3290 $php_errormsg = $php_errormsg_prev;
3291 ini_set(
"track_errors", $prev);
3308 foreach (
$fields[
'CONDITIONS'] as $item)
3310 foreach ($item as
$key => $value)
3312 if(!in_array(
$key, $whiteList))
3349 $r = CMailBox::GetByID(
$arFields[
"MAILBOX_ID"]);
3353 $arMsg[] =
array(
"id"=>
"MAILBOX_ID",
"text"=>
GetMessage(
"MAIL_CL_ERR_WRONG_MAILBOX"));
3359 $arMsg[] =
array(
"id"=>
"MAILBOX_ID",
"text"=>
GetMessage(
"MAIL_CL_ERR_MAILBOX_NA"));
3365 $GLOBALS[
"APPLICATION"]->ThrowException($e);
3392 $arFields[
"ACTION_DELETE_MESSAGE"] =
"N";
3400 $ID =
$DB->Add(
"b_mail_filter",
$arFields, Array(
"PHP_CONDITION",
"ACTION_PHP"));
3432 $arFields[
"ACTION_DELETE_MESSAGE"] =
"N";
3439 $arUpdateBinds =
array();
3440 $strUpdate =
$DB->PrepareUpdateBind(
"b_mail_filter",
$arFields,
"",
false, $arUpdateBinds);
3443 "UPDATE b_mail_filter SET ".
3448 foreach($arUpdateBinds as $field_id)
3449 $arBinds[$field_id] =
$arFields[$field_id];
3451 $DB->QueryBind($strSql, $arBinds);
3466 while($r = $dbr->Fetch())
3472 $strSql =
"DELETE FROM b_mail_filter WHERE ID=".$ID;
3474 return $DB->Query($strSql,
true);
3480 $PARENT_FILTER_ID = intval($PARENT_FILTER_ID);
3481 $MAILBOX_ID = intval(
$arFields[
"MAILBOX_ID"]);
3484 $cache_param = $MAILBOX_ID.
"|".$PARENT_FILTER_ID.
"|".
$event.
"|".$FILTER_ID;
3495 $strSqlAdd .=
" AND (WHEN_MAIL_RECEIVED='Y')";
3497 $strSqlAdd .=
" AND (WHEN_MANUALLY_RUN='Y' ".(intval($FILTER_ID)>0?
" AND f.ID='".intval($FILTER_ID).
"'":
"").
")";
3500 "SELECT f.*, c.*, f.ID, c.ID as CONDITION_ID
3501 FROM b_mail_filter f LEFT JOIN b_mail_filter_cond c ON f.ID = c.FILTER_ID
3502 WHERE (f.MAILBOX_ID = ".$MAILBOX_ID.
" OR MAILBOX_ID IS NULL)
3504 AND (f.PARENT_FILTER_ID = " . ($PARENT_FILTER_ID > 0 ? $PARENT_FILTER_ID :
"0 OR f.PARENT_FILTER_ID IS NULL") .
")" .
3506 ORDER BY f.SORT, f.ID";
3508 $dbr =
$DB->Query($strSql);
3511 $arFilterCond = Array();
3515 while(
$arr = $dbr->Fetch())
3518 if(
$arr[
"CONDITION_ID"]>0)
3520 if(!is_array($arFilterCond[
$arr[
"ID"]]))
3521 $arFilterCond[
$arr[
"ID"]] = Array();
3522 $arFilterCond[
$arr[
"ID"]][] =
$arr;
3530 foreach(
$arFilter as $filter_id=>$arFilterParams)
3533 $arFields[
"MAIL_FILTER"] = $arFilterParams;
3535 $arAllConditions = isset($arFilterCond[$filter_id]) ? $arFilterCond[$filter_id] : [];
3537 if(!is_array($arAllConditions))
3538 $arAllConditions = Array();
3539 foreach($arAllConditions as
$k => $arCondition)
3542 $type = $arCondition[
"TYPE"];
3545 case "ALL":
case "RECIPIENT":
case "SENDER":
3552 case "HEADER":
case "FIELD_FROM":
case "FIELD_REPLY_TO":
case "FIELD_TO":
case "FIELD_CC":
case "SUBJECT":
case "BODY":
3553 $arStrings = explode(
"\n", $arCondition[
"STRINGS"]);
3554 if($arCondition[
"COMPARE_TYPE"]==
"NOT_EQUAL" || $arCondition[
"COMPARE_TYPE"]==
"NOT_CONTAIN")
3559 $str = mb_strtoupper(Trim($arStrings[
$i],
"\r"));
3560 switch($arCondition[
"COMPARE_TYPE"])
3580 $str = mb_strtoupper(Trim($arStrings[
$i],
"\r"));
3581 switch($arCondition[
"COMPARE_TYPE"])
3605 $arStrings = explode(
"\n", $arCondition[
"STRINGS"]);
3606 if($arCondition[
"COMPARE_TYPE"]==
"NOT_EQUAL" || $arCondition[
"COMPARE_TYPE"]==
"NOT_CONTAIN")
3609 while($arr_att = $db_att->Fetch())
3613 $str = mb_strtoupper(Trim($arStrings[
$i],
"\r"));
3614 switch($arCondition[
"COMPARE_TYPE"])
3617 if(
$str <> '' && mb_strpos(mb_strtoupper($arr_att[
"FILE_NAME"]),
$str) !==
false)
3621 if(
$str == mb_strtoupper($arr_att[
"FILE_NAME"]))
3632 while($arr_att = $db_att->Fetch())
3636 $str = mb_strtoupper(Trim($arStrings[
$i],
"\r"));
3637 switch($arCondition[
"COMPARE_TYPE"])
3640 if(
$str <> '' && mb_strpos(mb_strtoupper($arr_att[
"FILE_NAME"]),
$str) !==
false)
3644 if(
$str == mb_strtoupper($arr_att[
"FILE_NAME"]))
3648 if(preg_match(
"'".str_replace(
"'",
"\'",
$str).
"'i", $arr_att[
"FILE_NAME"]))
3667 if($arFilterParams[
"SPAM_RATING"]>0)
3670 if($arFilterParams[
"SPAM_RATING_TYPE"]==
">" &&
$arFields[
"SPAM_RATING"]<=$arFilterParams[
"SPAM_RATING"])
3672 if($arFilterParams[
"SPAM_RATING_TYPE"]!=
">" &&
$arFields[
"SPAM_RATING"]>=$arFilterParams[
"SPAM_RATING"])
3676 if($arFilterParams[
"MESSAGE_SIZE"]>0)
3678 $MESSAGE_SIZE =
$arFields[
"MESSAGE_SIZE"];
3679 if($arFilterParams[
"MESSAGE_SIZE_UNIT"]==
"k")
3680 $MESSAGE_SIZE = intval($MESSAGE_SIZE/1024);
3681 elseif($arFilterParams[
"MESSAGE_SIZE_UNIT"]==
"m")
3682 $MESSAGE_SIZE = intval($MESSAGE_SIZE/1024/1024);
3684 if($arFilterParams[
"MESSAGE_SIZE_TYPE"]==
">" && $MESSAGE_SIZE<=$arFilterParams[
"MESSAGE_SIZE"])
3686 if($arFilterParams[
"MESSAGE_SIZE_TYPE"]!=
">" && $MESSAGE_SIZE>=$arFilterParams[
"MESSAGE_SIZE"])
3690 if($arFilterParams[
"PHP_CONDITION"] <>
'')
3694 $arModFilter =
false;
3695 if($arFilterParams[
"ACTION_TYPE"]!=
"")
3698 if($arModFilter =
$res->Fetch())
3701 (is_array($arModFilter[
"CONDITION_FUNC"]) &&
count($arModFilter[
"CONDITION_FUNC"]) > 0) ||
3702 $arModFilter[
"CONDITION_FUNC"] <>
''
3704 if(!call_user_func_array($arModFilter[
"CONDITION_FUNC"], Array(&
$arFields, &$arFilterParams[
"ACTION_VARS"])))
3710 "MAILBOX_ID"=>$MAILBOX_ID,
3711 "MESSAGE_ID"=>$MESSAGE_ID,
3712 "FILTER_ID"=>$filter_id,
3714 "LOG_TYPE"=>
"FILTER_OK",
3721 (is_array($arModFilter[
"ACTION_FUNC"]) &&
count($arModFilter[
"ACTION_FUNC"]) > 0) ||
3722 $arModFilter[
"ACTION_FUNC"] <>
''
3724 call_user_func_array($arModFilter[
"ACTION_FUNC"],
array(&
$arFields, &$arFilterParams[
"ACTION_VARS"]));
3727 if(Trim($arFilterParams[
"ACTION_PHP"]) <>
'')
3732 "MAILBOX_ID"=>$MAILBOX_ID,
3733 "MESSAGE_ID"=>$MESSAGE_ID,
3734 "FILTER_ID"=>$filter_id,
3735 "LOG_TYPE"=>
"DO_PHP",
3741 if($arFilterParams[
"ACTION_SPAM"]==
"Y" &&
$arFields[
"SPAM"]!=
"Y")
3749 "MAILBOX_ID"=>$MAILBOX_ID,
3750 "MESSAGE_ID"=>$MESSAGE_ID,
3751 "FILTER_ID"=>$filter_id,
3766 "MAILBOX_ID"=>$MAILBOX_ID,
3767 "MESSAGE_ID"=>$MESSAGE_ID,
3768 "FILTER_ID"=>$filter_id,
3769 "LOG_TYPE"=>
"NOTSPAM",
3776 if($arFilterParams[
"ACTION_READ"]==
"Y" &&
$arFields[
"NEW_MESSAGE"]==
"Y")
3781 elseif($arFilterParams[
"ACTION_READ"]==
"N" &&
$arFields[
"NEW_MESSAGE"]!=
"Y")
3787 if($arFilterParams[
"ACTION_DELETE_MESSAGE"]==
"Y")
3791 "MAILBOX_ID"=>$MAILBOX_ID,
3792 "MESSAGE_ID"=>$MESSAGE_ID,
3793 "FILTER_ID"=>$filter_id,
3795 "LOG_TYPE"=>
"MESSAGE_DELETED",
3802 if($arFilterParams[
"ACTION_STOP_EXEC"]==
"Y")
3806 "MAILBOX_ID"=>$MAILBOX_ID,
3807 "MESSAGE_ID"=>$MESSAGE_ID,
3808 "FILTER_ID"=>$filter_id,
3810 "LOG_TYPE"=>
"FILTER_STOP",
3834 $res =
$DB->Query(
"SELECT ID, HEADER, BODY_HTML, BODY FROM b_mail_message WHERE SPAM_LAST_RESULT<>'N'");
3837 $forSpamTest = sprintf(
'%s %s',
$arr[
'HEADER'],
$arr[
'BODY_HTML'] ?:
$arr[
'BODY']);
3839 $DB->Query(
"UPDATE b_mail_message SET SPAM_RATING=".Round($arSpam[
"RATING"], 4).
", SPAM_LAST_RESULT='Y', SPAM_WORDS='".
$DB->ForSql($arSpam[
"WORDS"], 255).
"' WHERE ID=".
$arr[
"ID"]);
3849 if (empty($arWords))
3853 $arWords = array_map(
"md5", $arWords);
3858 $strSql =
"SELECT MAX(GOOD_CNT) as G, MAX(BAD_CNT) as B FROM b_mail_spam_weight";
3859 if(
$res =
$DB->Query($strSql))
3869 $CNT_WORDS = COption::GetOptionInt(
"mail",
"spam_word_count",
B_MAIL_WORD_CNT);
3870 $MIN_COUNT = COption::GetOptionInt(
"mail",
"spam_min_count",
B_MAIL_MIN_CNT);
3877 "FROM b_mail_spam_weight SW ".
3878 "WHERE WORD_ID IN ('".implode(
"', '", $arWords).
"') ".
3880 " AND TOTAL_CNT>".$MIN_COUNT.
" ".
3881 "ORDER BY MOD_RATING DESC ".
3882 (
$DB->type ==
"MYSQL"?
"LIMIT ".$CNT_WORDS :
"");
3888 $dbr =
$DB->Query($strSql);
3892 for(
$i=0;
$i<$CNT_WORDS;
$i++)
3897 $words .=
$arr[
"WORD_REAL"].
" ".Round(
$arr[
"RATING"]*100, 4).
" ".
$arr[
"BAD_CNT"].
" ".
$arr[
"GOOD_CNT"].
"\n";
3898 $a =
$a * (
$arr[
"RATING"]==0?0.00001:$arr[
"RATING"]);
3899 $b = $b * (1 - (
$arr[
"RATING"]==1?0.9999:$arr[
"RATING"]));
3905 $b = $b * (1 - 0.4);
3909 $rating =
$a/(
$a+$b) * 100;
3911 return Array(
"RATING"=>$rating,
"WORDS"=>$words);
3920 for(
$i = ord(
"\x01");
$i < ord(
"\x23");
$i++)
3922 for(
$i = ord(
"\x25");
$i < ord(
"\x3F");
$i++)
3924 for(
$i = ord(
"\x5B");
$i < ord(
"\x5E");
$i++)
3930 while($word !==
false)
3932 $arWords[$word] = $word;
3933 if (
count($arWords) >= $max_words)
3935 $word = strtok($tok);
3962 $strSql =
"SELECT MAX(GOOD_CNT) as G, MAX(BAD_CNT) as B FROM b_mail_spam_weight";
3963 if(
$res =
$DB->Query($strSql))
3973 if($bDelete && $bIsSPAM)
3975 elseif($bDelete && !$bIsSPAM)
3977 elseif(!$bDelete && $bIsSPAM)
3979 elseif(!$bDelete && !$bIsSPAM)
3982 @set_time_limit(30);
3989 foreach($arWords as $word)
3991 $word_md5 = md5($word);
3995 "INSERT INTO b_mail_spam_weight(WORD_ID, WORD_REAL, GOOD_CNT, BAD_CNT, TOTAL_CNT) ".
3996 "VALUES('".$word_md5.
"', '".
$DB->ForSql($word, 40).
"', ".($bIsSPAM?0:1).
", ".($bIsSPAM?1:0).
", 1)";
3998 if($bDelete || (!
$DB->Query($strSql,
true)))
4003 "UPDATE b_mail_spam_weight SET ".
4004 " GOOD_CNT = GOOD_CNT - ".($bIsSPAM?0:1).
", ".
4005 " BAD_CNT = BAD_CNT - ".($bIsSPAM?1:0).
", ".
4006 " TOTAL_CNT = TOTAL_CNT - 1 ".
4007 "WHERE WORD_ID = '".$word_md5.
"' ".
4008 " AND ".($bIsSPAM?
"BAD_CNT>0":
"GOOD_CNT>0");
4013 "UPDATE b_mail_spam_weight SET ".
4014 " GOOD_CNT = GOOD_CNT + ".($bIsSPAM?0:1).
", ".
4015 " BAD_CNT = BAD_CNT + ".($bIsSPAM?1:0).
", ".
4016 " TOTAL_CNT = TOTAL_CNT + 1 ".
4017 "WHERE WORD_ID='".$word_md5.
"'";
4020 $DB->Query($strSql);
4025 if(COption::GetOptionString(
"mail",
"reset_all_spam_result",
"N") ==
"Y")
4026 $DB->Query(
"UPDATE b_mail_message SET SPAM_LAST_RESULT='N'");
4032 static $BX_MAIL_CUST_FILTER_LIST =
false;
4033 if($BX_MAIL_CUST_FILTER_LIST ===
false)
4035 $BX_MAIL_CUST_FILTER_LIST =
array();
4040 $BX_MAIL_CUST_FILTER_LIST[] =
$arResult;
4046 $allResultsTemp =
array();
4047 foreach($BX_MAIL_CUST_FILTER_LIST as
$arResult)
4058 $allResultsTemp = $BX_MAIL_CUST_FILTER_LIST;
4062 $db_res->InitFromArray($allResultsTemp);
4074 "FROM b_mail_filter_cond MFC ";
4078 $arSqlSearch = Array();
4083 if (
$val ==
'')
continue;
4084 $key = mb_strtoupper($filter_keys[
$i]);
4089 case "COMPARE_TYPE":
4102 if($arSqlSearch[
$i] <>
'')
4103 $strSqlSearch .=
" AND (".$arSqlSearch[
$i].
") ";
4106 $arSqlOrder = Array();
4107 foreach($arOrder as $by=>
$order)
4111 $order =
"desc".($DB->type ==
"ORACLE"?
" NULLS LAST":
"");
4113 $order =
"asc".($DB->type ==
"ORACLE"?
" NULLS FIRST":
"");
4115 switch(mb_strtoupper($by))
4120 case "COMPARE_TYPE":
4121 $arSqlOrder[] =
" MFC.".$by.
" ".
$order.
" ";
4124 $arSqlOrder[] =
" MFC.ID ".$order.
" ";
4129 $arSqlOrder = array_unique($arSqlOrder);
4135 $strSqlOrder =
" ORDER BY ";
4137 $strSqlOrder .=
",";
4139 $strSqlOrder .= $arSqlOrder[
$i];
4142 $strSql .=
" WHERE 1=1 ".$strSqlSearch.$strSqlOrder;
4145 $res->is_filtered = (
count($arSqlOrder)>0);
4159 $strSql =
"DELETE FROM b_mail_filter_cond WHERE ID=".$ID;
4160 return $DB->Query($strSql,
true);
4163 public static function SetConditions($FILTER_ID, $CONDITIONS, $bClearOther =
true)
4167 $FILTER_ID = intval($FILTER_ID);
4171 "FROM b_mail_filter_cond ".
4172 "WHERE FILTER_ID=".$FILTER_ID;
4174 $dbr =
$DB->Query($strSql);
4176 while($dbr_arr = $dbr->Fetch())
4178 if(
is_set($CONDITIONS, $dbr_arr[
"ID"]) && is_array($CONDITIONS[$dbr_arr[
"ID"]]) && $CONDITIONS[$dbr_arr[
"ID"]][
"STRINGS"] <>
'')
4180 $arFields = $CONDITIONS[$dbr_arr[
"ID"]];
4184 unset($CONDITIONS[$dbr_arr[
"ID"]]);
4188 $DB->Query(
"DELETE FROM b_mail_filter_cond WHERE ID=".$dbr_arr[
"ID"]);
4234 $strUpdate =
$DB->PrepareUpdate(
"b_mail_filter_cond",
$arFields);
4237 "UPDATE b_mail_filter_cond SET ".
4241 $DB->Query($strSql);
4254 if (COption::getOptionString(
'mail',
'disable_log',
'N') ==
'Y')
4258 if(array_key_exists(
'MESSAGE',
$arFields))
4270 $strSql =
"DELETE FROM b_mail_log WHERE ID=".$ID;
4271 return $DB->Query($strSql,
true);
4278 "SELECT ML.*, MB.NAME as MAILBOX_NAME, ".
4279 " MF.NAME as FILTER_NAME, ".
4280 " MM.SUBJECT as MESSAGE_SUBJECT, ".
4281 " ".$DB->DateToCharFunction(
"ML.DATE_INSERT").
" as DATE_INSERT ".
4283 "FROM b_mail_log ML ".
4284 " INNER JOIN b_mail_mailbox MB ON MB.ID=ML.MAILBOX_ID ".
4285 " LEFT JOIN b_mail_filter MF ON MF.ID=ML.FILTER_ID ".
4286 " LEFT JOIN b_mail_message MM ON MM.ID=ML.MESSAGE_ID ";
4290 $arSqlSearch = Array();
4295 if (
$val ==
'')
continue;
4296 $key = mb_strtoupper($filter_keys[
$i]);
4313 case "MAILBOX_NAME":
4316 case "MESSAGE_SUBJECT":
4322 $is_filtered =
false;
4326 if($arSqlSearch[
$i] <>
'')
4328 $strSqlSearch .=
" AND (".$arSqlSearch[
$i].
") ";
4329 $is_filtered =
true;
4333 $arSqlOrder = Array();
4334 foreach($arOrder as $by=>
$order)
4338 $order =
"desc".($DB->type ==
"ORACLE"?
" NULLS LAST":
"");
4340 $order =
"asc".($DB->type ==
"ORACLE"?
" NULLS FIRST":
"");
4342 switch(mb_strtoupper($by))
4352 $arSqlOrder[] =
" ML.".$by.
" ".
$order.
" ";
4353 case "MESSAGE_SUBJECT":
4354 $arSqlOrder[] =
" MM.SUBJECT ".$order.
" ";
4356 $arSqlOrder[] =
" MF.NAME ".$order.
" ";
4357 case "MAILBOX_NAME":
4358 $arSqlOrder[] =
" MB.NAME ".$order.
" ";
4360 $arSqlOrder[] =
" ML.ID ".$order.
" ";
4365 $arSqlOrder = array_unique($arSqlOrder);
4371 $strSqlOrder =
" ORDER BY ";
4373 $strSqlOrder .=
",";
4375 $strSqlOrder .= $arSqlOrder[
$i];
4378 $strSql .=
" WHERE 1=1 ".$strSqlSearch.$strSqlOrder;
4382 $res->is_filtered = $is_filtered;
4388 switch($arr_log[
"LOG_TYPE"])
4391 $arr_log[
"MESSAGE_TEXT"] =
GetMessage(
"MAIL_CL_RULE_RUN").
" \"[".$arr_log[
"FILTER_ID"].
"] ".mb_substr($arr_log[
"FILTER_NAME"], 0, 30).(mb_strlen($arr_log[
"FILTER_NAME"]) > 30?
"...":
"").
"\" ";
4392 if($arr_log[
"MESSAGE"]==
"R")
4393 $arr_log[
"MESSAGE_TEXT"] .=
GetMessage(
"MAIL_CL_WHEN_CONNECT");
4395 $arr_log[
"MESSAGE_TEXT"] .=
GetMessage(
"MAIL_CL_WHEN_MANUAL");
4398 $arr_log[
"MESSAGE_TEXT"] =
GetMessage(
"MAIL_CL_NEW_MESSAGE").
" ".$arr_log[
"MESSAGE"];
4401 if($arr_log[
"FILTER_ID"]>0)
4402 $arr_log[
"MESSAGE_TEXT"] =
" ".GetMessage(
"MAIL_CL_RULE_ACT_SPAM");
4404 $arr_log[
"MESSAGE_TEXT"] =
GetMessage(
"MAIL_CL_ACT_SPAM");
4407 if($arr_log[
"FILTER_ID"]>0)
4408 $arr_log[
"MESSAGE_TEXT"] =
" ".GetMessage(
"MAIL_CL_RULE_ACT_NOTSPAM");
4410 $arr_log[
"MESSAGE_TEXT"] =
GetMessage(
"MAIL_CL_ACT_NOTSPAM");
4413 $arr_log[
"MESSAGE_TEXT"] =
" ".GetMessage(
"MAIL_CL_RULE_ACT_PHP");
4415 case "MESSAGE_DELETED":
4416 $arr_log[
"MESSAGE_TEXT"] =
" ".GetMessage(
"MAIL_CL_RULE_ACT_DEL");
4419 $arr_log[
"MESSAGE_TEXT"] =
" ".GetMessage(
"MAIL_CL_RULE_ACT_CANC");
4422 $arr_log[
"MESSAGE_TEXT"] = $arr_log[
"MESSAGE"];
4432 parent::__construct(
$res);
4437 if($arr_log = parent::Fetch())
if(! $messageFields||!isset($messageFields['message_id'])||!isset($messageFields['status'])||!CModule::IncludeModule("messageservice")) $messageId
static registerAttachment(array $attachment)
static unregisterAttachment($fileId)
static parseMessage(array &$message)
static getConnection($name="")
static get($moduleId, $name, $default="", $siteId=false)
static getFileContents($path)
static includeModule($moduleName)
GetMessage($mailbox_id, $msgnum, $msguid, $session_id)
GetResponse($bMultiline=false, $bSkipFirst=true)
static GetList($arOrder=[], $arFilter=[])
Check($server, $port, $use_tls, $login, $passw)
static CheckFields($arFields, $ID=false)
static Update($ID, $arFields)
static CheckMailAgent($ID)
CheckMail($mailbox_id=false)
static decodeMessageBody($header, $body, $charset)
static parseHeader($header, $charset)
static MarkAsSpam($ID, $bIsSPAM=true, $arRow=false)
static isLongMessageBody(?string &$messageBody)
static GetSpamRating($msgid, $arRow=false)
static addAttachment($arFields)
static getTextHtmlBlock(string &$body)
static GetList($arOrder=Array(), $arFilter=Array(), $bCnt=false)
static Add($arFields, $mailboxID=false)
const MAX_LENGTH_MESSAGE_BODY
static Update($ID, $arFields, $mailboxID=false)
static prepareLongMessage(&$messageBody, &$messageBodyHtml)
static addMessage($mailboxId, $message, $charset, $params=array())
static parseMessage($message, $charset)
static getBodyMaxLength()
static getPartBody(&$part)
static saveMessage(int $mailboxId, &$message, &$header, &$bodyHtml, &$bodyText, &$attachments, $params=array())
static extractAllMailAddresses($emails)
static Decrypt($str, $key=false)
static ByteXOR($a, $b, $l)
static checkImapMailbox($server, $port, $use_tls, $login, $password, &$error)
static ExtractMailAddress($email)
static MkOperationFilter($key)
static convertCharset($str, $from, $to)
static FilterCreateEx($fname, $vals, $type, &$bFullJoin, $cOperationType=false, $bSkipEmpty=true)
static FilterCreate($fname, $vals, $type, $cOperationType=false, $bSkipEmpty=true)
static Crypt($str, $key=false)
static getContents($attachment)
static GetList($arOrder=Array(), $arFilter=Array())
static GetLastError($type=false)
static GetErrorsText($delim="<br>")
static SetError($ID, $TITLE="", $DESC="")
static SetConditions($FILTER_ID, $CONDITIONS, $bClearOther=true)
static GetList($arOrder=Array(), $arFilter=Array())
static Update($ID, $arFields)
static Filter($arFields, $event, $FILTER_ID=false, $PARENT_FILTER_ID=false)
static FilterMessage($message_id, $event, $FILTER_ID=false)
static DoPHPAction($id, $action, &$arMessageFields)
static CheckFields($arFields, $ID=false)
static getWords($message, $max_words)
static GetSpamRating($message)
static GetList($arOrder=Array(), $arFilter=Array(), $bCnt=false)
static RecalcSpamRating()
static GetFilterList($id="")
static CheckPHP($code, $field_name)
static DeleteFromSpamBase($message, $bIsSPAM=true)
static CheckConditionTypes($fields)
static Update($ID, $arFields)
static MarkAsSpam($message, $bIsSPAM=true)
static SpamAction($message, $bIsSPAM, $bDelete=false)
static getErrorMessage($code)
const ERR_API_BAD_PASSWORD
const ERR_API_LONG_PASSWORD
const ERR_API_PROHIBITED_DOMAIN
const ERR_API_EMPTY_PASSWORD
const ERR_ENTRY_NOT_FOUND
const ERR_API_EMPTY_DOMAIN
static onUserUpdate($arFields)
static option($name, $value=null)
const ERR_API_DOMAINLIST_EMPTY
const ERR_API_DOMAIN_OCCUPIED
const ERR_API_USER_NOTFOUND
const ERR_API_PASSWORD_LIKELOGIN
const ERR_API_NAME_OCCUPIED
const ERR_API_SHORT_PASSWORD
static AddMessage($arFields)
static ConvertRow($arr_log)
static GetList($arOrder=Array(), $arFilter=Array())
static IsSizeAllowed($size)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
global $BX_MAIL_FILTER_CACHE
global $B_MAIL_MAX_ALLOWED
const B_MAIL_SAVE_ATTACHMENTS
ExecuteModuleEventEx($arEvent, $arParams=[])
AddMessage2Log($text, $module='', $traceDepth=6, $showArgs=false)
htmlspecialcharsback($str)
DelDuplicateSort(&$arSort)
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
GetMessage($name, $aReplace=null)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
$GLOBALS['_____370096793']