use Bitrix\Im\Integration\Imopenlines;
use Bitrix\Im\Message;
IncludeModuleLangFile(__FILE__);
class CIMMessenger
{
private $user_id = 0;
private static $enableMessageCheck = 1;
const MESSAGE_LIMIT = 20000;
function __construct($user_id = false)
{
global $USER;
$this->user_id = intval($user_id);
if ($this->user_id == 0)
$this->user_id = intval($USER->GetID());
}
/**
* Sends instant message.
*
* @param array $arFields
*
* [
* (string) MESSAGE_TYPE - Message type:
* use const IM_MESSAGE_SYSTEM = S - notification,
* use const IM_MESSAGE_PRIVATE = P - private chat,
* use const IM_MESSAGE_CHAT = S - group chat,
* use const IM_MESSAGE_OPEN = O - open chat,
* use const IM_MESSAGE_OPEN_LINE = L - open line chat.
*
* (string|int) DIALOG_ID - Dialog Id:
* chatNNN - chat,
* sgNNN - sonet group,
* crmNNN - crm chat,
* NNN - recipient user.
*
* (string) MESSAGE_DATE - Setup the message creation date. String representation of datetime.
* (int) TO_CHAT_ID - Chat Id.
* (int) TO_USER_ID - Recipient user Id.
* (int) FROM_USER_ID - Sender user Id.
* (int) AUTHOR_ID - Created by Id.
* (string) MESSAGE - Message to send.
* (string) MESSAGE_OUT - Formated rich message.
* (Y|N) SYSTEM - Display message as a system notification.
*
* (array | \CIMMessageParamAttach) ATTACH - Message attachment.
* (array) FILES - Message file attachments.
* (\Bitrix\Im\Bot\Keyboard) KEYBOARD - Message keyboard.
* (\Bitrix\Im\Bot\ContextMenu) MENU - Message context menu.
* (array) PARAMS - Message additional parameters.
*
* (int) NOTIFY_TYPE - Notification type:
* use const IM_NOTIFY_CONFIRM = 1 - confirm,
* use const IM_NOTIFY_FROM = 2 - notify single from,
* use const IM_NOTIFY_SYSTEM = 4 - notify single.
* (string) NOTIFY_MODULE - Source module id (ex: xmpp, main, etc).
* (string) NOTIFY_EVENT - Source module event id for search (ex: IM_GROUP_INVITE).
* (string) NOTIFY_TITLE - Notify title for sending email.
* (string) TITLE - Alias for NOTIFY_TITLE parameter.
* (array) NOTIFY_BUTTONS - Array of buttons - available with NOTIFY_TYPE = 1
* Array(
* Array('TITLE' => 'OK', 'VALUE' => 'Y', 'TYPE' => 'accept', 'URL' => '/test.php?CONFIRM=Y'),
* Array('TITLE' => 'Cancel', 'VALUE' => 'N', 'TYPE' => 'cancel', 'URL' => '/test.php?CONFIRM=N'),
* )
* (string) NOTIFY_TAG - Field for group in JS notification and search in table.
* (string) NOTIFY_SUB_TAG - Second TAG for search in table.
* (Y|N) NOTIFY_ANSWER - Allow answering right in notification balloon.
* (string) EMAIL_TEMPLATE - E-mail template code.
* (string) NOTIFY_EMAIL_TEMPLATE - Alias to EMAIL_TEMPLATE parameter.
* (string) NOTIFY_LINK - Url to dislplay in notification balloon.
* (string) NOTIFY_MESSAGE - Alias for MESSAGE parameter.
* (string) NOTIFY_MESSAGE_OUT - Alias for MESSAGE_OUT parameter.
* (string) NOTIFY_ONLY_FLASH - Display only balloon without adding message into notification list.
*
* (Y|N) PUSH - Allows sending pull.
* (string) MESSAGE_PUSH - Private or chat push message.
* (string) PUSH_MESSAGE - Notification push message.
* (array) PUSH_PARAMS - Notification push params.
* (string) PUSH_IMPORTANT - Send push immediately.
* (string) TEMPLATE_ID - UUID of the message, which generates on the frontend.
* (string) FILE_TEMPLATE_ID
* (array) EXTRA_PARAMS
*
* (bool) RECENT_SKIP_AUTHOR - Do not add author in recent list in case of self message chat.
* (Y|N) RECENT_ADD - N = Skip refresh of the recent list for chat relations. Do not flow up recent on hidden notification.
*
* (int) IMPORT_ID - The ID of the message to be imported.
* (Y|N) CONVERT - Suppress events firing and pull sending on import operations.
*
* (Y|N) URL_PREVIEW - Generate URL preview attachment and insert date PUT/SEND command: Y|N.
* (Y|N) SKIP_URL_INDEX - Skip Link\Url processing @see \Bitrix\Im\V2\Link\Url\UrlService::saveUrlsFromMessage
*
* (Y|N) SKIP_COMMAND - Skip command execution @see \Bitrix\Im\Command::onCommandAdd
*
* (Y|N) SILENT_CONNECTOR - Keep silent. Do not send message into OL connector to client side. @see \Bitrix\ImOpenLines\Connector::onMessageSend
* (Y|N) SKIP_CONNECTOR - Do not send message into OL connector to client side. @see \Bitrix\ImOpenLines\Connector::onMessageSend
* (Y|N) IMPORTANT_CONNECTOR - Forward message into OL channel either mark as system. @see \Bitrix\ImOpenLines\Connector::onMessageSend
* (Y|N) NO_SESSION_OL - Do not touch OL session @see \Bitrix\ImOpenLines\Connector::onMessageSend
*
* (Y|N) SKIP_USER_CHECK - Skip chat relations check. Check if user has permission to write into open chat, open line or announce channel. Default - N
* ]
*
*
* @return int|false
*/
public static function Add($arFields)
{
global $DB;
$templateId = $arFields['TEMPLATE_ID'] ?? '';
if (
$arFields['MESSAGE_TYPE'] !== IM_MESSAGE_SYSTEM
&& Message\Uuid::validate($templateId)
)
{
$messageUuid = new Message\Uuid($templateId);
$uuidAddResult = $messageUuid->add();
// if it is false, then UUID already exists
if (!$uuidAddResult)
{
$messageIdByUuid = $messageUuid->getMessageId();
// if we got message_id, then message already exists, and we don't need to add it, so return with ID.
if (!is_null($messageIdByUuid))
{
return $messageIdByUuid;
}
// if there is no message_id and entry date is expired,
// then update date_create and return false to delay next sending on the client.
if (!$messageUuid->updateIfExpired())
{
return false;
}
}
}
if (isset($arFields['DIALOG_ID']) && !empty($arFields['DIALOG_ID']))
{
if (\Bitrix\Im\Common::isChatId($arFields['DIALOG_ID']))
{
$arFields['TO_CHAT_ID'] = \Bitrix\Im\Dialog::getChatId($arFields['DIALOG_ID']);
if (!isset($arFields['MESSAGE_TYPE']))
{
$arFields['MESSAGE_TYPE'] = IM_MESSAGE_CHAT;
}
}
else
{
$arFields['TO_USER_ID'] = intval($arFields['DIALOG_ID']);
$arFields['MESSAGE_TYPE'] = IM_MESSAGE_PRIVATE;
}
}
if (isset($arFields['TITLE']) && !isset($arFields['NOTIFY_TITLE']))
$arFields['NOTIFY_TITLE'] = mb_substr($arFields['TITLE'], 0, 255);
if (isset($arFields['NOTIFY_MESSAGE']) && !isset($arFields['MESSAGE']))
$arFields['MESSAGE'] = $arFields['NOTIFY_MESSAGE'];
if (isset($arFields['NOTIFY_MESSAGE_OUT']) && !isset($arFields['MESSAGE_OUT']))
$arFields['MESSAGE_OUT'] = $arFields['NOTIFY_MESSAGE_OUT'];
if (isset($arFields['MESSAGE']))
{
$arFields['MESSAGE'] = trim(str_replace(Array('[BR]', '[br]', '#BR#'), "\n", $arFields['MESSAGE']));
if (mb_strlen($arFields['MESSAGE']) > self::MESSAGE_LIMIT + 6)
{
$arFields['MESSAGE'] = mb_substr($arFields['MESSAGE'], 0, self::MESSAGE_LIMIT).' (...)';
}
}
if (
isset($arFields['FROM_USER_ID'])
&& (int)$arFields['FROM_USER_ID'] > 0
&& \Bitrix\Im\User::getInstance($arFields['FROM_USER_ID'])->isExtranet())
{
$arFields['SYSTEM'] = 'N';
}
$arFields['MESSAGE_OUT'] = isset($arFields['MESSAGE_OUT'])? trim($arFields['MESSAGE_OUT']): "";
$arFields['URL_PREVIEW'] = isset($arFields['URL_PREVIEW']) && $arFields['URL_PREVIEW'] == 'N'? 'N': 'Y';
$arFields['SKIP_URL_INDEX'] ??= 'N';
$bConvert = false;
if (isset($arFields['CONVERT']) && $arFields['CONVERT'] == 'Y')
$bConvert = true;
if (!isset($arFields['PARAMS']) || !is_array($arFields['PARAMS']))
{
$arFields['PARAMS'] = Array();
}
if (!isset($arFields['EXTRA_PARAMS']))
{
$arFields['EXTRA_PARAMS'] = Array();
}
$incrementCounter = true;
/*
if (isset($arFields['INCREMENT_COUNTER']) && $arFields['INCREMENT_COUNTER'] != 'Y')
{
if ($arFields['INCREMENT_COUNTER'] == 'N')
{
$incrementCounter = Array();
$arFields['PARAMS']['NOTIFY'] = 'N';
}
else if (is_array($arFields['INCREMENT_COUNTER']))
{
$incrementCounter = array_values($arFields['INCREMENT_COUNTER']);
$arFields['PARAMS']['NOTIFY'] = empty($incrementCounter)? 'N': $incrementCounter;
}
}
*/
if (!isset($arFields['MESSAGE_TYPE']))
$arFields['MESSAGE_TYPE'] = "";
if (!isset($arFields['NOTIFY_MODULE']))
$arFields['NOTIFY_MODULE'] = 'im';
if (!isset($arFields['NOTIFY_EVENT']))
$arFields['NOTIFY_EVENT'] = 'default';
if (isset($arFields['ATTACH']) || isset($arFields['PARAMS']['ATTACH']))
{
$attach = isset($arFields['ATTACH'])? $arFields['ATTACH']: $arFields['PARAMS']['ATTACH'];
if (is_object($attach))
{
$arFields['PARAMS']['ATTACH'] = Array($attach);
}
else if (is_array($attach))
{
$arFields['PARAMS']['ATTACH'] = $attach;
}
else
{
$arFields['PARAMS']['ATTACH'] = Array();
}
}
if (isset($arFields['FILES']))
{
if (is_array($arFields['FILES']))
{
$arFields['PARAMS']['FILE_ID'] = $arFields['FILES'];
}
else
{
$arFields['PARAMS']['FILE_ID'] = Array();
}
}
if (isset($arFields['KEYBOARD']) || isset($arFields['PARAMS']['KEYBOARD']))
{
$keyboard = isset($arFields['KEYBOARD'])? $arFields['KEYBOARD']: $arFields['PARAMS']['KEYBOARD'];
if (is_object($keyboard))
{
$arFields['PARAMS']['KEYBOARD'] = $keyboard;
}
else
{
$arFields['PARAMS']['KEYBOARD'] = Array();
}
}
if (isset($arFields['MENU']) || isset($arFields['PARAMS']['MENU']))
{
$menu = isset($arFields['MENU'])? $arFields['MENU']: $arFields['PARAMS']['MENU'];
if (is_object($menu))
{
$arFields['PARAMS']['MENU'] = $menu;
}
else
{
$arFields['PARAMS']['MENU'] = Array();
}
}
if (isset($arFields['FOR_USER_ID'])) // TODO create this feature in future
{
$arFields['PARAMS']['FOR_USER_ID'] = $arFields['FOR_USER_ID'];
}
$arFields['RECENT_ADD'] = isset($arFields['RECENT_ADD']) && $arFields['RECENT_ADD'] == 'N'? 'N': 'Y';
$arFields['SKIP_COMMAND'] = isset($arFields['SKIP_COMMAND']) && $arFields['SKIP_COMMAND'] == 'Y'? 'Y': 'N';
$arFields['SKIP_CONNECTOR'] = isset($arFields['SKIP_CONNECTOR']) && $arFields['SKIP_CONNECTOR'] == 'Y'? 'Y': 'N';
$arFields['IMPORTANT_CONNECTOR'] = isset($arFields['IMPORTANT_CONNECTOR']) && $arFields['IMPORTANT_CONNECTOR'] == 'Y'? 'Y': 'N';
$arFields['SILENT_CONNECTOR'] = isset($arFields['SILENT_CONNECTOR']) && $arFields['SILENT_CONNECTOR'] == 'Y'? 'Y': 'N';
if ($arFields['SILENT_CONNECTOR'] == 'Y')
{
$arFields['PARAMS']['CLASS'] = "bx-messenger-content-item-system";
}
$arFields['URL_ATTACH'] = Array();
if ($arFields['MESSAGE_TYPE'] == IM_MESSAGE_SYSTEM)
{
if (!isset($arFields['NOTIFY_TYPE']) && intval($arFields['FROM_USER_ID']) > 0)
$arFields['NOTIFY_TYPE'] = IM_NOTIFY_FROM;
else if (!isset($arFields['NOTIFY_TYPE']))
$arFields['NOTIFY_TYPE'] = IM_NOTIFY_SYSTEM;
if (isset($arFields['NOTIFY_ANSWER']) && $arFields['NOTIFY_ANSWER'] == 'Y')
$arFields['PARAMS']['CAN_ANSWER'] = 'Y';
/*
$urlPrepare = self::PrepareUrl($arFields['MESSAGE']);
if ($urlPrepare['RESULT'])
{
if (empty($arFields['MESSAGE_OUT']))
{
$arFields['MESSAGE_OUT'] = $arFields['MESSAGE'];
}
$arFields['MESSAGE'] = $urlPrepare['MESSAGE'];
$arFields['PARAMS']['ATTACH'] = array_merge($arFields['PARAMS']['ATTACH'], $urlPrepare['ATTACH']);
}
*/
}
else if ($arFields['URL_PREVIEW'] == 'Y')
{
$link = new CIMMessageLink();
$message = $arFields['MESSAGE'] ?? null;
$urlPrepare = $link->prepareInsert($message);
if ($urlPrepare['RESULT'])
{
if (empty($arFields['MESSAGE_OUT']))
{
$arFields['MESSAGE_OUT'] = $arFields['MESSAGE'];
}
$arFields['MESSAGE'] = $urlPrepare['MESSAGE'];
if (isset($arFields['PARAMS']['URL_ID']))
{
$arFields['PARAMS']['URL_ID'] = array_merge($arFields['PARAMS']['URL_ID'], $urlPrepare['URL_ID']);
}
else
{
$arFields['PARAMS']['URL_ID'] = $urlPrepare['URL_ID'];
}
$arFields['URL_ATTACH'] = $urlPrepare['ATTACH'];
if ($urlPrepare['MESSAGE_IS_LINK'])
{
$arFields['PARAMS']['URL_ONLY'] = 'Y';
}
}
}
if (isset($arFields['NOTIFY_EMAIL_TEMPLATE']) && !isset($arFields['EMAIL_TEMPLATE']))
$arFields['EMAIL_TEMPLATE'] = $arFields['NOTIFY_EMAIL_TEMPLATE'];
if (!isset($arFields['AUTHOR_ID']))
{
$arFields['AUTHOR_ID'] = isset($arFields['FROM_USER_ID']) ? (int)$arFields['FROM_USER_ID'] : 0;
}
foreach(GetModuleEvents("im", "OnBeforeMessageNotifyAdd", true) as $arEvent)
{
$result = ExecuteModuleEventEx($arEvent, array(&$arFields));
if($result===false || isset($result['result']) && $result['result'] === false)
{
$reason = self::GetReasonForMessageSendError($arFields['MESSAGE_TYPE'], $result['reason']);
$GLOBALS["APPLICATION"]->ThrowException($reason, "ERROR_FROM_OTHER_MODULE");
return false;
}
}
if (!self::CheckFields($arFields))
{
return false;
}
if ($arFields['MESSAGE_TYPE'] != IM_MESSAGE_SYSTEM)
{
$message = $arFields['MESSAGE'] ?? null;
if ($arFields['URL_PREVIEW'] === 'Y')
{
$results = \Bitrix\Im\Text::getDateConverterParams($message);
foreach ($results as $result)
{
$arFields['PARAMS']['DATE_TEXT'][] = $result->getText();
$arFields['PARAMS']['DATE_TS'][] = $result->getDate()->getTimestamp();
}
}
if (\Bitrix\Im\Text::isOnlyEmoji($message))
{
$arFields['PARAMS']['LARGE_FONT'] = 'Y';
}
}
if ($arFields['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE)
{
$isSelfChat = false;
if (isset($arFields['TO_CHAT_ID']))
{
$chatId = $arFields['TO_CHAT_ID'];
$relations = CIMChat::GetRelationById($chatId, false, true, false);
$arFields['TO_USER_ID'] = $arFields['FROM_USER_ID'];
foreach ($relations as $rel)
{
if (
$arFields['TO_USER_ID']
&& $rel['USER_ID'] == $arFields['FROM_USER_ID']
)
{
continue;
}
$arFields['TO_USER_ID'] = $rel['USER_ID'];
}
if ($arFields['FROM_USER_ID'] == $arFields['TO_USER_ID'])
{
$isSelfChat = true;
}
}
else
{
$arFields['FROM_USER_ID'] = intval($arFields['FROM_USER_ID']);
$arFields['TO_USER_ID'] = intval($arFields['TO_USER_ID']);
$chatId = CIMMessage::GetChatId($arFields['FROM_USER_ID'], $arFields['TO_USER_ID']);
if ($arFields['FROM_USER_ID'] == $arFields['TO_USER_ID'])
{
$isSelfChat = true;
}
}
if (!$bConvert && !\Bitrix\Im\Dialog::hasAccess($arFields['TO_USER_ID'], $arFields['FROM_USER_ID']))
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_MESSAGE_CANCELED"), "ERROR_NO_ACCESS");
return false;
}
if ($chatId > 0)
{
$chatData = \Bitrix\Im\Model\ChatTable::getById($chatId)->fetch();
$prevMessageId = intval($chatData['PREV_MESSAGE_ID']);
$arFields['CHAT_ID'] = $chatId;
$arFields = self::UploadFileFromText($arFields);
if (!$arFields)
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_LINES_SHARE_FILE"), "LINES_SHARE");
return false;
}
$arParams = Array();
$arParams['CHAT_ID'] = $chatId;
$arParams['AUTHOR_ID'] = intval($arFields['AUTHOR_ID']);
$arParams['MESSAGE'] = $arFields['MESSAGE'] ?? null;
$arParams['MESSAGE_OUT'] = $arFields['MESSAGE_OUT'];
$arParams['NOTIFY_MODULE'] = $arFields['NOTIFY_MODULE'];
$arParams['NOTIFY_EVENT'] = isset($arFields['SYSTEM']) && $arFields['SYSTEM'] === 'Y' ? 'private_system': 'private';
if (isset($arFields['IMPORT_ID']))
$arParams['IMPORT_ID'] = intval($arFields['IMPORT_ID']);
if (isset($arFields['MESSAGE_DATE']))
{
$arParams['DATE_CREATE'] = new Bitrix\Main\Type\DateTime($arFields['MESSAGE_DATE']);
}
$arFiles = Array();
$arFields['FILES'] = Array();
if (isset($arFields['PARAMS']['FILE_ID']))
{
foreach ($arFields['PARAMS']['FILE_ID'] as $fileId)
{
$arFiles[$fileId] = $fileId;
}
}
$arFields['FILES'] = CIMDisk::GetFiles($chatId, $arFiles, false);
$messageFiles = self::GetFormatFilesMessageOut($arFields['FILES']);
if ($messageFiles <> '')
{
$arParams['MESSAGE_OUT'] = $arParams['MESSAGE_OUT'] <> ''? $arParams['MESSAGE_OUT']."\n".$messageFiles: $messageFiles;
$arFields['MESSAGE_OUT'] = $arParams['MESSAGE_OUT'];
}
$result = \Bitrix\Im\Model\MessageTable::add($arParams);
$messageID = intval($result->getId());
if ($messageID <= 0)
return false;
if (isset($messageUuid))
{
$messageUuid->updateMessageId($messageID);
}
\Bitrix\Im\Model\ChatTable::update($chatId, Array(
'MESSAGE_COUNT' => new \Bitrix\Main\DB\SqlExpression('?# + 1', 'MESSAGE_COUNT'),
//'PREV_MESSAGE_ID' => new \Bitrix\Main\DB\SqlExpression('?#', 'LAST_MESSAGE_ID'),
'LAST_MESSAGE_ID' => $messageID,
//'LAST_MESSAGE_STATUS' => IM_MESSAGE_STATUS_RECEIVED
));
if ($chatData['PARENT_MID'])
{
CIMMessageParam::set($chatData['PARENT_MID'], Array(
'CHAT_MESSAGE' => $chatData['MESSAGE_COUNT']+1,
'CHAT_LAST_DATE' => new \Bitrix\Main\Type\DateTime()
));
CIMMessageParam::SendPull($chatData['PARENT_MID'], Array('CHAT_MESSAGE', 'CHAT_LAST_DATE'));
}
if (empty($arFields['PARAMS']))
{
CIMMessageParam::UpdateTimestamp($messageID, $arParams['CHAT_ID']);
}
else
{
CIMMessageParam::Set($messageID, $arFields['PARAMS']);
}
if (!empty($arFields['URL_ATTACH']))
{
if (isset($arFields['PARAMS']['ATTACH']))
{
$arFields['PARAMS']['ATTACH'] = array_merge($arFields['PARAMS']['ATTACH'], $arFields['URL_ATTACH']);
}
else
{
$arFields['PARAMS']['ATTACH'] = $arFields['URL_ATTACH'];
}
}
$relations = CIMChat::GetRelationById($chatId, false, true, false);
$message = new \Bitrix\Im\V2\Message($arParams);
$message->setMessageId($messageID);
foreach ($relations as $relation)
{
if (\Bitrix\Im\User::getInstance($relation['USER_ID'])->isBot())
{
// bot
}
else if (!\Bitrix\Im\User::getInstance($relation['USER_ID'])->isActive())
{
continue;
}
if (isset($arFields['RECENT_SKIP_AUTHOR']) && $relation['USER_ID'] == $arParams['AUTHOR_ID'])
{
continue;
}
$addToRecent = true;
if ($incrementCounter !== true && !in_array($relation['USER_ID'], $incrementCounter))
{
$addToRecent = \CIMContactList::InRecent($relation['USER_ID'], $arFields['MESSAGE_TYPE'], $relation['CHAT_ID']);
}
if ($addToRecent)
{
CIMContactList::SetRecent(Array(
'ENTITY_ID' => $relation['USER_ID'] == $arFields['TO_USER_ID']? $arFields['FROM_USER_ID']: $arFields['TO_USER_ID'],
'MESSAGE_ID' => $messageID,
'CHAT_TYPE' => IM_MESSAGE_PRIVATE,
'CHAT_ID' => $relation['CHAT_ID'],
'RELATION_ID' => $relation['ID'],
'USER_ID' => $relation['USER_ID']
));
}
}
if (!$bConvert)
{
$pullIncluded = CModule::IncludeModule("pull");
$pullServerActive = $pullIncluded && CPullOptions::GetNginxStatus();
$relations = \Bitrix\Im\Chat::getRelation($chatId, Array(
//'REAL_COUNTERS' => 'Y',
'WITHOUT_COUNTERS' => 'Y',
'USER_DATA' => 'Y',
));
$relationCollection = new \Bitrix\Im\V2\RelationCollection();
foreach ($relations as $id => $relation)
{
if (\Bitrix\Im\User::getInstance($relation["USER_ID"])->isBot())
{
// bot
}
else if ($relation['USER_DATA']['ACTIVE'] == 'N')
{
continue;
}
$relationObject = new \Bitrix\Im\V2\Relation([
'USER_ID' => (int)$relation['USER_ID'],
'CHAT_ID' => $relation['CHAT_ID'],
'MESSAGE_TYPE' => $relation['MESSAGE_TYPE'],
'NOTIFY_BLOCK' => $relation['NOTIFY_BLOCK'] === 'Y',
]);
$relationObject->setId((int)$relation['ID']);
$relationCollection->add($relationObject);
if ($isSelfChat || $relation["USER_ID"] == $arFields["FROM_USER_ID"])
{
$relations[$id]['COUNTER'] = 0;
$relationUpdate = array(
//"STATUS" => IM_STATUS_READ,
//"MESSAGE_STATUS" => IM_MESSAGE_STATUS_RECEIVED,
//"UNREAD_ID" => $messageID,
//"COUNTER" => 0,
"LAST_ID" => $messageID,
//"LAST_SEND_ID" => $messageID,
//"LAST_READ" => new Bitrix\Main\Type\DateTime(),
);
/*if (!$pullServerActive)
{
unset($relationUpdate['STATUS']);
unset($relationUpdate['LAST_ID']);
}*/
if ($pullServerActive)
{
\Bitrix\Im\Model\RelationTable::update($relation["ID"], $relationUpdate);
}
}
else
{
/*$updateRelation = array(
"STATUS" => IM_STATUS_UNREAD,
"MESSAGE_STATUS" => IM_MESSAGE_STATUS_RECEIVED,
"UNREAD_ID" => $messageID,
"COUNTER" => $relation['COUNTER'],
);
if ($relation["UNREAD_ID"])
{
unset($updateRelation['UNREAD_ID']);
}
if ($incrementCounter !== true && !in_array($relation['USER_ID'], $incrementCounter))
{
unset($updateRelation['COUNTER']);
}
\Bitrix\Im\Model\RelationTable::update($relation["ID"], $updateRelation);*/
}
//\Bitrix\Im\Counter::clearCache($relation['USER_ID']);
}
$counters = (new \Bitrix\Im\V2\Message\ReadService((int)$arFields["FROM_USER_ID"]))
->onAfterMessageSend($message, $relationCollection)
->getResult()['COUNTERS']
;
if (CModule::IncludeModule("pull"))
{
$arParams['FROM_USER_ID'] = $arFields['FROM_USER_ID'];
$arParams['TO_USER_ID'] = $arFields['TO_USER_ID'];
$pullMessage = Array(
'module_id' => 'im',
'command' => 'message',
'params' => CIMMessage::GetFormatMessage(Array(
'ID' => $messageID,
'TEMPLATE_ID' => $arFields['TEMPLATE_ID'] ?? null,
'FILE_TEMPLATE_ID' => $arFields['FILE_TEMPLATE_ID'] ?? null,
'PREV_ID' => $prevMessageId,
'CHAT_ID' => $chatId,
'TO_USER_ID' => $arParams['TO_USER_ID'],
'FROM_USER_ID' => $arParams['FROM_USER_ID'],
'SYSTEM' => isset($arFields['SYSTEM']) && $arFields['SYSTEM'] === 'Y' ? 'Y' : 'N',
'MESSAGE' => $arParams['MESSAGE'],
'DATE_CREATE' => time(),
'PARAMS' => self::PrepareParamsForPull($arFields['PARAMS']),
'FILES' => $arFields['FILES'],
'NOTIFY' => $incrementCounter
)),
'extra' => \Bitrix\Im\Common::getPullExtra()
);
$pullMessageTo = $pullMessage;
$pullMessageTo['params']['dialogId'] = $arParams['FROM_USER_ID'];
$pullMessageFrom = $pullMessage;
$pullMessageFrom['params']['dialogId'] = $arParams['TO_USER_ID'];
$pullMessageFrom['params']['counter'] = $counters[(int)$arParams['FROM_USER_ID']] ?? 0;
\Bitrix\Pull\Event::add($arParams['FROM_USER_ID'], $pullMessageFrom);
if ($arParams['FROM_USER_ID'] != $arParams['TO_USER_ID'])
{
$pullMessageTo['params']['counter'] = $counters[(int)$arParams['TO_USER_ID']] ?? 0;
\Bitrix\Pull\Event::add($arParams['TO_USER_ID'], $pullMessageTo);
$pullMessageTo = self::PreparePushForPrivate($pullMessageTo);
$pullMessageFrom = self::PreparePushForPrivate($pullMessageFrom);
if (
!isset($arFields['PUSH'])
|| isset($arFields['PUSH']) && $arFields['PUSH'] === 'Y'
)
{
if (isset($arFields['MESSAGE_PUSH']))
{
$pullMessageTo['push']['message'] = $arFields['MESSAGE_PUSH'];
$pullMessageTo['push']['advanced_params']['senderMessage'] = $arFields['MESSAGE_PUSH'];
$pullMessageFrom['push']['message'] = $arFields['MESSAGE_PUSH'];
$pullMessageFrom['push']['advanced_params']['senderMessage'] = $arFields['MESSAGE_PUSH'];
}
$pullMessageTo['push']['advanced_params']['counter'] = $counters[$arParams['TO_USER_ID']] ?? 0;
\Bitrix\Pull\Push::add($arParams['TO_USER_ID'], $pullMessageTo);
$pullMessageFrom['push']['advanced_params']['counter'] = $counters[$arParams['FROM_USER_ID']] ?? 0;
\Bitrix\Pull\Push::add($arParams['FROM_USER_ID'], array_merge_recursive($pullMessageFrom, ['push' => [
'skip_users' => [$arParams['FROM_USER_ID']],
'advanced_params' => [
"notificationsToCancel" => ['IM_MESS'],
],
'send_immediately' => 'Y',
]]));
}
}
}
foreach(GetModuleEvents("im", "OnAfterMessagesAdd", true) as $arEvent)
ExecuteModuleEventEx($arEvent, array(intval($messageID), $arFields));
$arFields['COMMAND_CONTEXT'] = 'TEXTAREA';
$result = \Bitrix\Im\Command::onCommandAdd(intval($messageID), $arFields);
if (!$result)
{
\Bitrix\Im\Bot::onMessageAdd(intval($messageID), $arFields);
}
if ($arFields['SKIP_URL_INDEX'] !== 'Y')
{
(new \Bitrix\Im\V2\Link\Url\UrlService())->saveUrlsFromMessage($message);
}
(new \Bitrix\Im\V2\Link\File\FileService())->saveFilesFromMessage($arFields['FILES_FROM_TEXT'] ?? [], $message);
}
\Bitrix\Im\Model\MessageTable::indexRecord($messageID);
return $messageID;
}
else
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_MESSAGE_CREATE"), "CHAT_ID");
return false;
}
}
else if ($arFields['MESSAGE_TYPE'] == IM_MESSAGE_CHAT || $arFields['MESSAGE_TYPE'] == IM_MESSAGE_OPEN || $arFields['MESSAGE_TYPE'] == IM_MESSAGE_OPEN_LINE)
{
$arFields['SKIP_USER_CHECK'] = isset($arFields['SKIP_USER_CHECK']) && $arFields['SKIP_USER_CHECK'] == 'Y'? 'Y': 'N';
$arFields['FROM_USER_ID'] = isset($arFields['FROM_USER_ID']) ? (int)$arFields['FROM_USER_ID'] : 0;
$chatId = 0;
$systemMessage = false;
if (isset($arFields['SYSTEM']) && $arFields['SYSTEM'] == 'Y')
{
$strSql = "
SELECT
C.ID CHAT_ID,
C.PARENT_ID CHAT_PARENT_ID,
C.PARENT_MID CHAT_PARENT_MID,
C.TITLE CHAT_TITLE,
C.AUTHOR_ID CHAT_AUTHOR_ID,
C.TYPE CHAT_TYPE,
C.AVATAR CHAT_AVATAR,
C.COLOR CHAT_COLOR,
C.ENTITY_TYPE CHAT_ENTITY_TYPE,
C.ENTITY_ID CHAT_ENTITY_ID,
C.ENTITY_DATA_1 CHAT_ENTITY_DATA_1,
C.ENTITY_DATA_2 CHAT_ENTITY_DATA_2,
C.ENTITY_DATA_3 CHAT_ENTITY_DATA_3,
C.EXTRANET CHAT_EXTRANET,
C.PREV_MESSAGE_ID CHAT_PREV_MESSAGE_ID,
'1' RID,
'Y' IS_MANAGER
FROM b_im_chat C
WHERE C.ID = ".intval($arFields['TO_CHAT_ID'])."
";
$systemMessage = true;
}
else
{
$strSql = "
SELECT
C.ID CHAT_ID,
C.PARENT_ID CHAT_PARENT_ID,
C.PARENT_MID CHAT_PARENT_MID,
C.TITLE CHAT_TITLE,
C.AUTHOR_ID CHAT_AUTHOR_ID,
C.TYPE CHAT_TYPE,
C.AVATAR CHAT_AVATAR,
C.COLOR CHAT_COLOR,
C.ENTITY_TYPE CHAT_ENTITY_TYPE,
C.ENTITY_ID CHAT_ENTITY_ID,
C.ENTITY_DATA_1 CHAT_ENTITY_DATA_1,
C.ENTITY_DATA_2 CHAT_ENTITY_DATA_2,
C.ENTITY_DATA_3 CHAT_ENTITY_DATA_3,
C.EXTRANET CHAT_EXTRANET,
C.PREV_MESSAGE_ID CHAT_PREV_MESSAGE_ID,
R.USER_ID RID,
R.MANAGER IS_MANAGER
FROM b_im_chat C
LEFT JOIN b_im_relation R ON R.CHAT_ID = C.ID AND R.USER_ID = ".$arFields['FROM_USER_ID']."
WHERE C.ID = ".intval($arFields['TO_CHAT_ID'])."
";
}
$dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
if ($arRes = $dbRes->Fetch())
{
$chatId = intval($arRes['CHAT_ID']);
$chatTitle = htmlspecialcharsbx(\Bitrix\Im\Text::decodeEmoji($arRes['CHAT_TITLE']));
$chatAuthorId = intval($arRes['CHAT_AUTHOR_ID']);
$chatParentId = intval($arRes['CHAT_PARENT_ID']);
$chatParentMid = intval($arRes['CHAT_PARENT_MID']);
$chatExtranet = $arRes['CHAT_EXTRANET'] == 'Y';
$arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
$arFields['MESSAGE_TYPE'] = $arRes['CHAT_TYPE'];
$prevMessageId = intval($arRes['CHAT_PREV_MESSAGE_ID']);
$importantPush = $arRes['CHAT_ENTITY_TYPE'] == 'ANNOUNCEMENT';
if ($arFields['SKIP_USER_CHECK'] == 'N')
{
if ($arRes['CHAT_ENTITY_TYPE'] == 'ANNOUNCEMENT' && $arRes['IS_MANAGER'] !== 'Y')
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_GROUP_CANCELED"), "CANCELED");
return false;
}
if ($arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN)
{
if (!CIMMessenger::CheckEnableOpenChat())
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_GROUP_CANCELED"), "CANCELED");
return false;
}
else if (intval($arRes['RID']) <= 0)
{
if (\Bitrix\Im\User::getInstance($arFields['FROM_USER_ID'])->isExtranet())
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_GROUP_CANCELED"), "CANCELED");
return false;
}
else
{
$chat = new CIMChat(0);
$chat->AddUser($chatId, $arFields['FROM_USER_ID']);
}
}
}
else if (intval($arRes['RID']) <= 0)
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_GROUP_CANCELED"), "CANCELED");
return false;
}
}
}
else
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_GROUP_CANCELED"), "CANCELED");
return false;
}
if ($chatId > 0)
{
foreach(GetModuleEvents("im", "OnBeforeChatMessageAdd", true) as $arEvent)
{
$result = ExecuteModuleEventEx($arEvent, array($arFields, $arRes));
if($result===false || isset($result['result']) && $result['result'] === false)
{
$reason = self::GetReasonForMessageSendError($arFields['MESSAGE_TYPE'], $result['reason']);
$GLOBALS["APPLICATION"]->ThrowException($reason, "ERROR_FROM_OTHER_MODULE");
return false;
}
if (isset($result['fields']))
{
$arFields = $result['fields'];
}
}
$chatId = intval($arRes['CHAT_ID']);
$arFields['CHAT_ID'] = $chatId;
$arFields = self::UploadFileFromText($arFields);
$arParams = Array();
$arParams['CHAT_ID'] = $chatId;
$arParams['AUTHOR_ID'] = $systemMessage? 0: intval($arFields['AUTHOR_ID']);
$arParams['MESSAGE'] = $arFields['MESSAGE'] ?? null;
$arParams['MESSAGE_OUT'] = $arFields['MESSAGE_OUT'];
$arParams['NOTIFY_MODULE'] = 'im';
$arParams['NOTIFY_EVENT'] = 'group';
if (isset($arFields['MESSAGE_DATE']))
{
$arParams['DATE_CREATE'] = new Bitrix\Main\Type\DateTime($arFields['MESSAGE_DATE']);
}
$arFiles = Array();
$arFields['FILES'] = Array();
if (isset($arFields['PARAMS']['FILE_ID']))
{
foreach ($arFields['PARAMS']['FILE_ID'] as $fileId)
{
$arFiles[$fileId] = $fileId;
}
}
$arFields['FILES'] = CIMDisk::GetFiles($chatId, $arFiles, false);
$messageFiles = self::GetFormatFilesMessageOut($arFields['FILES']);
if ($messageFiles <> '')
{
$arParams['MESSAGE_OUT'] = $arParams['MESSAGE_OUT'] <> ''? $arParams['MESSAGE_OUT']."\n".$messageFiles: $messageFiles;
$arFields['MESSAGE_OUT'] = $arParams['MESSAGE_OUT'];
}
$result = \Bitrix\Im\Model\MessageTable::add($arParams);
$messageID = intval($result->getId());
if ($messageID <= 0)
return false;
if (isset($messageUuid))
{
$messageUuid->updateMessageId($messageID);
}
if (empty($arFields['PARAMS']))
{
CIMMessageParam::UpdateTimestamp($messageID, $arParams['CHAT_ID']);
}
else
{
CIMMessageParam::Set($messageID, $arFields['PARAMS']);
}
if (!empty($arFields['URL_ATTACH']))
{
if (isset($arFields['PARAMS']['ATTACH']))
{
$arFields['PARAMS']['ATTACH'] = array_merge($arFields['PARAMS']['ATTACH'], $arFields['URL_ATTACH']);
}
else
{
$arFields['PARAMS']['ATTACH'] = $arFields['URL_ATTACH'];
}
}
if (!$bConvert)
{
\Bitrix\Im\Model\ChatTable::update($chatId, Array(
'MESSAGE_COUNT' => new \Bitrix\Main\DB\SqlExpression('?# + 1', 'MESSAGE_COUNT'),
//'PREV_MESSAGE_ID' => new \Bitrix\Main\DB\SqlExpression('?#', 'LAST_MESSAGE_ID'),
'LAST_MESSAGE_ID' => $messageID,
//'LAST_MESSAGE_STATUS' => IM_MESSAGE_STATUS_RECEIVED
));
if ($chatParentMid)
{
$chatData = \Bitrix\Im\Model\ChatTable::getById($chatId)->fetch();
CIMMessageParam::set($chatParentMid, Array(
'CHAT_MESSAGE' => $chatData['MESSAGE_COUNT'],
'CHAT_LAST_DATE' => new \Bitrix\Main\Type\DateTime()
));
CIMMessageParam::SendPull($chatParentMid, Array('CHAT_MESSAGE', 'CHAT_LAST_DATE'));
}
$arParams['FROM_USER_ID'] = $arFields['FROM_USER_ID'];
$arParams['TO_CHAT_ID'] = $arFields['TO_CHAT_ID'];
$arBotInChat = Array();
$relations = \Bitrix\Im\Chat::getRelation($chatId, Array(
//'REAL_COUNTERS' => 'Y',
'WITHOUT_COUNTERS' => 'Y',
'USER_DATA' => 'Y',
'SKIP_CONNECTOR' => $arRes['CHAT_ENTITY_TYPE'] == 'LINES'? 'Y': 'N'
));
$pullIncluded = CModule::IncludeModule("pull");
$pullServerActive = $pullIncluded && CPullOptions::GetNginxStatus();
$events = [];
$skippedRelations = [];
$pushUserSkip = [];
$pushUserSend = [];
$relationCollection = new \Bitrix\Im\V2\RelationCollection();
foreach ($relations as $id => $relation)
{
if ($arFields['RECENT_ADD'] != 'Y')
{
$skippedRelations[$id] = true;
continue;
}
if ($relation['USER_DATA']["EXTERNAL_AUTH_ID"] == \Bitrix\Im\Bot::EXTERNAL_AUTH_ID)
{
$arBotInChat[$relation["USER_ID"]] = $relation["USER_ID"];
}
else if ($relation['USER_DATA']['ACTIVE'] == 'N')
{
$skippedRelations[$id] = true;
continue;
}
$sessionId = 0;
if ($arRes['CHAT_ENTITY_TYPE'] == "LINES")
{
if ($relation['USER_DATA']["EXTERNAL_AUTH_ID"] == 'imconnector')
{
$skippedRelations[$id] = true;
continue;
}
if ($arRes['CHAT_ENTITY_DATA_1'])
{
$fieldData = explode("|", $arRes['CHAT_ENTITY_DATA_1']);
$sessionId = intval($fieldData[5]);
}
}
$addToRecent = true;
if ($incrementCounter !== true && !in_array($relation['USER_ID'], $incrementCounter))
{
$addToRecent = \CIMContactList::InRecent($relation['USER_ID'], $arFields['MESSAGE_TYPE'], $relation['CHAT_ID']);
}
if ($addToRecent)
{
CIMContactList::SetRecent([
'ENTITY_ID' => $chatId,
'MESSAGE_ID' => $messageID,
'CHAT_TYPE' => $arFields['MESSAGE_TYPE'],
'USER_ID' => $relation['USER_ID'],
'CHAT_ID' => $relation['CHAT_ID'],
'RELATION_ID' => $relation['ID'],
'SESSION_ID' => $sessionId,
]);
}
$relationObject = new \Bitrix\Im\V2\Relation([
'USER_ID' => (int)$relation['USER_ID'],
'CHAT_ID' => $relation['CHAT_ID'],
'MESSAGE_TYPE' => $relation['MESSAGE_TYPE'],
'NOTIFY_BLOCK' => $relation['NOTIFY_BLOCK'] === 'Y',
]);
$relationObject->setId((int)$relation['ID']);
$relationCollection->add($relationObject);
if ($relation["USER_ID"] == $arFields["FROM_USER_ID"])
{
$relations[$id]['COUNTER'] = $relation['COUNTER'] = 0;
$relationUpdate = array(
//"STATUS" => IM_STATUS_READ,
//"MESSAGE_STATUS" => IM_MESSAGE_STATUS_RECEIVED,
//"COUNTER" => 0,
//"UNREAD_ID" => $messageID,
"LAST_ID" => $messageID,
//"LAST_SEND_ID" => $messageID,
//"LAST_READ" => new Bitrix\Main\Type\DateTime(),
);
/*if (!$pullServerActive)
{
unset($relationUpdate['STATUS']);
unset($relationUpdate['LAST_ID']);
}*/
if ($pullServerActive)
{
\Bitrix\Im\Model\RelationTable::update($relation["ID"], $relationUpdate);
}
}
else
{
/*$updateRelation = array(
"STATUS" => IM_STATUS_UNREAD,
"UNREAD_ID" => $messageID,
"MESSAGE_STATUS" => IM_MESSAGE_STATUS_RECEIVED,
"COUNTER" => $relation['COUNTER'],
);
if ($relation["UNREAD_ID"])
{
unset($updateRelation['UNREAD_ID']);
}
if ($incrementCounter !== true && !in_array($relation['USER_ID'], $incrementCounter))
{
unset($updateRelation['COUNTER']);
}
\Bitrix\Im\Model\RelationTable::update($relation["ID"], $updateRelation);*/
}
//\Bitrix\Im\Counter::clearCache($relation['USER_ID']);
if (!$pullIncluded)
{
continue;
}
$sendPush = true;
if ($relation['USER_ID'] == $arParams['FROM_USER_ID'])
{
CPushManager::DeleteFromQueueBySubTag($arParams['FROM_USER_ID'], 'IM_MESS');
$sendPush = false;
}
else if ($relation['NOTIFY_BLOCK'] == 'Y' && !$importantPush)
{
$pushUserSkip[] = $relation['USER_ID'];
$pushUserSend[] = $relation['USER_ID'];
}
else if (isset($arFields['PUSH']) && $arFields['PUSH'] === 'N')
{
$sendPush = false;
}
else
{
$pushUserSend[] = $relation['USER_ID'];
}
}
$message = new \Bitrix\Im\V2\Message($arParams);
$message->setMessageId($messageID);
$counters = (new \Bitrix\Im\V2\Message\ReadService((int)$arFields["FROM_USER_ID"]))
->onAfterMessageSend($message, $relationCollection)
->getResult()['COUNTERS']
;
$pullMessage = [
'module_id' => 'im',
'command' => 'messageChat',
'params' => CIMMessage::GetFormatMessage([
'ID' => $messageID,
'TEMPLATE_ID' => $arFields['TEMPLATE_ID'] ?? null,
'FILE_TEMPLATE_ID' => $arFields['FILE_TEMPLATE_ID'] ?? null,
'PREV_ID' => $prevMessageId,
'CHAT_ID' => $chatId,
'TO_CHAT_ID' => $arParams['TO_CHAT_ID'],
'FROM_USER_ID' => $arParams['FROM_USER_ID'],
'MESSAGE' => $arParams['MESSAGE'],
'SYSTEM' => ($arFields['SYSTEM'] ?? null) === 'Y' ? 'Y' : 'N',
'DATE_CREATE' => time(),
'PARAMS' => self::PrepareParamsForPull($arFields['PARAMS']),
'FILES' => $arFields['FILES'],
'EXTRA_PARAMS' => $arFields['EXTRA_PARAMS'],
'COUNTER' => -1,
'NOTIFY' => $incrementCounter
]),
'extra' => \Bitrix\Im\Common::getPullExtra()
];
foreach ($relations as $id => $relation)
{
$skippedRelation = $skippedRelations[$id] ?? null;
if ($skippedRelation)
{
continue;
}
$events[$relation['USER_ID']] = $pullMessage;
$events[$relation['USER_ID']]['params']['counter'] = $counters[$relation['USER_ID']] ?? 0;
//$events[$relation['USER_ID']]['params']['counter'] = $incrementCounter !== true && !in_array($relation['USER_ID'], $incrementCounter)? $relation['PREVIOUS_COUNTER']: $relation['COUNTER'];
$events[$relation['USER_ID']]['groupId'] = 'im_chat_'.$chatId.'_'.$messageID.'_'.$events[$relation['USER_ID']]['params']['counter'];
}
if (($arFields['SYSTEM'] ?? null) !== 'Y')
{
self::SendMention([
'CHAT_ID' => $chatId,
'CHAT_TITLE' => $chatTitle,
'CHAT_RELATION' => $relations,
'CHAT_TYPE' => $arFields['MESSAGE_TYPE'],
'CHAT_ENTITY_TYPE' => $arRes['CHAT_ENTITY_TYPE'],
'CHAT_COLOR' => $arRes['CHAT_COLOR'],
'MESSAGE' => $arParams['MESSAGE'],
'FILES' => $arFields['FILES'],
'FROM_USER_ID' => $arParams['FROM_USER_ID'],
]);
}
if ($pullIncluded)
{
if ($arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN || $arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN_LINE)
{
$watchPullMessage = $pullMessage;
$watchPullMessage['params']['message']['params']['NOTIFY'] = 'N';
CPullWatch::AddToStack('IM_PUBLIC_' . $chatId, $watchPullMessage);
}
$groups = self::GetEventByCounterGroup($events);
foreach ($groups as $group)
{
\Bitrix\Pull\Event::add($group['users'], $group['event']);
$userList = array_intersect($pushUserSend, $group['users']);
if (!empty($userList))
{
$pushParams = $group['event'];
$pushParams = self::PreparePushForChat($pushParams);
if ($importantPush)
{
$pushParams['push']['important'] = 'Y';
}
$pushParams['skip_users'] = $pushUserSkip;
if (isset($arFields['MESSAGE_PUSH']))
{
$pushParams['push']['message'] = $arFields['MESSAGE_PUSH'];
$pushParams['push']['advanced_params']['senderMessage'] = $arFields['MESSAGE_PUSH'];
}
$pushParams['push']['advanced_params']['counter'] = $group['event']['params']['counter'];
\Bitrix\Pull\Push::add($userList, $pushParams);
}
}
}
$arFields['CHAT_AUTHOR_ID'] = $chatAuthorId;
$arFields['CHAT_ENTITY_TYPE'] = $arRes['CHAT_ENTITY_TYPE'];
$arFields['CHAT_ENTITY_ID'] = $arRes['CHAT_ENTITY_ID'];
$arFields['CHAT_ENTITY_DATA_1'] = $arRes['CHAT_ENTITY_DATA_1'];
$arFields['CHAT_ENTITY_DATA_2'] = $arRes['CHAT_ENTITY_DATA_2'];
$arFields['CHAT_ENTITY_DATA_3'] = $arRes['CHAT_ENTITY_DATA_3'];
$arFields['BOT_IN_CHAT'] = $arBotInChat;
foreach (GetModuleEvents("im", "OnAfterMessagesAdd", true) as $arEvent)
ExecuteModuleEventEx($arEvent, [intval($messageID), $arFields]);
$arFields['COMMAND_CONTEXT'] = 'TEXTAREA';
$result = \Bitrix\Im\Command::onCommandAdd(intval($messageID), $arFields);
if (!$result)
{
\Bitrix\Im\Bot::onMessageAdd(intval($messageID), $arFields);
}
if ($arFields['SKIP_URL_INDEX'] !== 'Y')
{
(new \Bitrix\Im\V2\Link\Url\UrlService())->saveUrlsFromMessage($message);
}
(new \Bitrix\Im\V2\Link\File\FileService())->saveFilesFromMessage($arFields['FILES_FROM_TEXT'] ?? [], $message);
}
\Bitrix\Im\Model\MessageTable::indexRecord($messageID);
return $messageID;
}
else
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_MESSAGE_CREATE"), "CHAT_ID");
return false;
}
}
else if ($arFields['MESSAGE_TYPE'] == IM_MESSAGE_SYSTEM)
{
$arFields['TO_USER_ID'] = intval($arFields['TO_USER_ID']);
$blockedExternalAuthId = \Bitrix\Im\Model\UserTable::filterExternalUserTypes(['replica']);
$orm = \Bitrix\Im\Model\UserTable::getById($arFields['TO_USER_ID']);
$userData = $orm->fetch();
if (
!$userData
|| $userData['ACTIVE'] == 'N'
|| in_array($userData['EXTERNAL_AUTH_ID'], $blockedExternalAuthId, true)
)
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_MESSAGE_CREATE"), "TO_USER_ID");
return false;
}
$strSql = "
SELECT ID CHAT_ID
FROM b_im_chat
WHERE AUTHOR_ID = ".$arFields['TO_USER_ID']." AND TYPE = '".IM_MESSAGE_SYSTEM."'
ORDER BY ID ASC
";
$dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
if ($arRes = $dbRes->Fetch())
{
$chatId = intval($arRes['CHAT_ID']);
}
else
{
$result = \Bitrix\Im\V2\Chat\ChatFactory::getInstance()->addChat([
'TYPE' => IM_MESSAGE_SYSTEM,
'AUTHOR_ID' => $arFields['TO_USER_ID']
]);
if (!$result->isSuccess() || !$result->hasResult())
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_MESSAGE_CREATE"), "CHAT_ID");
return false;
}
$chatId = $result->getResult()['CHAT_ID'];
if ($chatId <= 0)
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_MESSAGE_CREATE"), "CHAT_ID");
return false;
}
/*\Bitrix\Im\Model\RelationTable::add(array(
"CHAT_ID" => $chatId,
"MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
"USER_ID" => intval($arFields['TO_USER_ID']),
//"STATUS" => ($bConvert? 2: 0),
));*/
}
if ($chatId > 0)
{
$arFields['MESSAGE'] = \Bitrix\Im\Text::convertHtmlToBbCode($arFields['MESSAGE']);
if (isset($arFields['PUSH_MESSAGE']))
{
$arFields['PUSH_MESSAGE'] = $html = str_replace(' ', ' ', $arFields['PUSH_MESSAGE']);;
}
$arParams = Array();
$arParams['CHAT_ID'] = $chatId;
$arParams['AUTHOR_ID'] = intval($arFields['AUTHOR_ID']);
$arParams['MESSAGE'] = $arFields['MESSAGE'];
$arParams['MESSAGE_OUT'] = $arFields['MESSAGE_OUT'];
$arParams['NOTIFY_TYPE'] = intval($arFields['NOTIFY_TYPE']);
$arParams['NOTIFY_MODULE'] = $arFields['NOTIFY_MODULE'];
$arParams['NOTIFY_EVENT'] = $arFields['NOTIFY_EVENT'];
//if (mb_strlen($arParams['MESSAGE']) <= 0 && mb_strlen($arParams['MESSAGE_OUT']) <= 0)
// return false;
$skipAdd = false;
$skipFlash = false;
if ($arParams['NOTIFY_TYPE'] != IM_NOTIFY_CONFIRM)
{
$skipAdd = !CIMSettings::GetNotifyAccess($arFields["TO_USER_ID"], $arFields["NOTIFY_MODULE"], $arFields["NOTIFY_EVENT"], CIMSettings::CLIENT_SITE);
$skipFlash = $skipAdd;
}
if (!$skipAdd && ($arFields['NOTIFY_ONLY_FLASH'] ?? null) === 'Y')
{
$skipAdd = true;
}
if ($skipAdd)
{
$arParams['NOTIFY_READ'] = 'Y';
}
if (isset($arFields['IMPORT_ID']))
$arParams['IMPORT_ID'] = intval($arFields['IMPORT_ID']);
if (isset($arFields['MESSAGE_DATE']))
{
$arParams['DATE_CREATE'] = new Bitrix\Main\Type\DateTime($arFields['MESSAGE_DATE']);
}
if (isset($arFields['EMAIL_TEMPLATE']) && trim($arFields['EMAIL_TEMPLATE']) <> '')
$arParams['EMAIL_TEMPLATE'] = trim($arFields['EMAIL_TEMPLATE']);
$arParams['NOTIFY_TAG'] = isset($arFields['NOTIFY_TAG'])? $arFields['NOTIFY_TAG']: '';
if (!empty($arParams['NOTIFY_TAG']))
{
$lastMessages = Bitrix\Im\Model\MessageTable::getList([
'select' => ['ID', 'AUTHOR_ID'],
'filter' => [
'=NOTIFY_TAG' => $arParams['NOTIFY_TAG'],
'=CHAT_ID' => $arParams['CHAT_ID'],
]
])->fetchAll();
// If we have other notifications with the same tag,
// we need to get USERS from the old notifications
// then merge it with AUTHOR_ID or create new USERS array with AUTHOR_ID
// then delete old notifications.
if (count($lastMessages) > 0)
{
foreach ($lastMessages as $lastMessage)
{
$lastMessage['AUTHOR_ID'] = (int)$lastMessage['AUTHOR_ID'];
$lastMessageParams = \CIMMessageParam::Get($lastMessage['ID']);
if (empty($lastMessageParams['USERS']) && (int)$arFields['FROM_USER_ID'] !== $lastMessage['AUTHOR_ID'])
{
$arFields['PARAMS']['USERS'] = [$lastMessage['AUTHOR_ID']];
}
else
{
$lastMessageParams['USERS'][] = $lastMessage['AUTHOR_ID'];
$arFields['PARAMS']['USERS'] = array_unique($lastMessageParams['USERS']);
$index = array_search((int)$arFields['FROM_USER_ID'], $arFields['PARAMS']['USERS'], true);
if ($index !== false)
{
array_splice($arFields['PARAMS']['USERS'], $index, 1);
}
}
CIMNotify::Delete($lastMessage['ID']);
}
}
}
$arParams['NOTIFY_SUB_TAG'] = isset($arFields['NOTIFY_SUB_TAG'])? $arFields['NOTIFY_SUB_TAG']: '';
if (isset($arFields['NOTIFY_TITLE']) && trim($arFields['NOTIFY_TITLE']) <> '')
$arParams['NOTIFY_TITLE'] = trim($arFields['NOTIFY_TITLE']);
if ($arParams['NOTIFY_TYPE'] == IM_NOTIFY_CONFIRM)
{
if (isset($arFields['NOTIFY_BUTTONS']))
{
foreach ($arFields['NOTIFY_BUTTONS'] as $key => $arButtons)
{
if (is_array($arButtons))
{
if (isset($arButtons['TITLE']) && $arButtons['TITLE'] <> ''
&& isset($arButtons['VALUE']) && $arButtons['VALUE'] <> ''
&& isset($arButtons['TYPE']) && $arButtons['TYPE'] <> '')
{
$arButtons['TITLE'] = htmlspecialcharsbx($arButtons['TITLE']);
$arButtons['VALUE'] = htmlspecialcharsbx($arButtons['VALUE']);
$arButtons['TYPE'] = htmlspecialcharsbx($arButtons['TYPE']);
$arFields['NOTIFY_BUTTONS'][$key] = $arButtons;
}
else
unset($arFields['NOTIFY_BUTTONS'][$key]);
}
else
unset($arFields['NOTIFY_BUTTONS'][$key]);
}
}
else
{
$arFields['NOTIFY_BUTTONS'] = Array(
Array('TITLE' => GetMessage('IM_ERROR_BUTTON_ACCEPT'), 'VALUE' => 'Y', 'TYPE' => 'accept'),
Array('TITLE' => GetMessage('IM_ERROR_BUTTON_CANCEL'), 'VALUE' => 'N', 'TYPE' => 'cancel'),
);
}
$arParams['NOTIFY_BUTTONS'] = serialize($arFields["NOTIFY_BUTTONS"]);
if (isset($arParams['NOTIFY_TAG']) && $arParams['NOTIFY_TAG'] <> '')
CIMNotify::DeleteByTag($arParams['NOTIFY_TAG']);
}
if ($skipAdd)
{
$messageID = time();
}
else
{
$result = \Bitrix\Im\Model\MessageTable::add($arParams);
$messageID = intval($result->getId());
if ($messageID <= 0)
return false;
if (empty($arFields['PARAMS']))
{
CIMMessageParam::UpdateTimestamp($messageID, $arParams['CHAT_ID']);
}
else
{
CIMMessageParam::Set($messageID, $arFields['PARAMS']);
}
/*$counter = \CIMNotify::GetCounter($chatId);
if ($counter > 100)
{
$counter += 1;
}
else
{
$counter = \CIMNotify::GetRealCounter($chatId);
}*/
/*$DB->Query("
UPDATE b_im_relation
SET STATUS = '".IM_STATUS_UNREAD."', COUNTER = {$counter}
WHERE USER_ID = ".intval($arFields['TO_USER_ID'])." AND MESSAGE_TYPE = '".IM_MESSAGE_SYSTEM."' AND CHAT_ID = ".$chatId
);*/
//\Bitrix\Im\Counter::clearCache($arFields['TO_USER_ID']);
$messageCount = \Bitrix\Im\Model\MessageTable::getList(
[
'select' => ['CNT'],
'filter' => ['=CHAT_ID' => $chatId],
'runtime' => [
new \Bitrix\Main\ORM\Fields\ExpressionField('CNT', 'COUNT(*)')
]
]
)->fetch();
\Bitrix\Im\Model\ChatTable::update($chatId, Array(
'MESSAGE_COUNT' => $messageCount['CNT'],
//'PREV_MESSAGE_ID' => new \Bitrix\Main\DB\SqlExpression('?#', 'LAST_MESSAGE_ID'),
'LAST_MESSAGE_ID' => $messageID,
//'LAST_MESSAGE_STATUS' => IM_MESSAGE_STATUS_RECEIVED
));
CIMMessenger::SpeedFileDelete($arFields['TO_USER_ID'], IM_SPEED_NOTIFY);
$relationObject = new \Bitrix\Im\V2\Relation([
'USER_ID' => (int)$arFields['TO_USER_ID'],
'CHAT_ID' => $chatId,
'MESSAGE_TYPE' => IM_MESSAGE_SYSTEM,
'NOTIFY_BLOCK' => false,
]);
$relationObject->setId(1);
$message = new \Bitrix\Im\V2\Message($arParams);
$message->setMessageId($messageID);
$counter = (new \Bitrix\Im\V2\Message\ReadService((int)$arFields['TO_USER_ID']))
->onAfterNotificationSend($message, $relationObject)->getResult()['COUNTER']
;
}
foreach(GetModuleEvents("im", "OnAfterNotifyAdd", true) as $arEvent)
ExecuteModuleEventEx($arEvent, array(intval($messageID), $arFields));
$counter ??= null;
if (CModule::IncludeModule('pull'))
{
$pullNotificationParams = CIMNotify::GetFormatNotify(
[
'ID' => $messageID,
'DATE_CREATE' => time(),
'FROM_USER_ID' => (int)$arFields['FROM_USER_ID'],
'MESSAGE' => $arParams['MESSAGE'],
'PARAMS' => self::PrepareParamsForPull($arFields['PARAMS']),
'NOTIFY_ONLY_FLASH' => $skipAdd,
'NOTIFY_LINK' => $arFields['NOTIFY_LINK'] ?? null,
'NOTIFY_MODULE' => $arParams['NOTIFY_MODULE'],
'NOTIFY_EVENT' => $arParams['NOTIFY_EVENT'],
'NOTIFY_TAG' => $arParams['NOTIFY_TAG'],
'NOTIFY_TYPE' => $arParams['NOTIFY_TYPE'],
'NOTIFY_BUTTONS' => $arParams['NOTIFY_BUTTONS'] ?? serialize([]),
'NOTIFY_TITLE' => $arParams['NOTIFY_TITLE'] ?? '',
'COUNTER' => $counter,
]
);
// We shouldn't send push, if it is disabled in notification settings.
$needPush = CIMSettings::GetNotifyAccess(
$arFields['TO_USER_ID'],
$arFields['NOTIFY_MODULE'],
$arFields['NOTIFY_EVENT'],
CIMSettings::CLIENT_PUSH
);
if ($needPush)
{
// we prepare push params ONLY if there are no ADVANCED_PARAMS from outside.
// If ADVANCED_PARAMS exists we must not change them.
if (isset($arFields['PUSH_PARAMS']['ADVANCED_PARAMS']))
{
$advancedParams = $arFields['PUSH_PARAMS']['ADVANCED_PARAMS'];
unset($arFields['PUSH_PARAMS']['ADVANCED_PARAMS']);
}
else
{
$advancedParams = self::prepareAdvancedParamsForNotificationPush(
$pullNotificationParams,
$arFields['PUSH_MESSAGE'] ?? null
);
}
\Bitrix\Pull\Push::add(
$arFields['TO_USER_ID'],
[
'module_id' => $arParams['NOTIFY_MODULE'],
'push' => [
'type' => $arFields['NOTIFY_EVENT'],
'message' => $arFields['PUSH_MESSAGE'] ?? null,
'params' => $arFields['PUSH_PARAMS'] ?? ['TAG' => 'IM_NOTIFY'],
'advanced_params' => $advancedParams,
'important' => isset($arFields['PUSH_IMPORTANT']) && $arFields['PUSH_IMPORTANT'] === 'Y' ? 'Y': 'N',
'tag' => $arParams['NOTIFY_TAG'],
'sub_tag' => $arParams['NOTIFY_SUB_TAG'],
'app_id' => $arParams['PUSH_APP_ID'] ?? '',
]
]
);
}
if (!$skipFlash)
{
\Bitrix\Pull\Event::add(
$arFields['TO_USER_ID'],
[
'module_id' => 'im',
'command' => 'notifyAdd',
'params' => $pullNotificationParams,
'extra' => \Bitrix\Im\Common::getPullExtra()
]
);
}
}
if (!$skipAdd)
{
\Bitrix\Im\Model\MessageTable::indexRecord($messageID);
}
return $messageID;
}
else
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_MESSAGE_CREATE"), "CHAT_ID");
return false;
}
}
else
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_MESSAGE_TYPE"), "MESSAGE_TYPE");
return false;
}
}
public static function IsMobileRequest()
{
return isset($_REQUEST['MOBILE']) && $_REQUEST['MOBILE'] == 'Y' || defined('BX_MOBILE');
}
public static function CheckPossibilityUpdateMessage($type, $id, $userId = null)
{
$id = intval($id);
if ($id <= 0)
return false;
$enableCheck = self::IsEnabledMessageCheck();
if ($enableCheck)
{
global $USER;
$userId = is_null($userId)? $USER->GetId(): intval($userId);
if ($userId <= 0)
return false;
}
$result = false;
if (CModule::IncludeModule('pull') && CPullOptions::GetNginxStatus())
{
$message = self::GetById($id);
$skipUserCheck = false;
if ($message !== false)
{
$isMessageDeleted = $message['PARAMS']['IS_DELETED'] ?? null;
if
(
$type == IM_CHECK_DELETE
&& (
$message['AUTHOR_ID'] == 0 && $message['CHAT_ENTITY_TYPE'] === 'LINES'
|| !\Bitrix\Im\User::getInstance($message['AUTHOR_ID'])->isActive() && !\Bitrix\Im\User::getInstance($message['AUTHOR_ID'])->isExtranet()
|| \Bitrix\Im\User::getInstance($message['AUTHOR_ID'])->isConnector()
|| $message['CHAT_ID'] == CIMChat::GetGeneralChatId()
)
&& self::IsAdmin()
)
{
$skipUserCheck = true;
}
else if (
\Bitrix\Im\User::getInstance($userId)->isBot()
&& ($message['AUTHOR_ID'] == 0 || $isMessageDeleted === 'Y')
)
{}
else if (
$isMessageDeleted === 'Y'
|| $type != IM_CHECK_DELETE
&& $message['DATE_CREATE'] + 259200 < time())
{
return false;
}
}
else
{
return false;
}
if ($enableCheck)
{
if ($message['CHAT_ENTITY_TYPE'] == 'LINES' && CModule::IncludeModule('imopenlines'))
{
[$connectorType] = explode("|", $message['CHAT_ENTITY_ID']);
if (\Bitrix\Im\User::getInstance($userId)->isBot())
{
if ($message['AUTHOR_ID'] != $userId)
{
$relation = \CIMMessenger::GetRelationById($id);
if (!isset($relation[$userId]))
{
return false;
}
}
}
else if ($message['AUTHOR_ID'] == $userId)
{
if (!($type == IM_CHECK_UPDATE && in_array($connectorType, \Bitrix\ImOpenlines\Connector::getListCanUpdateOwnMessage()))
&& !($type == IM_CHECK_DELETE && in_array($connectorType, \Bitrix\ImOpenlines\Connector::getListCanDeleteOwnMessage())))
{
return false;
}
}
else
{
if ($type == IM_CHECK_UPDATE || !$skipUserCheck && !in_array($connectorType, \Bitrix\ImOpenlines\Connector::getListCanDeleteMessage()))
{
return false;
}
}
}
else if (!$skipUserCheck && $message['AUTHOR_ID'] != $userId)
{
return false;
}
}
$result = $message;
}
return $result;
}
public static function Update($id, $text, $urlPreview = true, $editFlag = true, $userId = null, $byEvent = false, $convert = false)
{
if (mb_strlen($text) > self::MESSAGE_LIMIT + 6)
{
$text = mb_substr($text, 0, self::MESSAGE_LIMIT).' (...)';
}
$updateFlags = Array(
'ID' => $id,
'TEXT' => $text,
'URL_PREVIEW' => $urlPreview,
'EDIT_FLAG' => $editFlag,
'USER_ID' => $userId,
'BY_EVENT' => $byEvent,
);
$text = trim(str_replace(Array('[BR]', '[br]'), "\n", $text));
if ($text == '')
{
return self::Delete($id, $userId, false, $byEvent);
}
$message =
!$convert
? self::CheckPossibilityUpdateMessage(IM_CHECK_UPDATE, $id, $userId)
: self::GetById((int)$id)
;
if (!$message)
return false;
$dateText = Array();
$dateTs = Array();
if ($urlPreview)
{
$results = \Bitrix\Im\Text::getDateConverterParams($text);
foreach ($results as $result)
{
$dateText[] = $result->getText();
$dateTs[] = $result->getDate()->getTimestamp();
}
}
$arUpdate = Array('MESSAGE' => $text, 'MESSAGE_OUT' => '');
$urlId = Array();
$urlOnly = false;
if ($urlPreview)
{
$link = new CIMMessageLink();
$urlPrepare = $link->prepareInsert($text);
if ($urlPrepare['RESULT'])
{
$arUpdate['MESSAGE_OUT'] = $text;
$arUpdate['MESSAGE'] = $urlPrepare['MESSAGE'];
$urlId = $urlPrepare['URL_ID'];
if ($urlPrepare['MESSAGE_IS_LINK'])
{
$urlOnly = true;
}
}
}
\Bitrix\Im\Model\MessageTable::update($message['ID'], $arUpdate);
$isOnlyEmoji = \Bitrix\Im\Text::isOnlyEmoji($arUpdate['MESSAGE']);
CIMMessageParam::Set($message['ID'], Array('IS_EDITED' => $editFlag?'Y':'N', 'URL_ID' => $urlId, 'URL_ONLY' => $urlOnly?'Y':'N', 'LARGE_FONT' => $isOnlyEmoji?'Y':'N', 'DATE_TEXT' => $dateText, 'DATE_TS' => $dateTs));
if (!$convert)
{
$arFields = $message;
$arFields['MESSAGE'] = $text;
$arFields['DATE_MODIFY'] = new \Bitrix\Main\Type\DateTime();
$pullMessage = \Bitrix\Im\Text::parse($arFields['MESSAGE']);
$relations = CIMMessenger::GetRelationById($message['ID']);
$arPullMessage = Array(
'id' => (int)$arFields['ID'],
'type' => $arFields['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE? 'private': 'chat',
'text' => $pullMessage,
'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arFields['MESSAGE']),
);
$arBotInChat = Array();
if ($message['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE)
{
$arFields['FROM_USER_ID'] = $arFields['AUTHOR_ID'];
$arFields['TO_USER_ID'] = $arFields['AUTHOR_ID'];
foreach ($relations as $rel)
{
if ($rel['USER_ID'] != $arFields['AUTHOR_ID'])
{
$arFields['TO_USER_ID'] = $rel['USER_ID'];
}
}
$arPullMessage['fromUserId'] = (int)$arFields['FROM_USER_ID'];
$arPullMessage['toUserId'] = (int)$arFields['TO_USER_ID'];
$arPullMessage['senderId'] = (int)$arFields['FROM_USER_ID'];
$arPullMessage['chatId'] = (int)$arFields['CHAT_ID'];
}
else
{
$arPullMessage['chatId'] = (int)$arFields['CHAT_ID'];
$arPullMessage['senderId'] = (int)$arFields['AUTHOR_ID'];
foreach ($relations as $relation)
{
if ($message['CHAT_ENTITY_TYPE'] == 'LINES')
{
if ($relation["EXTERNAL_AUTH_ID"] == 'imconnector')
{
unset($relations[$relation["USER_ID"]]);
continue;
}
}
if ($relation["EXTERNAL_AUTH_ID"] == \Bitrix\Im\Bot::EXTERNAL_AUTH_ID)
{
$arBotInChat[$relation["USER_ID"]] = $relation["USER_ID"];
unset($relations[$relation["USER_ID"]]);
continue;
}
}
}
$arMessages[$message['ID']] = [];
$params = CIMMessageParam::Get([$message['ID']], false);
$arMessages[$message['ID']]['params'] = $params[$message['ID']];
$arDefault = CIMMessageParam::GetDefault();
if (!isset($arMessages[$message['ID']]['params']['IS_EDITED']))
{
$arMessages[$message['ID']]['params']['IS_EDITED'] = $arDefault['IS_EDITED'];
}
if (!isset($arMessages[$message['ID']]['params']['URL_ID']))
{
$arMessages[$message['ID']]['params']['URL_ID'] = $arDefault['URL_ID'];
}
if (!isset($arMessages[$message['ID']]['params']['ATTACH']))
{
$arMessages[$message['ID']]['params']['ATTACH'] = $arDefault['ATTACH'];
}
if (!isset($arMessages[$message['ID']]['params']['DATE_TEXT']))
{
$arMessages[$message['ID']]['params']['DATE_TEXT'] = $arDefault['DATE_TEXT'];
}
if (!isset($arMessages[$message['ID']]['params']['DATE_TS']))
{
$arMessages[$message['ID']]['params']['DATE_TS'] = $arDefault['DATE_TS'];
}
$arMessages = CIMMessageLink::prepareShow($arMessages, $params);
$arPullMessage['params'] = CIMMessenger::PrepareParamsForPull($arMessages[$message['ID']]['params']);
if ($message['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE)
{
$arPullMessage['dialogId'] = (int)$arFields['FROM_USER_ID'];
$arPullMessage['fromUserId'] = (int)$arFields['FROM_USER_ID'];
$arPullMessage['toUserId'] = (int)$arFields['TO_USER_ID'];
\Bitrix\Pull\Event::add($arPullMessage['toUserId'], [
'module_id' => 'im',
'command' => 'messageUpdate',
'params' => $arPullMessage,
'extra' => \Bitrix\Im\Common::getPullExtra()
]);
$arPullMessage['dialogId'] = (int)$arFields['TO_USER_ID'];
$arPullMessage['fromUserId'] = (int)$arFields['TO_USER_ID'];
$arPullMessage['toUserId'] = (int)$arFields['FROM_USER_ID'];
\Bitrix\Pull\Event::add($arPullMessage['toUserId'], [
'module_id' => 'im',
'command' => 'messageUpdate',
'params' => $arPullMessage,
'extra' => \Bitrix\Im\Common::getPullExtra()
]);
}
else
{
$arPullMessage['dialogId'] = 'chat' . $arPullMessage['chatId'];
\Bitrix\Pull\Event::add(array_keys($relations), [
'module_id' => 'im',
'command' => 'messageUpdate',
'params' => $arPullMessage,
'extra' => \Bitrix\Im\Common::getPullExtra()
]);
}
if ($message['MESSAGE_TYPE'] == IM_MESSAGE_OPEN || $message['MESSAGE_TYPE'] == IM_MESSAGE_OPEN_LINE)
{
CPullWatch::AddToStack('IM_PUBLIC_' . $message['CHAT_ID'], [
'module_id' => 'im',
'command' => 'messageUpdate',
'params' => $arPullMessage,
'extra' => \Bitrix\Im\Common::getPullExtra()
]);
}
if ($message['MESSAGE_TYPE'] != IM_MESSAGE_PRIVATE)
{
$arFields['BOT_IN_CHAT'] = $arBotInChat;
}
\Bitrix\Main\Application::getConnection()->query(
"UPDATE b_im_recent SET DATE_UPDATE = NOW() WHERE ITEM_MID = " . intval($id)
);
foreach (GetModuleEvents("im", "OnAfterMessagesUpdate", true) as $arEvent)
{
ExecuteModuleEventEx($arEvent, [intval($id), $arFields, $updateFlags]);
}
\Bitrix\Im\Bot::onMessageUpdate(intval($id), $arFields);
$message = (new \Bitrix\Im\V2\Message())
->setMessageId((int)$id)
->setMessage($arFields['MESSAGE'])
->setChatId((int)$arFields['CHAT_ID'])
->setAuthorId((int)$arFields['AUTHOR_ID'])
;
(new \Bitrix\Im\V2\Link\Url\UrlService())->updateUrlsFromMessage($message);
}
\Bitrix\Im\Model\MessageTable::indexRecord($id);
return true;
}
public static function Share($id, $type, $date = '')
{
$chat = new CIMShare();
if (\Bitrix\Im\User::getInstance($chat->user_id)->isExtranet())
{
return false;
}
if ($type == 'CHAT')
{
$result = $chat->Chat($id);
}
else if ($type == 'TASK')
{
$result = $chat->Task($id, $date);
}
else if ($type == 'POST')
{
$result = $chat->Post($id);
}
else if ($type == 'CALEND')
{
$result = $chat->Calendar($id, $date);
}
return $result;
}
public static function Delete($id, $userId = null, $completeDelete = false, $byEvent = false)
{
$deleteFlags = Array(
'ID' => $id,
'USER_ID' => $userId,
'COMPLETE_DELETE' => $completeDelete,
'BY_EVENT' => $byEvent
);
$message = self::CheckPossibilityUpdateMessage(IM_CHECK_DELETE, $id, $userId);
if (!$message)
return false;
$deleteFlags['COMPLETE_DELETE'] = $completeDelete = $message['CHAT_ID'] == CIMChat::GetGeneralChatId() && self::IsAdmin()? true: $completeDelete;
$params = CIMMessageParam::Get($message['ID']);
if (!empty($params['FILE_ID']))
{
foreach ($params['FILE_ID'] as $fileId)
{
CIMDisk::DeleteFile($message['CHAT_ID'], $fileId);
}
}
$date = FormatDate("FULL", $message['DATE_CREATE']+CTimeZone::GetOffset());
if (!$completeDelete)
{
\Bitrix\Im\Model\MessageTable::update($message['ID'], array(
"MESSAGE" => GetMessage('IM_MESSAGE_DELETED'),
"MESSAGE_OUT" => GetMessage('IM_MESSAGE_DELETED_OUT', Array('#DATE#' => $date)),
));
CIMMessageParam::Set($message['ID'], Array('IS_DELETED' => 'Y', 'URL_ID' => Array(), 'FILE_ID' => Array(), 'KEYBOARD' => 'N', 'ATTACH' => Array()));
}
$arFields = $message;
$arFields['MESSAGE'] = GetMessage('IM_MESSAGE_DELETED_OUT', Array('#DATE#' => $date));
$arFields['DATE_MODIFY'] = new \Bitrix\Main\Type\DateTime();
$relations = CIMMessenger::GetRelationById($message['ID']);
$arPullMessage = Array(
'id' => (int)$arFields['ID'],
'type' => $arFields['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE? 'private': 'chat',
'text' => GetMessage('IM_MESSAGE_DELETED'),
'params' => Array('IS_DELETED' => 'Y', 'URL_ID' => Array(), 'FILE_ID' => Array(), 'KEYBOARD' => 'N', 'ATTACH' => Array())
);
$arBotInChat = Array();
if ($message['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE)
{
$arFields['FROM_USER_ID'] = $arFields['AUTHOR_ID'];
$arFields['TO_USER_ID'] = $arFields['AUTHOR_ID'];
foreach ($relations as $rel)
{
if ($rel['USER_ID'] != $arFields['AUTHOR_ID'])
$arFields['TO_USER_ID'] = $rel['USER_ID'];
}
$arPullMessage['fromUserId'] = (int)$arFields['FROM_USER_ID'];
$arPullMessage['toUserId'] = (int)$arFields['TO_USER_ID'];
$arPullMessage['senderId'] = (int)$arFields['FROM_USER_ID'];
$arPullMessage['chatId'] = (int)$arFields['CHAT_ID'];
}
else
{
$arPullMessage['chatId'] = (int)$arFields['CHAT_ID'];
$arPullMessage['senderId'] = (int)$arFields['AUTHOR_ID'];
foreach ($relations as $relation)
{
if ($message['CHAT_ENTITY_TYPE'] == 'LINES')
{
if ($relation["EXTERNAL_AUTH_ID"] == 'imconnector')
{
unset($relations[$relation["USER_ID"]]);
continue;
}
}
if ($relation["EXTERNAL_AUTH_ID"] == \Bitrix\Im\Bot::EXTERNAL_AUTH_ID)
{
$arBotInChat[$relation["USER_ID"]] = $relation["USER_ID"];
unset($relations[$relation["USER_ID"]]);
continue;
}
}
}
if ($message['MESSAGE_TYPE'] != IM_MESSAGE_PRIVATE)
{
$arFields['BOT_IN_CHAT'] = $arBotInChat;
}
\Bitrix\Im\Bot::onMessageDelete(intval($id), $arFields);
if ($completeDelete)
{
\Bitrix\Im\Model\ChatTable::update($message['CHAT_ID'], Array(
'MESSAGE_COUNT' => new \Bitrix\Main\DB\SqlExpression('?# - 1', 'MESSAGE_COUNT'),
));
if ($message['CHAT_PARENT_MID'])
{
$chatData = \Bitrix\Im\Model\ChatTable::getById($message['CHAT_ID'])->fetch();
CIMMessageParam::set($chatData['PARENT_MID'], Array(
'CHAT_MESSAGE' => $chatData['MESSAGE_COUNT'],
'CHAT_LAST_DATE' => new \Bitrix\Main\Type\DateTime()
));
CIMMessageParam::SendPull($chatData['PARENT_MID'], Array('CHAT_MESSAGE', 'CHAT_LAST_DATE'));
}
$messageObject = new \Bitrix\Im\V2\Message((int)$id);
(new \Bitrix\Im\V2\Link\Favorite\FavoriteService())->unmarkMessageAsFavoriteForAll($messageObject);
(new \Bitrix\Im\V2\Message\ReadService())->deleteByMessageId(
$id,
\Bitrix\Im\V2\Chat::getInstance((int)$message['CHAT_ID'])->getRelations()->getUserIds()
);
$completeDelete = true;
CIMMessageParam::DeleteAll($message['ID']);
\Bitrix\Im\Model\MessageTable::delete($message['ID']);
/*$relationCounters = \Bitrix\Im\Chat::getRelation($message['CHAT_ID'], Array(
'SELECT' => Array('ID', 'USER_ID'),
'REAL_COUNTERS' => 'Y',
'USER_DATA' => 'Y',
'SKIP_RELATION_WITH_UNMODIFIED_COUNTERS' => 'Y'
));
foreach ($relationCounters as $relation)
{
if (
$relation['USER_DATA']["EXTERNAL_AUTH_ID"] == \Bitrix\Im\Bot::EXTERNAL_AUTH_ID
|| $relation['USER_DATA']['ACTIVE'] == 'N'
)
{
continue;
}
//\Bitrix\Im\Model\RelationTable::update($relation['ID'], Array('COUNTER' => $relation['COUNTER']));
\Bitrix\Im\Counter::clearCache($relation['USER_ID']);
}*/
$result = \Bitrix\Im\Model\RecentTable::getList(Array('filter' => Array('=ITEM_MID' => $message['ID'])))->fetchAll();
if (!empty($result))
{
$message = \Bitrix\Im\Model\MessageTable::getList(Array(
'filter' => Array('=CHAT_ID' => $message['CHAT_ID']),
'limit' => 1,
'order' => Array('ID' => 'DESC')
))->fetch();
if ($message)
{
foreach ($result as $recent)
{
\Bitrix\Im\Model\RecentTable::update(Array(
'USER_ID' => $recent['USER_ID'],
'ITEM_TYPE' => $recent['ITEM_TYPE'],
'ITEM_ID' => $recent['ITEM_ID'],
), Array('ITEM_MID' => $message['ID']));
if ($recent['ITEM_TYPE'] == IM_MESSAGE_PRIVATE)
CIMMessenger::SpeedFileDelete($recent['USER_ID'], IM_SPEED_GROUP);
else
CIMMessenger::SpeedFileDelete($recent['USER_ID'], IM_SPEED_MESSAGE);
}
}
}
}
if ($message['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE)
{
$arPullMessage['dialogId'] = (int)$arFields['FROM_USER_ID'];
$arPullMessage['chatId'] = (int)$message['CHAT_ID'];
$arPullMessage['fromUserId'] = (int)$arFields['FROM_USER_ID'];
$arPullMessage['toUserId'] = (int)$arFields['TO_USER_ID'];
\Bitrix\Pull\Event::add($arPullMessage['toUserId'], Array(
'module_id' => 'im',
'command' => ($completeDelete? 'messageDeleteComplete': 'messageDelete'),
'params' => $arPullMessage,
'push' => $completeDelete? Array('badge' => 'Y'): Array(),
'extra' => \Bitrix\Im\Common::getPullExtra()
));
$arPullMessage['dialogId'] = (int)$arFields['TO_USER_ID'];
$arPullMessage['fromUserId'] = (int)$arFields['TO_USER_ID'];
$arPullMessage['toUserId'] = (int)$arFields['FROM_USER_ID'];
\Bitrix\Pull\Event::add($arPullMessage['toUserId'], Array(
'module_id' => 'im',
'command' => ($completeDelete? 'messageDeleteComplete': 'messageDelete'),
'params' => $arPullMessage,
'push' => $completeDelete? Array('badge' => 'Y'): Array(),
'extra' => \Bitrix\Im\Common::getPullExtra()
));
}
else
{
$arPullMessage['dialogId'] = 'chat'.$arPullMessage['chatId'];
$arPullMessage['chatId'] = (int)$message['CHAT_ID'];
\Bitrix\Pull\Event::add(array_keys($relations), Array(
'module_id' => 'im',
'command' => ($completeDelete? 'messageDeleteComplete': 'messageDelete'),
'params' => $arPullMessage,
'push' => $completeDelete? Array('badge' => 'Y'): Array(),
'extra' => \Bitrix\Im\Common::getPullExtra()
));
}
if ($message['MESSAGE_TYPE'] == IM_MESSAGE_OPEN || $message['MESSAGE_TYPE'] == IM_MESSAGE_OPEN_LINE)
{
CPullWatch::AddToStack('IM_PUBLIC_'.$message['CHAT_ID'], Array(
'module_id' => 'im',
'command' => ($completeDelete? 'messageDeleteComplete': 'messageDelete'),
'params' => $arPullMessage,
'push' => $completeDelete? Array('badge' => 'Y'): Array(),
'extra' => \Bitrix\Im\Common::getPullExtra()
));
}
$indexEnabled = \Bitrix\Main\Config\Option::get('im', 'message_history_index');
if ($indexEnabled)
{
\Bitrix\Im\Model\MessageIndexTable::delete($id);
}
$messageObject = new \Bitrix\Im\V2\Message(
[
'ID' => (int)$id,
'CHAT_ID' => (int)$message['CHAT_ID'],
'AUTHOR_ID' => (int)$arFields['AUTHOR_ID']
]
);
(new \Bitrix\Im\V2\Link\Url\UrlService())->deleteUrlsByMessage($messageObject);
(new \Bitrix\Im\V2\Link\Pin\PinService())->unpinMessage($messageObject);
foreach(GetModuleEvents("im", "OnAfterMessagesDelete", true) as $arEvent)
ExecuteModuleEventEx($arEvent, array(intval($id), $arFields, $deleteFlags));
return true;
}
public static function LinesSessionVote($dialogId, $messageId, $action, $userId = null)
{
global $USER;
$userId = is_null($userId) ? $USER->getId(): (int)$userId;
$messageId = (int)$messageId;
if ($userId <= 0 || $messageId <= 0 || $dialogId == '')
{
return false;
}
$message = self::getById($messageId);
if (!$message)
{
return false;
}
// only messages from network bots
if (!\Bitrix\Im\User::getInstance($message['AUTHOR_ID'])->isBot() || !\Bitrix\Im\User::getInstance($message['AUTHOR_ID'])->isNetwork())
{
return false;
}
$sessionId = (int)$message['PARAMS']['IMOL_VOTE'];
if ($sessionId <= 0)
{
return false;
}
$timeToVote = (int)$message['PARAMS']['IMOL_TIME_LIMIT_VOTE'];
if ($timeToVote > 0 && ($message['DATE_CREATE'] + $timeToVote < time()))
{
// expired
return false;
}
$relations = self::getRelationById($messageId);
if (!isset($relations[$userId]))
{
return false;
}
$action = $action == 'dislike' ? 'dislike': 'like';
\CIMMessageParam::set($messageId, Array('IMOL_VOTE' => $action));
\CIMMessageParam::sendPull($messageId, Array('IMOL_VOTE'));
$chat = \Bitrix\Im\Model\ChatTable::getByPrimary($message['CHAT_ID'])->fetch();
if ($chat['ENTITY_TYPE'] == 'LIVECHAT')
{
\CIMMessageParam::set($message['PARAMS']['CONNECTOR_MID'][0], Array('IMOL_VOTE' => $action));
\CIMMessageParam::sendPull($message['PARAMS']['CONNECTOR_MID'][0], Array('IMOL_VOTE'));
if (\Bitrix\Main\Loader::includeModule('imopenlines'))
{
\Bitrix\ImOpenlines\Session::voteAsUser($sessionId, $action);
}
}
foreach(\GetModuleEvents('im', 'OnSessionVote', true) as $arEvent)
{
\ExecuteModuleEventEx($arEvent, array(array(
'DIALOG_ID' => $dialogId,
'MESSAGE_ID' => $messageId,
'SESSION_ID' => $sessionId,
'MESSAGE' => $message,
'ACTION' => $action,
'CHAT' => $chat,
'RELATION' => $relations,
'USER_ID' => $userId
)));
}
return true;
}
public static function Like($id, $action = 'auto', $userId = null, $byEvent = false, $withReaction = true)
{
if (!CModule::IncludeModule('pull'))
return false;
global $USER;
$userId = is_null($userId)? $USER->GetId(): intval($userId);
if ($userId <= 0)
return false;
$action = in_array($action, Array('plus', 'minus'))? $action: 'auto';
$message = self::GetById($id);
if (!$message)
return false;
$relations = self::GetRelationById($id);
$result = \Bitrix\Im\Model\ChatTable::getList(Array(
'filter'=>Array(
'=ID' => $message['CHAT_ID']
)
));
$chat = $result->fetch();
if ($chat['ENTITY_TYPE'] != 'LIVECHAT')
{
if (!isset($relations[$userId]))
return false;
}
if (!$byEvent && $chat['ENTITY_TYPE'] == 'LINES')
{
[$connectorType, $lineId, $chatId] = explode("|", $chat['ENTITY_ID']);
if ($connectorType == "livechat")
{
foreach($message['PARAMS']['CONNECTOR_MID'] as $mid)
{
self::Like($mid, $action, $userId, true, false);
}
}
}
else if (!$byEvent && $chat['ENTITY_TYPE'] == 'LIVECHAT')
{
foreach($message['PARAMS']['CONNECTOR_MID'] as $mid)
{
self::Like($mid, $action, $userId, true, false);
}
}
$isLike = false;
if (isset($message['PARAMS']['LIKE']))
{
$isLike = in_array($userId, $message['PARAMS']['LIKE']);
}
if ($isLike && $action == 'plus')
{
return false;
}
else if (!$isLike && $action == 'minus')
{
return false;
}
$isLike = true;
if (isset($message['PARAMS']['LIKE']))
{
$like = $message['PARAMS']['LIKE'];
$selfLike = array_search($userId, $like);
if ($selfLike !== false)
{
$isLike = false;
unset($like[$selfLike]);
}
else
{
$like[] = $userId;
}
}
else
{
$like = Array($userId);
}
sort($like);
CIMMessageParam::Set($id, Array('LIKE' => $like));
if ($withReaction)
{
$messageObject = new \Bitrix\Im\V2\Message([
'ID' => $message['ID'],
'CHAT_ID' => $message['CHAT_ID'],
'AUTHOR_ID' => $message['AUTHOR_ID'],
'MESSAGE' => $message['MESSAGE'],
]);
$reactionService = new \Bitrix\Im\V2\Message\Reaction\ReactionService($messageObject, false);
if ($isLike)
{
$reactionService->addReaction(\Bitrix\Im\V2\Message\Reaction\ReactionItem::LIKE);
}
else
{
$reactionService->deleteReaction(\Bitrix\Im\V2\Message\Reaction\ReactionItem::LIKE);
}
}
if ($message['AUTHOR_ID'] > 0 && $message['AUTHOR_ID'] != $userId && $isLike && $chat['ENTITY_TYPE'] != 'LIVECHAT')
{
$message['MESSAGE'] = self::PrepareParamsForPush($message);
$isChat = $chat && $chat['TITLE'] <> '';
$dot = mb_strlen($message['MESSAGE']) >= 200? '...': '';
$message['MESSAGE'] = mb_substr($message['MESSAGE'], 0, 199).$dot;
$message['MESSAGE'] = $message['MESSAGE'] <> ''? $message['MESSAGE']: '-';
/*$arMessageFields = array(
"MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
"TO_USER_ID" => $message['AUTHOR_ID'],
"FROM_USER_ID" => $userId,
"NOTIFY_TYPE" => IM_NOTIFY_FROM,
"NOTIFY_MODULE" => "im",
"NOTIFY_EVENT" => "like",
"NOTIFY_TAG" => "RATING|IM|".($isChat? 'G':'P')."|".($isChat? $chat['ID']: $userId)."|".$id,
"NOTIFY_MESSAGE" => GetMessage($isChat? 'IM_MESSAGE_LIKE': 'IM_MESSAGE_LIKE_PRIVATE', Array(
'#MESSAGE#' => $message['MESSAGE'],
'#TITLE#' => $isChat? '[CHAT='.$chat['ID'].']'.$chat['TITLE'].'[/CHAT]': $chat['TITLE']
)),
"NOTIFY_MESSAGE_OUT" => GetMessage($isChat? 'IM_MESSAGE_LIKE': 'IM_MESSAGE_LIKE_PRIVATE', Array(
'#MESSAGE#' => $message['MESSAGE'],
'#TITLE#' => $chat['TITLE']
)),
);
CIMNotify::Add($arMessageFields);*/
}
$pushUsers = $like;
$pushUsers[] = $message['AUTHOR_ID'];
$arPullMessage = Array(
'id' => (int)$id,
'dialogId' => 0,
'chatId' => (int)$chat['ID'],
'senderId' => (int)$userId,
'set' => (bool)$isLike,
'users' => $like
);
if ($chat['TYPE'] == IM_MESSAGE_PRIVATE)
{
$fromUserId = (int)$userId;
foreach ($relations as $rel)
{
if ($rel['USER_ID'] != $fromUserId)
{
$toUserId = (int)$rel['USER_ID'];
}
}
$dialogId = $toUserId;
\Bitrix\Pull\Event::add($fromUserId, Array(
'module_id' => 'im',
'command' => 'messageLike',
'params' => array_merge($arPullMessage, ['dialogId' => $toUserId]),
'extra' => \Bitrix\Im\Common::getPullExtra()
));
\Bitrix\Pull\Event::add($toUserId, Array(
'module_id' => 'im',
'command' => 'messageLike',
'params' => array_merge($arPullMessage, ['dialogId' => $fromUserId]),
'extra' => \Bitrix\Im\Common::getPullExtra()
));
}
else
{
$dialogId = 'chat'.$chat['ID'];
$arPullMessage['dialogId'] = $dialogId;
if ($chat['ENTITY_TYPE'] == 'LINES')
{
foreach ($relations as $rel)
{
if ($rel["EXTERNAL_AUTH_ID"] == 'imconnector')
{
unset($relations[$rel["USER_ID"]]);
}
}
}
\Bitrix\Pull\Event::add(array_keys($relations), Array(
'module_id' => 'im',
'command' => 'messageLike',
'params' => $arPullMessage,
'extra' => \Bitrix\Im\Common::getPullExtra()
));
if ($chat['TYPE'] == IM_MESSAGE_OPEN || $chat['TYPE'] == IM_MESSAGE_OPEN_LINE)
{
CPullWatch::AddToStack('IM_PUBLIC_'.$chat['ID'], Array(
'module_id' => 'im',
'command' => 'messageLike',
'params' => $arPullMessage,
'extra' => \Bitrix\Im\Common::getPullExtra()
));
}
}
foreach(GetModuleEvents("im", "OnAfterMessagesLike", true) as $arEvent)
{
ExecuteModuleEventEx($arEvent, array(array(
'DIALOG_ID' => $dialogId,
'CHAT' => $chat,
'MESSAGE' => $message,
'ACTION' => $action,
'USER_ID' => $userId,
'BY_EVENT' => $byEvent
)));
}
return $like;
}
public static function ExecCommand($id, $botId, $command, $commandParams = '', $userId = null, $byEvent = false)
{
global $USER;
$userId = is_null($userId)? $USER->GetId(): intval($userId);
if ($userId <= 0)
return false;
$messageId = intval($id);
$orm = \Bitrix\Im\Model\MessageTable::getById($messageId);
$message = $orm->fetch();
if(!$message)
{
return false;
}
$orm = \Bitrix\Im\Model\ChatTable::getById($message['CHAT_ID']);
$chat = $orm->fetch();
if (!$chat)
{
return false;
}
$relations = \CIMChat::GetRelationById($message['CHAT_ID'], false, true, false);
if (!isset($relations[$userId]))
{
return false;
}
$entityType = $chat['ENTITY_TYPE'];
$entityId = $chat['ENTITY_ID'];
if ($chat['TYPE'] != IM_MESSAGE_PRIVATE)
{
$chatId = $message['CHAT_ID'];
$messageType = $chat['TYPE'];
if ($chat['ENTITY_TYPE'] === 'LIVECHAT') // TODO finalize it
{
[$lineId, $userId] = explode("|", $chat['ENTITY_ID']);
$entityType = 'LINES';
$entityId = 'livechat|'.$lineId.'|'.$message['CHAT_ID'].'|'.$userId;
$chatLines = \Bitrix\Im\Model\ChatTable::getList(Array(
'select' => ['ID'],
'filter' => [
'=ENTITY_TYPE' => $entityType,
'=ENTITY_ID' => $entityId,
]
))->fetch();
if (!$chatLines)
{
return false;
}
$chatId = $chatLines['ID'];
$messageType = $chatLines['TYPE'];
}
$messageFields = Array(
"FROM_USER_ID" => $userId,
"TO_CHAT_ID" => $chatId,
"MESSAGE" => '/'.$command.' '.$commandParams,
);
}
else
{
$messageFields = Array(
"FROM_USER_ID" => $userId,
"TO_USER_ID" => intval($botId),
"MESSAGE" => '/'.$_POST['COMMAND'].' '.$_POST['COMMAND_PARAMS'],
);
$messageType = $relations[$userId]['MESSAGE_TYPE'];
}
$messageFields['MESSAGE_TYPE'] = $messageType;
$messageFields['CHAT_ENTITY_TYPE'] = $entityType;
$messageFields['CHAT_ENTITY_ID'] = $entityId;
$messageFields['AUTHOR_ID'] = $userId;
$messageFields['COMMAND_CONTEXT'] = 'KEYBOARD';
\Bitrix\Im\Command::onCommandAdd($messageId, $messageFields);
return true;
}
public static function UrlAttachDelete($id, $attachId = false, $userId = null)
{
if (!CModule::IncludeModule('pull'))
return false;
global $USER;
$userId = is_null($userId)? $USER->GetId(): intval($userId);
if ($userId <= 0)
return false;
$relations = CIMMessenger::GetRelationById($id);
if (!isset($relations[$userId]))
return false;
$newUrlId = Array();
if ($attachId)
{
$urlId = CIMMessageParam::Get($id, 'URL_ID');
foreach ($urlId as $value)
{
if ($value != $attachId)
{
$newUrlId[] = $value;
}
}
}
CIMMessageParam::Set($id, Array('URL_ID' => $newUrlId, 'URL_ONLY' => empty($newUrlId)? 'N': 'Y'));
CIMMessageParam::SendPull($id, Array('URL_ID', 'ATTACH', 'URL_ONLY'));
return true;
}
private static function CheckFields($arFields)
{
$messageType = $arFields['MESSAGE_TYPE'] ?? null;
$messageDate = $arFields['MESSAGE_DATE'] ?? null;
$message = $arFields['MESSAGE'] ?? null;
$system = $arFields['SYSTEM'] ?? null;
$importId = $arFields['IMPORT_ID'] ?? null;
$authorId = $arFields['AUTHOR_ID'] ?? null;
$toChatId = $arFields['TO_CHAT_ID'] ?? null;
$toUserId = $arFields['TO_USER_ID'] ?? null;
$fromUserId = $arFields['FROM_USER_ID'] ?? null;
$aMsg = array();
if (
!$messageType
|| !in_array($messageType, [IM_MESSAGE_PRIVATE, IM_MESSAGE_CHAT, IM_MESSAGE_OPEN, IM_MESSAGE_SYSTEM, IM_MESSAGE_OPEN_LINE], true)
)
{
$aMsg[] = array("id"=>"MESSAGE_TYPE", "text"=> GetMessage("IM_ERROR_MESSAGE_TYPE"));
}
else
{
if (
in_array($messageType, [IM_MESSAGE_CHAT, IM_MESSAGE_OPEN, IM_MESSAGE_OPEN_LINE], true)
&& !$system
&& (int)$toChatId <= 0
&& (int)$fromUserId <= 0
)
{
$aMsg[] = array("id"=>"TO_CHAT_ID", "text"=> GetMessage("IM_ERROR_MESSAGE_TO_FROM"));
}
if (
$messageType === IM_MESSAGE_PRIVATE
&& !(
((int)$toUserId > 0 || (int)$toChatId > 0) && (int)$fromUserId > 0
)
)
{
$aMsg[] = array("id"=>"FROM_USER_ID", "text"=> GetMessage("IM_ERROR_MESSAGE_TO_FROM"));
}
if ($messageDate && (!$GLOBALS['DB']->IsDate($messageDate, false, LANG, "FULL")))
{
$aMsg[] = array("id"=>"MESSAGE_DATE", "text"=> GetMessage("IM_ERROR_MESSAGE_DATE"));
}
if (
in_array($messageType, [IM_MESSAGE_PRIVATE, IM_MESSAGE_SYSTEM], true)
&& !((int)$toUserId > 0 || (int)$toChatId > 0)
)
{
$aMsg[] = array("id"=>"TO_USER_ID", "text"=> GetMessage("IM_ERROR_MESSAGE_TO"));
}
if (!is_null($message) && trim($message) == '')
{
$aMsg[] = array("id"=>"MESSAGE", "text"=> GetMessage("IM_ERROR_MESSAGE_TEXT"));
}
else if(is_null($message) && $messageType === IM_MESSAGE_SYSTEM && empty($arFields['PARAMS']['ATTACH']))
{
$aMsg[] = array("id"=>"MESSAGE", "text"=> GetMessage("IM_ERROR_MESSAGE_TEXT"));
}
else if(is_null($message) && empty($arFields['PARAMS']['ATTACH']) && empty($arFields['PARAMS']['FILE_ID']))
{
$aMsg[] = array("id"=>"MESSAGE", "text"=> GetMessage("IM_ERROR_MESSAGE_TEXT"));
}
if ($messageType === IM_MESSAGE_PRIVATE && $authorId && (int)$authorId <= 0)
{
$aMsg[] = ["id" => "AUTHOR_ID", "text" => GetMessage("IM_ERROR_MESSAGE_AUTHOR")];
}
if ($importId && (int)$importId <= 0)
{
$aMsg[] = ["id" => "IMPORT_ID", "text" => GetMessage("IM_ERROR_IMPORT_ID")];
}
if ($messageType === IM_MESSAGE_SYSTEM)
{
if (isset($arFields["NOTIFY_MODULE"]) && trim($arFields["NOTIFY_MODULE"]) == '')
{
$aMsg[] = ["id" => "NOTIFY_MODULE", "text" => GetMessage("IM_ERROR_NOTIFY_MODULE")];
}
if (isset($arFields["NOTIFY_EVENT"]) && trim($arFields["NOTIFY_EVENT"]) == '')
{
$aMsg[] = ["id" => "NOTIFY_EVENT", "text" => GetMessage("IM_ERROR_NOTIFY_EVENT")];
}
if (isset($arFields["NOTIFY_TYPE"]) && !in_array($arFields["NOTIFY_TYPE"], [IM_NOTIFY_CONFIRM, IM_NOTIFY_SYSTEM, IM_NOTIFY_FROM], true))
{
$aMsg[] = ["id" => "NOTIFY_TYPE", "text" => GetMessage("IM_ERROR_NOTIFY_TYPE")];
}
if (isset($arFields["NOTIFY_TYPE"]) && $arFields["NOTIFY_TYPE"] == IM_NOTIFY_CONFIRM)
{
if(isset($arFields["NOTIFY_BUTTONS"]) && !is_array($arFields["NOTIFY_BUTTONS"]))
{
$aMsg[] = ["id" => "NOTIFY_BUTTONS", "text" => GetMessage("IM_ERROR_NOTIFY_BUTTON")];
}
}
else if(isset($arFields["NOTIFY_TYPE"]) && $arFields["NOTIFY_TYPE"] == IM_NOTIFY_FROM)
{
if (!$fromUserId || (int)$fromUserId <= 0)
{
$aMsg[] = ["id" => "FROM_USER_ID", "text" => GetMessage("IM_ERROR_MESSAGE_FROM")];
}
}
}
}
if(!empty($aMsg))
{
$e = new CAdminException($aMsg);
$GLOBALS["APPLICATION"]->ThrowException($e);
return false;
}
return true;
}
public static function GetById($ID, $params = Array())
{
global $DB;
$ID = intval($ID);
$strSql = "
SELECT
DISTINCT M.*,
".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE,
C.TYPE MESSAGE_TYPE,
C.AUTHOR_ID CHAT_AUTHOR_ID,
C.ENTITY_TYPE CHAT_ENTITY_TYPE,
C.ENTITY_ID CHAT_ENTITY_ID,
C.PARENT_ID CHAT_PARENT_ID,
C.PARENT_MID CHAT_PARENT_MID,
C.ENTITY_DATA_1 CHAT_ENTITY_DATA_1,
C.ENTITY_DATA_2 CHAT_ENTITY_DATA_2,
C.ENTITY_DATA_3 CHAT_ENTITY_DATA_3
FROM b_im_message M
LEFT JOIN b_im_chat C ON M.CHAT_ID = C.ID
WHERE M.ID = ".$ID;
$dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
if ($arRes = $dbRes->Fetch())
{
$param = CIMMessageParam::Get($arRes['ID']);
$arRes['PARAMS'] = $param? $param: Array();
}
if ($arRes && ($params['WITH_FILES'] ?? null) === 'Y')
{
$arFiles = Array();
if (isset($arRes['PARAMS']['FILE_ID']))
{
foreach ($arRes['PARAMS']['FILE_ID'] as $fileId)
{
$arFiles[$fileId] = $fileId;
}
}
$arRes['FILES'] = CIMDisk::GetFiles($arRes['CHAT_ID'], $arFiles, false);
}
return $arRes;
}
public static function GetRelationById($ID)
{
global $DB;
$ID = intval($ID);
$arResult = Array();
$strSql = "
SELECT
R.USER_ID, U.EXTERNAL_AUTH_ID, M.CHAT_ID
FROM b_im_message M
LEFT JOIN b_im_relation R ON M.CHAT_ID = R.CHAT_ID
LEFT JOIN b_user U ON U.ID = R.USER_ID
WHERE M.ID = ".$ID;
$dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
while ($arRes = $dbRes->Fetch())
$arResult[$arRes['USER_ID']] = $arRes;
return $arResult;
}
public static function CheckXmppStatusOnline()
{
If (IsModuleInstalled('xmpp'))
{
$LastActivityDate = CUserOptions::GetOption('xmpp', 'LastActivityDate');
if (intval($LastActivityDate)+60 > time())
return true;
}
return false;
}
public static function CheckEnableOpenChat()
{
return COption::GetOptionString('im', 'open_chat_enable');
}
public static function CheckNetwork()
{
return COption::GetOptionString('bitrix24', 'network', 'N') == 'Y';
}
public static function CheckNetwork2()
{
if (!CModule::IncludeModule('socialservices'))
return false;
$network = new \Bitrix\Socialservices\Network();
return $network->isEnabled();
}
public static function CheckInstallDesktop()
{
$status = CIMStatus::GetStatus($userId);
if ($status['DESKTOP_LAST_DATE'])
return true;
else
return false;
}
public static function EnableInVersion($version)
{
$version = intval($version);
$currentVersion = intval(CUserOptions::GetOption('im', 'DesktopVersionApi', 0));
return $currentVersion >= $version;
}
public static function IsDesktopEnvironment()
{
$userAgent = \Bitrix\Main\Context::getCurrent()->getServer()->get("HTTP_USER_AGENT");
if (mb_strpos($userAgent, 'BitrixDesktop') === false)
{
return false;
}
return true;
}
public static function SetDesktopVersion($version)
{
global $USER;
$version = intval($version);
$userId = intval($USER->GetId());
if ($userId <= 0)
return false;
$currentVersion = self::GetDesktopVersion();
if ($currentVersion !== $version)
{
CUserOptions::SetOption('im', 'DesktopVersionApi', $version, false, $userId);
}
return $version;
}
public static function GetDesktopVersion()
{
$version = CUserOptions::GetOption('im', 'DesktopVersionApi', 0);
return (int)$version;
}
public static function SetDesktopLastActivityDate($timestamp, $deviceType = IM_DESKTOP_WINDOWS, $userId = false)
{
if ($timestamp instanceof \Bitrix\Main\Type\DateTime)
{
$timestamp = $timestamp->getTimestamp();
}
else
{
$timestamp = (int)$timestamp;
}
CIMStatus::Set($userId, Array('DESKTOP_LAST_DATE' => \Bitrix\Main\Type\DateTime::createFromTimestamp($timestamp)));
if ($deviceType === IM_DESKTOP_MAC)
{
$lastTimestamp = (int)CUserOptions::GetOption('im', 'MacLastActivityDate', -1, $userId);
if ($lastTimestamp+86400*30 < time())
{
CUserOptions::SetOption('im', 'MacLastActivityDate', $timestamp, false, $userId);
}
}
elseif ($deviceType === IM_DESKTOP_LINUX)
{
$lastTimestamp = (int)CUserOptions::GetOption('im', 'LinuxLastActivityDate', -1, $userId);
if ($lastTimestamp+86400*30 < time())
{
CUserOptions::SetOption('im', 'LinuxLastActivityDate', $timestamp, false, $userId);
}
}
else
{
$lastTimestamp = (int)CUserOptions::GetOption('im', 'WindowsLastActivityDate', -1, $userId);
if ($lastTimestamp+86400*30 < time())
{
CUserOptions::SetOption('im', 'WindowsLastActivityDate', $timestamp, false, $userId);
}
}
}
public static function CheckPhoneStatus()
{
if(!\Bitrix\Main\Loader::includeModule('voximplant') || !\Bitrix\Main\Loader::includeModule('pull'))
return false;
return CPullOptions::GetNginxStatus() && (!IsModuleInstalled('extranet') || CModule::IncludeModule('extranet') && CExtranet::IsIntranetUser());
}
public static function CanUserCallCrmNumber()
{
if(!\Bitrix\Main\Loader::includeModule('voximplant'))
return false;
$userPermissions = \Bitrix\Voximplant\Security\Permissions::createWithCurrentUser();
return $userPermissions->canPerform(
\Bitrix\Voximplant\Security\Permissions::ENTITY_CALL,
\Bitrix\Voximplant\Security\Permissions::ACTION_PERFORM,
\Bitrix\Voximplant\Security\Permissions::PERMISSION_CALL_CRM
);
}
public static function CanUserCallUserNumber()
{
if(!\Bitrix\Main\Loader::includeModule('voximplant'))
return false;
$userPermissions = \Bitrix\Voximplant\Security\Permissions::createWithCurrentUser();
return $userPermissions->canPerform(
\Bitrix\Voximplant\Security\Permissions::ENTITY_CALL,
\Bitrix\Voximplant\Security\Permissions::ACTION_PERFORM,
\Bitrix\Voximplant\Security\Permissions::PERMISSION_CALL_USERS
);
}
public static function CanUserCallAnyNumber()
{
if(!\Bitrix\Main\Loader::includeModule('voximplant'))
return false;
$userPermissions = \Bitrix\Voximplant\Security\Permissions::createWithCurrentUser();
return $userPermissions->canPerform(
\Bitrix\Voximplant\Security\Permissions::ENTITY_CALL,
\Bitrix\Voximplant\Security\Permissions::ACTION_PERFORM,
\Bitrix\Voximplant\Security\Permissions::PERMISSION_ANY
);
}
public static function CanUserPerformCalls()
{
if(!\Bitrix\Main\Loader::includeModule('voximplant'))
return false;
$userPermissions = \Bitrix\Voximplant\Security\Permissions::createWithCurrentUser();
return $userPermissions->canPerform(\Bitrix\Voximplant\Security\Permissions::ENTITY_CALL, \Bitrix\Voximplant\Security\Permissions::ACTION_PERFORM);
}
public static function CanInterceptCall()
{
if(!\Bitrix\Main\Loader::includeModule('voximplant'))
return false;
return \Bitrix\Voximplant\Limits::canInterceptCall();
}
public static function GetCallCardRestApps()
{
if(!\Bitrix\Main\Loader::includeModule('rest'))
return array();
if(!\Bitrix\Main\Loader::includeModule('voximplant'))
return array();
$result = array();
if(!defined('Bitrix\Voximplant\Rest\Helper::PLACEMENT_CALL_CARD'))
return array();
$placementId = Bitrix\Voximplant\Rest\Helper::PLACEMENT_CALL_CARD;
$cursor = \Bitrix\Rest\PlacementTable::getHandlersList($placementId);
foreach($cursor as $row)
{
$result[] = array(
'id' => $row['ID'],
'name' => $row['TITLE'] ?: $row['APP_NAME']
);
}
return $result;
}
public static function GetTelephonyAvailableLines($userId = null)
{
if(!\Bitrix\Main\Loader::includeModule('voximplant'))
return array();
if(is_null($userId))
$userId = self::GetCurrentUserId();
return \CVoxImplantUser::getAllowedLines($userId);
}
public static function GetDefaultTelephonyLine($userId = null)
{
if(!\Bitrix\Main\Loader::includeModule('voximplant'))
return array();
if(is_null($userId))
$userId = self::GetCurrentUserId();
return CVoxImplantUser::getUserOutgoingLine($userId);
}
public static function CheckDesktopStatusOnline($userId = null)
{
global $USER;
if (is_null($userId))
{
$userId = $USER->GetId();
}
$userId = intval($userId);
if ($userId <= 0)
{
return false;
}
$maxOnlineTime = 120;
if (CModule::IncludeModule('pull') && CPullOptions::GetNginxStatus())
{
$maxOnlineTime = self::GetSessionLifeTime();
}
$status = CIMStatus::GetStatus($userId);
$desktopLastDateStatus = $status['DESKTOP_LAST_DATE'] ?? null;
if (
$desktopLastDateStatus instanceof \Bitrix\Main\Type\DateTime
&& $desktopLastDateStatus->getTimestamp() + $maxOnlineTime + 60 > time()
)
{
return true;
}
return false;
}
public static function GetDesktopStatusOnline($userId = null)
{
global $USER;
if (is_null($userId))
{
$userId = $USER->GetId();
}
$userId = intval($userId);
if ($userId <= 0)
{
return 0;
}
$status = CIMStatus::GetStatus($userId);
if ($status['DESKTOP_LAST_DATE'] instanceof \Bitrix\Main\Type\DateTime)
{
return $status['DESKTOP_LAST_DATE']->getTimestamp();
}
return 0;
}
public static function SetDesktopStatusOnline($userId = null, $cache = true)
{
global $USER;
if (is_null($userId))
$userId = $USER->GetId();
$userId = intval($userId);
if ($userId <= 0)
return false;
if ($cache && $userId == $USER->GetId())
{
if (
isset(\Bitrix\Main\Application::getInstance()->getKernelSession()['IM']['SET_DESKTOP_ACTIVITY'])
&& intval(\Bitrix\Main\Application::getInstance()->getKernelSession()['IM']['SET_DESKTOP_ACTIVITY'])+300 > time()
)
{
return false;
}
\Bitrix\Main\Application::getInstance()->getKernelSession()['IM']['SET_DESKTOP_ACTIVITY'] = time();
}
$userAgent = \Bitrix\Main\Context::getCurrent()->getRequest()->getUserAgent();
if (mb_strpos(mb_strtolower($userAgent), "windows") !== false)
{
$deviceType = IM_DESKTOP_WINDOWS;
}
elseif (mb_strpos(mb_strtolower($userAgent), "macintosh") !== false)
{
$deviceType = IM_DESKTOP_MAC;
}
elseif (mb_strpos(mb_strtolower($userAgent), "linux") !== false)
{
$deviceType = IM_DESKTOP_LINUX;
}
$time = time();
\CIMMessenger::SetDesktopLastActivityDate($time, $deviceType, $userId);
if (CModule::IncludeModule("pull"))
{
if ($cache && $userId == $USER->GetId())
{
if (
isset(\Bitrix\Main\Application::getInstance()->getKernelSession()['IM']['SET_DESKTOP_ACTIVITY_PULL'])
&& intval(\Bitrix\Main\Application::getInstance()->getKernelSession()['IM']['SET_DESKTOP_ACTIVITY_PULL'])+3600 > $time
)
{
return false;
}
\Bitrix\Main\Application::getInstance()->getKernelSession()['IM']['SET_DESKTOP_ACTIVITY_PULL'] = $time;
}
\Bitrix\Pull\Event::add($userId, Array(
'module_id' => 'im',
'expiry' => 3600,
'command' => 'desktopOnline',
'params' => Array(
'version' => CIMMessenger::GetDesktopVersion()
),
'extra' => \Bitrix\Im\Common::getPullExtra()
));
}
return $time;
}
public static function SetDesktopStatusOffline($userId = null)
{
global $USER;
if (is_null($userId))
$userId = $USER->GetId();
$userId = intval($userId);
if ($userId <= 0)
return false;
unset(\Bitrix\Main\Application::getInstance()->getKernelSession()['IM']['SET_DESKTOP_ACTIVITY']);
unset(\Bitrix\Main\Application::getInstance()->getKernelSession()['IM']['SET_DESKTOP_ACTIVITY_PULL']);
CIMStatus::Set($userId, Array('DESKTOP_LAST_DATE' => null));
if (CModule::IncludeModule("pull"))
{
\Bitrix\Pull\Event::add($userId, Array(
'module_id' => 'im',
'expiry' => 3600,
'command' => 'desktopOffline',
'params' => Array(),
'extra' => \Bitrix\Im\Common::getPullExtra()
));
}
return true;
}
public static function GetSettings($userId = false)
{
$arSettings = CIMSettings::Get($userId);
return $arSettings['settings'];
}
public static function GetFormatFilesMessageOut($files)
{
if (!is_array($files) || count($files) <= 0)
return false;
$messageFiles = '';
$serverName = (CMain::IsHTTPS() ? "https" : "http")."://".((defined("SITE_SERVER_NAME") && SITE_SERVER_NAME <> '') ? SITE_SERVER_NAME : COption::GetOptionString("main", "server_name", ""));
foreach ($files as $fileId => $fileData)
{
if ($fileData['status'] == 'done')
{
$fileElement = $fileData['name'].' ('.CFile::FormatSize($fileData['size']).")\n".
GetMessage('IM_MESSAGE_FILE_DOWN').' '.$serverName.$fileData['urlDownload']."\n";
$messageFiles = $messageFiles <> ''? $messageFiles."\n".$fileElement: $fileElement;
}
}
return $messageFiles;
}
public static function GetSessionLifeTime()
{
global $USER;
$sessTimeout = CUser::GetSecondsForLimitOnline();
if ($USER instanceof CUser)
{
$arPolicy = $USER->GetSecurityPolicy();
if($arPolicy["SESSION_TIMEOUT"] > 0)
{
$sessTimeout = min($arPolicy["SESSION_TIMEOUT"]*60, $sessTimeout);
}
}
$sessTimeout = intval($sessTimeout);
if ($sessTimeout <= 120)
{
$sessTimeout = 100;
}
return intval($sessTimeout);
}
public static function GetUnreadCounter($userId)
{
//todo return counters for user
return (new \Bitrix\Im\V2\Message\CounterService($userId))->getForNotifyChat();
//$count = 0;
/*$userId = intval($userId);
if ($userId <= 0)
return $count;
global $DB;
$strSql ="
SELECT M.ID, M.NOTIFY_TYPE, M.NOTIFY_TAG
FROM b_im_message M
INNER JOIN b_im_relation R1 ON M.ID > R1.LAST_ID AND M.CHAT_ID = R1.CHAT_ID AND R1.USER_ID != M.AUTHOR_ID
WHERE R1.USER_ID = ".$userId." AND R1.STATUS < ".IM_STATUS_READ."
";
$dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
$arGroupNotify = Array();
while ($arRes = $dbRes->Fetch())
{
if ($arRes['NOTIFY_TYPE'] == 2 && $arRes['NOTIFY_TAG'] != '')
{
if (!isset($arGroupNotify[$arRes['NOTIFY_TAG']]))
{
$arGroupNotify[$arRes['NOTIFY_TAG']] = true;
$count++;
}
}
else
$count++;
}*/
//return $count;
}
public static function GetMessageCounter($userId, $arMessages = Array())
{
$count = 0;
if (isset($arMessages['message']))
{
foreach ($arMessages['message'] as $value)
$count += isset($value['counter'])? $value['counter']: 1;
}
else
{
$count = CIMMessenger::SpeedFileGet($userId, IM_SPEED_MESSAGE);
}
return intval($count);
}
private static function GetReasonForMessageSendError($type = IM_MESSAGE_PRIVATE, $reason = '')
{
if (!empty($reason))
{
$CBXSanitizer = new CBXSanitizer;
$CBXSanitizer->AddTags(array(
'a' => array('href','style', 'target'),
'b' => array(), 'u' => array(),
'i' => array(), 'br' => array(),
'span' => array('style'),
));
$reason = $CBXSanitizer->SanitizeHtml($reason);
}
else
{
if ($type == IM_MESSAGE_PRIVATE)
{
$reason = GetMessage("IM_ERROR_MESSAGE_CANCELED");
}
else if ($type == IM_MESSAGE_SYSTEM)
{
$reason = GetMessage("IM_ERROR_NOTIFY_CANCELED");
}
else
{
$reason = GetMessage("IM_ERROR_GROUP_CANCELED");
}
}
return $reason;
}
public static function SpeedFileCreate($userID, $value, $type = IM_SPEED_MESSAGE)
{
global $CACHE_MANAGER;
$userID = intval($userID);
if ($userID <= 0 || !in_array($type, Array(IM_SPEED_NOTIFY, IM_SPEED_MESSAGE, IM_SPEED_GROUP)))
return false;
$CACHE_MANAGER->Clean("im_csf_v2_".$type.'_'.$userID);
$CACHE_MANAGER->Read(86400*30, "im_csf_v2_".$type.'_'.$userID);
$CACHE_MANAGER->Set("im_csf_v2_".$type.'_'.$userID, $value);
}
public static function SpeedFileDelete($userID, $type = IM_SPEED_MESSAGE)
{
global $CACHE_MANAGER;
$userID = intval($userID);
if ($userID <= 0 || !in_array($type, Array(IM_SPEED_NOTIFY, IM_SPEED_MESSAGE, IM_SPEED_GROUP)))
return false;
$CACHE_MANAGER->Clean("im_csf_v2_".$type.'_'.$userID);
}
public static function SpeedFileExists($userID, $type = IM_SPEED_MESSAGE)
{
global $CACHE_MANAGER;
$userID = intval($userID);
if ($userID <= 0 || !in_array($type, Array(IM_SPEED_NOTIFY, IM_SPEED_MESSAGE, IM_SPEED_GROUP)))
return false;
$result = $CACHE_MANAGER->Read(86400*30, "im_csf_v2_".$type.'_'.$userID);
if ($result)
$result = $CACHE_MANAGER->Get("im_csf_v2_".$type.'_'.$userID) === false? false: true;
return $result;
}
public static function SpeedFileGet($userID, $type = IM_SPEED_MESSAGE)
{
global $CACHE_MANAGER;
$userID = intval($userID);
if ($userID <= 0 || !in_array($type, Array(IM_SPEED_NOTIFY, IM_SPEED_MESSAGE, IM_SPEED_GROUP)))
return false;
$CACHE_MANAGER->Read(86400*30, "im_csf_v2_".$type.'_'.$userID);
return $CACHE_MANAGER->Get("im_csf_v2_".$type.'_'.$userID);
}
public static function GetTemplateJS($arParams, $arTemplate)
{
global $USER;
$ppStatus = 'false';
$ppServerStatus = 'false';
$updateStateInterval = 'auto';
if (CModule::IncludeModule("pull"))
{
$ppStatus = CPullOptions::ModuleEnable()? 'true': 'false';
$ppServerStatus = CPullOptions::GetNginxStatus()? 'true': 'false';
$updateStateInterval = CPullOptions::GetNginxStatus()? self::GetSessionLifeTime(): 80;
if ($updateStateInterval > 100)
{
if ($updateStateInterval > 3600)
$updateStateInterval = 3600;
if (in_array($arTemplate["CONTEXT"], Array("POPUP-FULLSCREEN", "MESSENGER")))
$updateStateInterval = $updateStateInterval-60;
else
$updateStateInterval = intval($updateStateInterval/2)-10;
}
}
$diskStatus = CIMDisk::Enabled();
$diskExternalLinkStatus = CIMDisk::EnabledExternalLink();
$phoneCanPerformCalls = false;
$phoneDeviceActive = false;
$phoneCanCallUserNumber = false;
$phoneEnabled = false;
$chatExtendShowHistory = \COption::GetOptionInt('im', 'chat_extend_show_history');
$contactListLoad = \COption::GetOptionInt('im', 'contact_list_load');
$contactListBirthday = \COption::GetOptionString('im', 'contact_list_birthday');
$isFullTextEnabled = \Bitrix\Im\Model\MessageIndexTable::getEntity()->fullTextIndexEnabled("SEARCH_CONTENT");
$fullTextMinSizeToken = \Bitrix\Main\ORM\Query\Filter\Helper::getMinTokenSize();
$phoneCanInterceptCall = self::CanInterceptCall();
if ($arTemplate['INIT'] == 'Y')
{
$phoneEnabled = self::CheckPhoneStatus();
if ($phoneEnabled && CModule::IncludeModule('voximplant'))
{
$phoneCanPerformCalls = self::CanUserPerformCalls();
$phoneDeviceActive = CVoxImplantUser::GetPhoneActive($USER->GetId());
$phoneCanCallUserNumber = self::CanUserCallUserNumber();
}
}
$counters = \Bitrix\Im\Counter::get(null, ['JSON' => 'Y']);
$counters['type']['mail'] = isset($arParams['MAIL_COUNTER']) ? (int)$arParams['MAIL_COUNTER'] : 0;
$crmPath = Array();
$olConfig = Array();
$businessUsers = false;
if (\Bitrix\Main\Loader::includeModule('crm'))
{
$crmPath['LEAD'] = \Bitrix\Im\Integration\Crm\Common::getLink('LEAD');
$crmPath['CONTACT'] = \Bitrix\Im\Integration\Crm\Common::getLink('CONTACT');
$crmPath['COMPANY'] = \Bitrix\Im\Integration\Crm\Common::getLink('COMPANY');
$crmPath['DEAL'] = \Bitrix\Im\Integration\Crm\Common::getLink('DEAL');
}
if (\Bitrix\Main\Loader::includeModule('imopenlines'))
{
$olConfig['canDeleteMessage'] = str_replace('.', '_', \Bitrix\Imopenlines\Connector::getListCanDeleteMessage());
$olConfig['canDeleteOwnMessage'] = str_replace('.', '_', \Bitrix\Imopenlines\Connector::getListCanDeleteOwnMessage());
$olConfig['canUpdateOwnMessage'] = str_replace('.', '_', \Bitrix\Imopenlines\Connector::getListCanUpdateOwnMessage());
$olConfig['queue'] = Array();
foreach (\Bitrix\ImOpenLines\Config::getQueueList($USER->GetID()) as $config)
{
$olConfig['queue'][] = array_change_key_case($config, CASE_LOWER);
}
if (method_exists(\Bitrix\ImOpenLines\Config::class, 'getAllLinesSettings'))
{
foreach (\Bitrix\ImOpenLines\Config::getAllLinesSettings(['CONFIRM_CLOSE']) as $config)
{
$olConfig['settings'][$config['ID']] = array_change_key_case($config, CASE_LOWER);
}
}
$olConfig['canUseVoteHead'] = Imopenlines\Limit::canUseVoteHead();
$olConfig['canJoinChatUser'] = Imopenlines\Limit::canJoinChatUser();
$olConfig['canTransferToLine'] = Imopenlines\Limit::canTransferToLine();
}
$bitrix24blocked = false;
$bitrix24Enabled = false;
$bitrixPaid = true;
if (\Bitrix\Main\Loader::includeModule('bitrix24'))
{
$bitrix24Enabled = true;
$bitrixPaid = CBitrix24::IsLicensePaid() || CBitrix24::IsNfrLicense();
if (CIMMessenger::IsBitrix24UserRestricted())
{
$bitrix24blocked = \Bitrix\Bitrix24\Limits\User::getUserRestrictedHelperCode();
}
}
$userBirthday = \Bitrix\Im\Integration\Intranet\User::getBirthdayForToday();
$pathToIm = isset($arTemplate['PATH_TO_IM']) ? $arTemplate['PATH_TO_IM'] : '';
$pathToCall = isset($arTemplate['PATH_TO_CALL']) ? $arTemplate['PATH_TO_CALL'] : '';
$pathToFile = isset($arTemplate['PATH_TO_FILE']) ? $arTemplate['PATH_TO_FILE'] : '';
$pathToLf = isset($arTemplate['PATH_TO_LF']) ? $arTemplate['PATH_TO_LF'] : '/';
$pathToDisk = Array(
'localFile' => \CIMDisk::GetLocalDiskFilePath(),
);
$recentLastUpdate = (new \Bitrix\Main\Type\DateTime())->format(\DateTimeInterface::RFC3339);
$recent = \Bitrix\Im\Recent::getList(null, [
'SKIP_NOTIFICATION' => 'Y',
'SKIP_OPENLINES' => 'Y',
'JSON' => 'Y',
'GET_ORIGINAL_TEXT' => 'Y',
//'SHORT_INFO' => 'Y',
]);
$iframeRequest = $_REQUEST['IFRAME'] ?? null;
$iframeTypeRequest = $_REQUEST['IFRAME_TYPE'] ?? null;
$imMenuRequest = $_REQUEST['IM_MENU'] ?? null;
$imRecentRequest = $_REQUEST['IM_RECENT'] ?? null;
$sJS = "
BX.ready(function() {
BXIM = new BX.IM(BX('bx-notifier-panel'), {
'init': ".($arTemplate['INIT'] == 'Y'? 'true': 'false').",
'context': '".$arTemplate["CONTEXT"]."',
'design': '".$arTemplate["DESIGN"]."',
'colors': ".(\Bitrix\Im\Color::isEnabled()? \Bitrix\Im\Common::objectEncode(\Bitrix\Im\Color::getSafeColorNames()): 'false').",
'colorsHex': ".\Bitrix\Im\Common::objectEncode(\Bitrix\Im\Color::getSafeColors()).",
'chatCounters': ".\Bitrix\Im\Common::objectEncode($counters, true).",
'counters': ".(empty($arTemplate['COUNTERS'])? '{}': \Bitrix\Im\Common::objectEncode($arTemplate['COUNTERS'])).",
'ppStatus': ".$ppStatus.",
'ppServerStatus': ".$ppServerStatus.",
'updateStateInterval': '".$updateStateInterval."',
'openChatEnable': ".(CIMMessenger::CheckEnableOpenChat()? 'true': 'false').",
'xmppStatus': ".(CIMMessenger::CheckXmppStatusOnline()? 'true': 'false').",
'isAdmin': ".(self::IsAdmin()? 'true': 'false').",
'canInvite': ".(\Bitrix\Im\Integration\Intranet\User::canInvite()? 'true': 'false').",
'isLinesOperator': 'true',
'isUtfMode': ".(\Bitrix\Main\Application::getInstance()->isUtfMode()? 'true': 'false').",
'bitrixNetwork': ".(CIMMessenger::CheckNetwork()? 'true': 'false').",
'bitrix24': ".($bitrix24Enabled? 'true': 'false').",
'bitrix24blocked': ".($bitrix24blocked? $bitrix24blocked: 'false').",
'bitrix24net': ".(IsModuleInstalled('b24network')? 'true': 'false').",
'bitrixPaid': ".($bitrixPaid? 'true': 'false').",
'bitrixIntranet': ".(IsModuleInstalled('intranet')? 'true': 'false').",
'bitrixXmpp': ".(IsModuleInstalled('xmpp')? 'true': 'false').",
'bitrixMobile': ".(IsModuleInstalled('mobile')? 'true': 'false').",
'bitrixOpenLines': ".(IsModuleInstalled('imopenlines')? 'true': 'false').",
'bitrixCrm': ".(IsModuleInstalled('crm')? 'true': 'false').",
'desktop': ".($arTemplate["DESKTOP"] ?? 'false').",
'desktopStatus': ".(CIMMessenger::CheckDesktopStatusOnline()? 'true': 'false').",
'desktopVersion': ".CIMMessenger::GetDesktopVersion().",
'desktopLinkOpen': ".($arTemplate["DESKTOP_LINK_OPEN"] ?? 'false').",
'language': '".LANGUAGE_ID."',
'loggerConfig': ".\Bitrix\Im\Common::objectEncode(\Bitrix\Im\Settings::getLoggerConfig(), true).",
'broadcastingEnabled': ".\Bitrix\Im\Common::objectEncode(\Bitrix\Im\Settings::isBroadcastingEnabled(), true).",
'tooltipShowed': ".\Bitrix\Im\Common::objectEncode(CUserOptions::GetOption('im', 'tooltipShowed', array())).",
'limit': ".(empty($arTemplate['LIMIT'])? 'false': \Bitrix\Im\Common::objectEncode($arTemplate["LIMIT"])).",
'promo': ".(empty($arTemplate['PROMO'])? '[]': \Bitrix\Im\Common::objectEncode($arTemplate["PROMO"])).",
'bot': ".(empty($arTemplate['BOT'])? '{}': \Bitrix\Im\Common::objectEncode($arTemplate["BOT"])).",
'textareaIcon': ".(empty($arTemplate['TEXTAREA_ICON'])? '{}': \Bitrix\Im\Common::objectEncode($arTemplate["TEXTAREA_ICON"])).",
'command': ".(empty($arTemplate['COMMAND'])? '[]': \Bitrix\Im\Common::objectEncode($arTemplate["COMMAND"])).",
'smile': ".\Bitrix\Im\Common::objectEncode($arTemplate["SMILE"]).",
'smileSet': ".\Bitrix\Im\Common::objectEncode($arTemplate["SMILE_SET"]).",
'settings': ".\Bitrix\Im\Common::objectEncode($arTemplate['SETTINGS']).",
'settingsNotifyBlocked': ".(empty($arTemplate['SETTINGS_NOTIFY_BLOCKED'])? '{}': \Bitrix\Im\Common::objectEncode($arTemplate['SETTINGS_NOTIFY_BLOCKED'])).",
'recent': ".\Bitrix\Im\Common::objectEncode($recent, true).",
'recentLastUpdate': '".$recentLastUpdate."',
'businessUsers': ".($businessUsers === false? 'false': (empty($businessUsers)? '{}': \Bitrix\Im\Common::objectEncode($businessUsers))).",
'userChatOptions': ".\Bitrix\Im\Common::objectEncode(CIMChat::GetChatOptions()).",
'historyOptions' : ".\Bitrix\Im\Common::objectEncode(['fullTextEnabled' => $isFullTextEnabled, 'ftMinSizeToken' => $fullTextMinSizeToken]).",
'openMessenger' : ".(isset($_REQUEST['IM_DIALOG'])? "'".CUtil::JSEscape(htmlspecialcharsbx($_REQUEST['IM_DIALOG']))."'": 'false').",
'openHistory' : ".(isset($_REQUEST['IM_HISTORY'])? "'".CUtil::JSEscape(htmlspecialcharsbx($_REQUEST['IM_HISTORY']))."'": 'false').",
'openNotify' : ".(isset($_GET['IM_NOTIFY']) && $_GET['IM_NOTIFY'] == 'Y'? 'true': 'false').",
'openSettings' : ".(isset($_GET['IM_SETTINGS'])? $_GET['IM_SETTINGS'] == 'Y'? "'true'": "'".CUtil::JSEscape(htmlspecialcharsbx($_GET['IM_SETTINGS']))."'": 'false').",
'externalRecentList' : '".(isset($arTemplate['EXTERNAL_RECENT_LIST'])?$arTemplate['EXTERNAL_RECENT_LIST']: '')."',
'generalChatId': ".CIMChat::GetGeneralChatId().",
'canSendMessageGeneralChat': ".(CIMChat::CanSendMessageToGeneralChat($USER->GetID())? 'true': 'false').",
'debug': ".(defined('IM_DEBUG')? 'true': 'false').",
'next': ".(defined('IM_NEXT')? 'true': 'false').",
'betaAvailable': ".(\Bitrix\Im\Settings::isBetaAvailable()? 'true': 'false').",
'userId': ".$USER->GetID().",
'userEmail': '".CUtil::JSEscape($USER->GetEmail())."',
'userColor': '".\Bitrix\Im\Color::getCode(\Bitrix\Im\User::getInstance()->getColor())."',
'userGender': '".\Bitrix\Im\User::getInstance()->getGender()."',
'userExtranet': ".(\Bitrix\Im\User::getInstance()->isExtranet()? 'true': 'false').",
'user': ".($arTemplate['CURRENT_USER']? \Bitrix\Im\Common::objectEncode($arTemplate['CURRENT_USER']): '{}').",
'userBirthday': ".(!empty($userBirthday)? \Bitrix\Im\Common::objectEncode($userBirthday): '[]').",
'webrtc': {
'turnServer' : '".CUtil::JSEscape($arTemplate['TURN_SERVER'])."',
'turnServerFirefox' : '".CUtil::JSEscape($arTemplate['TURN_SERVER_FIREFOX'])."',
'turnServerLogin' : '".CUtil::JSEscape($arTemplate['TURN_SERVER_LOGIN'])."',
'turnServerPassword' : '".CUtil::JSEscape($arTemplate['TURN_SERVER_PASSWORD'])."',
'mobileSupport': false,
'phoneEnabled': ".($phoneEnabled? 'true': 'false').",
'phoneDeviceActive': '".($phoneDeviceActive? 'Y': 'N')."',
'phoneCanPerformCalls': '".($phoneCanPerformCalls? 'Y': 'N')."',
'phoneCanCallUserNumber': '".($phoneCanCallUserNumber? 'Y': 'N')."',
'phoneCanInterceptCall': ".($phoneCanInterceptCall? 'true': 'false').",
'phoneCallCardRestApps': ".\Bitrix\Im\Common::objectEncode(self::GetCallCardRestApps()).",
'phoneDefaultLineId': '".self::GetDefaultTelephonyLine()."',
'availableLines': ".\Bitrix\Im\Common::objectEncode(self::GetTelephonyAvailableLines()).",
'formatRecordDate': '".\Bitrix\Main\Context::getCurrent()->getCulture()->getShortDateFormat()."'
},
'openlines': ".\Bitrix\Im\Common::objectEncode($olConfig).",
'options': {'contactListLoad' : ".($contactListLoad? 'true': 'false').", 'contactListBirthday' : '".$contactListBirthday."', 'chatExtendShowHistory' : ".($chatExtendShowHistory? 'true': 'false').", 'frameMode': ".($iframeRequest === 'Y'? 'true': 'false').", 'frameType': '".($iframeTypeRequest === 'SIDE_SLIDER'? 'SIDE_SLIDER': 'NONE')."', 'showRecent': ".($imRecentRequest === 'N'? 'false': 'true').", 'showMenu': ".($imMenuRequest === 'N'? 'false': 'true')."},
'disk': {'enable' : ".($diskStatus? 'true': 'false').", 'external' : ".($diskExternalLinkStatus? 'true': 'false')."},
'zoomStatus': {'active' : ".(\Bitrix\Im\Call\Integration\Zoom::isActive()? 'true': 'false').", 'enabled' : ".(\Bitrix\Im\Call\Integration\Zoom::isAvailable()? 'true': 'false').", 'connected' : ".(\Bitrix\Im\Call\Integration\Zoom::isConnected($USER->GetID())? 'true': 'false')."},
'path' : {'lf' : '".CUtil::JSEscape($pathToLf)."', 'profile' : '".CUtil::JSEscape($arTemplate['PATH_TO_USER_PROFILE'])."', 'profileTemplate' : '".CUtil::JSEscape($arTemplate['PATH_TO_USER_PROFILE_TEMPLATE'])."', 'mail' : '".CUtil::JSEscape($arTemplate['PATH_TO_USER_MAIL'])."', 'im': '".CUtil::JSEscape($pathToIm)."', 'call': '".CUtil::JSEscape($pathToCall)."', 'file': '".CUtil::JSEscape($pathToFile)."', 'crm' : ".\Bitrix\Im\Common::objectEncode($crmPath).", 'disk' : ".\Bitrix\Im\Common::objectEncode($pathToDisk)."}
});
});
";
return $sJS;
}
public static function GetV2TemplateJS(): string
{
global $USER;
$counters = (new \Bitrix\Im\V2\Message\CounterService())->get();
$recentList = \Bitrix\Im\Recent::getList(null, [
'SKIP_NOTIFICATION' => 'Y',
'SKIP_OPENLINES' => 'Y',
'JSON' => 'Y',
'GET_ORIGINAL_TEXT' => 'Y',
//'SHORT_INFO' => 'Y',
]);
$chatOptions = CIMChat::GetChatOptions();
$marketApps = (new \Bitrix\Im\V2\Marketplace\Application())->toRestFormat();
$currentUser = \CIMContactList::GetUserData([
'ID' => $USER->GetID(),
'PHONES' => 'Y',
'SHOW_ONLINE' => 'N',
'EXTRA_FIELDS' => 'Y',
'DATE_ATOM' => 'Y'
])['users'][$USER->GetID()];
$loggerConfig = \Bitrix\Im\Settings::getLoggerConfig();
$settings = (new \Bitrix\Im\V2\Settings\UserConfiguration($USER->GetID()))->getGeneralSettings();
$jsString = "
BX.ready(function() {
BX.Messenger.v2.Application.Launch('quickAccess', {
node: '#bx-im-external-recent-list',
preloadedList: " . \Bitrix\Main\Web\Json::encode($recentList) . ",
chatOptions: " . \Bitrix\Main\Web\Json::encode($chatOptions) . ",
marketApps: " . \Bitrix\Main\Web\Json::encode($marketApps) . ",
currentUser: " . \Bitrix\Main\Web\Json::encode($currentUser) . ",
loggerConfig: " . \Bitrix\Main\Web\Json::encode($loggerConfig) . ",
counters: " . \Bitrix\Main\Web\Json::encode($counters) . ",
settings: " . \Bitrix\Main\Web\Json::encode($settings) . ",
});
});
";
return $jsString;
}
public static function GetMobileDialogTemplateJS($arParams, $arTemplate)
{
global $USER;
$ppStatus = false;
$ppServerStatus = false;
$updateStateInterval = 'auto';
if (CModule::IncludeModule("pull"))
{
$ppStatus = (bool)CPullOptions::ModuleEnable();
$ppServerStatus = (bool)CPullOptions::GetNginxStatus();
$updateStateInterval = CPullOptions::GetNginxStatus()? self::GetSessionLifeTime(): 80;
if ($updateStateInterval > 100)
{
if ($updateStateInterval > 3600)
$updateStateInterval = 3600;
$updateStateInterval = $updateStateInterval-60;
}
}
$diskStatus = CIMDisk::Enabled();
$diskExternalLinkStatus = CIMDisk::EnabledExternalLink();
$chatExtendShowHistory = \COption::GetOptionInt('im', 'chat_extend_show_history');
$phoneEnabled = self::CheckPhoneStatus() && CModule::IncludeModule('mobileapp') && \Bitrix\MobileApp\Mobile::getInstance()->isWebRtcSupported();
$olConfig = Array();
$crmPath = Array();
$businessUsers = false;
if (\Bitrix\Main\Loader::includeModule('crm'))
{
$crmPath['LEAD'] = \Bitrix\Im\Integration\Crm\Common::getLink('LEAD');
$crmPath['CONTACT'] = \Bitrix\Im\Integration\Crm\Common::getLink('CONTACT');
$crmPath['COMPANY'] = \Bitrix\Im\Integration\Crm\Common::getLink('COMPANY');
$crmPath['DEAL'] = \Bitrix\Im\Integration\Crm\Common::getLink('DEAL');
}
if (CModule::IncludeModule('imopenlines'))
{
$olConfig['canDeleteMessage'] = str_replace('.', '_', \Bitrix\Imopenlines\Connector::getListCanDeleteMessage());
$olConfig['canDeleteOwnMessage'] = str_replace('.', '_', \Bitrix\Imopenlines\Connector::getListCanDeleteOwnMessage());
$olConfig['canUpdateOwnMessage'] = str_replace('.', '_', \Bitrix\Imopenlines\Connector::getListCanUpdateOwnMessage());
$olConfig['queue'] = Array();
foreach (\Bitrix\ImOpenLines\Config::getQueueList($USER->GetID()) as $config)
{
$olConfig['queue'][] = array_change_key_case($config, CASE_LOWER);
}
}
$mobileAction = isset($arTemplate["ACTION"])? $arTemplate["ACTION"]: 'none';
$mobileCallMethod = isset($arTemplate["CALL_METHOD"])? $arTemplate["CALL_METHOD"]: 'device';
$initConfig = [
'mobileAction' => $mobileAction,
'mobileCallMethod' => $mobileCallMethod,
'colors' => \Bitrix\Im\Color::isEnabled()? \Bitrix\Im\Color::getSafeColorNames(): false,
'chatCounters' => [
'notify' => intval($counters['TYPE']['NOTIFY']),
'dialog' => intval($counters['TYPE']['DIALOG']),
'chat' => intval($counters['TYPE']['CHAT']),
'lines' => intval($counters['TYPE']['LINES']),
'mail' => intval($arTemplate["MAIL_COUNTER"])
],
'counters' => empty($arTemplate['COUNTERS'])? false: $arTemplate['COUNTERS'],
'ppStatus' => $ppStatus,
'ppServerStatus' => $ppServerStatus,
'updateStateInterval' => $updateStateInterval,
'openChatEnable' => (bool)CIMMessenger::CheckEnableOpenChat(),
'xmppStatus' => (bool)CIMMessenger::CheckXmppStatusOnline(),
'isAdmin' => (bool)self::IsAdmin(),
'bitrixNetwork' => (bool)CIMMessenger::CheckNetwork(),
'bitrix24' => (bool)IsModuleInstalled('bitrix24'),
'bitrix24net' => (bool)IsModuleInstalled('b24network'),
'bitrixIntranet' => (bool)IsModuleInstalled('intranet'),
'bitrixXmpp' => (bool)IsModuleInstalled('xmpp'),
'bitrixMobile' => (bool)IsModuleInstalled('mobile'),
'bitrixOpenLines' => (bool)IsModuleInstalled('imopenlines'),
'bitrixCrm' => (bool)IsModuleInstalled('crm'),
'desktopStatus' => (bool)CIMMessenger::CheckDesktopStatusOnline(),
'desktopVersion' => (int)CIMMessenger::GetDesktopVersion(),
'language' => LANGUAGE_ID,
'bot' => empty($arTemplate['BOT'])? false: $arTemplate["BOT"],
'command' => empty($arTemplate['COMMAND'])? false: $arTemplate["COMMAND"],
'textareaIcon' => empty($arTemplate['TEXTAREA_ICON'])? false: $arTemplate["TEXTAREA_ICON"],
'smile' => empty($arTemplate['SMILE'])? false: $arTemplate["SMILE"],
'smileSet' => empty($arTemplate['SMILE_SET'])? false: $arTemplate["SMILE_SET"],
'settings' => empty($arTemplate['SETTINGS'])? false: $arTemplate['SETTINGS'],
'settingsNotifyBlocked' => empty($arTemplate['SETTINGS_NOTIFY_BLOCKED'])? false: $arTemplate['SETTINGS_NOTIFY_BLOCKED'],
'recent' => false,
'businessUsers' => $businessUsers === false? false: (empty($businessUsers)? null: $businessUsers),
'userChatOptions' => CIMChat::GetChatOptions(),
'history' => false,
'openMessenger' => false,
'openHistory' => false,
'openNotify' => false,
'openSettings' => false,
'generalChatId' => CIMChat::GetGeneralChatId(),
'canSendMessageGeneralChat' => (bool)CIMChat::CanSendMessageToGeneralChat($USER->GetID()),
'userId' => $USER->GetID(),
'userEmail' => $USER->GetEmail(),
'userColor' => \Bitrix\Im\Color::getCode(\Bitrix\Im\User::getInstance()->getColor()),
'userGender' => \Bitrix\Im\User::getInstance()->getGender(),
'userExtranet' => (bool)\Bitrix\Im\User::getInstance()->isExtranet(),
'webrtc' => [
'turnServer' => empty($arTemplate['TURN_SERVER'])? '': $arTemplate['TURN_SERVER'],
'turnServerLogin' => empty($arTemplate['TURN_SERVER_LOGIN'])? '': $arTemplate['TURN_SERVER_LOGIN'],
'turnServerPassword' => empty($arTemplate['TURN_SERVER_PASSWORD'])? '': $arTemplate['TURN_SERVER_PASSWORD'],
'mobileSupport' => (bool)$arTemplate['WEBRTC_MOBILE_SUPPORT'],
'phoneEnabled' => (bool)$phoneEnabled,
],
'openlines' => $olConfig,
'options' => [
'chatExtendShowHistory' => (bool)$chatExtendShowHistory
],
'disk' => [
'enable' => (bool)$diskStatus,
'external' => (bool)$diskExternalLinkStatus
],
'path' => [
'lf' => empty($arTemplate['PATH_TO_LF'])? '/': $arTemplate['PATH_TO_LF'],
'profile' => empty($arTemplate['PATH_TO_USER_PROFILE'])? '': $arTemplate['PATH_TO_USER_PROFILE'],
'profileTemplate' => empty($arTemplate['PATH_TO_USER_PROFILE_TEMPLATE'])? '': $arTemplate['PATH_TO_USER_PROFILE_TEMPLATE'],
'mail' => empty($arTemplate['PATH_TO_USER_MAIL'])? '': $arTemplate['PATH_TO_USER_MAIL'],
'crm' => $crmPath
]
];
return $initConfig;
}
public static function StartWriting($dialogId, $userId = false, $userName = "", $byEvent = false, $linesSilentMode = false)
{
$userId = intval($userId);
if ($userId <= 0)
{
global $USER;
$userId = intval($USER->GetID());
}
if (mb_substr($dialogId, 0, 4) == 'chat')
{
}
else if ($dialogId == $userId)
{
return false;
}
else
{
$dialogId = intval($dialogId);
}
if (!$userName)
{
$userName = \Bitrix\Im\User::getInstance($userId)->getFullName();
}
if ($userId > 0 && $dialogId <> '' && CModule::IncludeModule("pull"))
{
$chat = Array();
$relation = Array();
if (mb_substr($dialogId, 0, 4) == 'chat')
{
$orm = \Bitrix\Im\Model\ChatTable::getById(mb_substr($dialogId, 4));
$chat = $orm->fetch();
$arRelation = CIMChat::GetRelationById(mb_substr($dialogId, 4), false, true, false);
$relation = $arRelation;
if ($chat['ENTITY_TYPE'] != 'LIVECHAT' && !isset($arRelation[$userId]))
{
return false;
}
unset($arRelation[$userId]);
$pullMessage = Array(
'module_id' => 'im',
'command' => 'startWriting',
'expiry' => 60,
'params' => Array(
'dialogId' => $dialogId,
'userId' => $userId,
'userName' => $userName
),
'extra' => \Bitrix\Im\Common::getPullExtra()
);
$chatId = $chat['ID'];
$entityType = $chat['ENTITY_TYPE'];
$entityId = $chat['ENTITY_ID'];
if ($chat['ENTITY_TYPE'] == 'LINES')
{
foreach ($arRelation as $rel)
{
if ($rel["EXTERNAL_AUTH_ID"] == 'imconnector')
{
unset($arRelation[$rel["USER_ID"]]);
}
}
}
\Bitrix\Pull\Event::add(array_keys($arRelation), $pullMessage);
if ($chat['TYPE'] == IM_MESSAGE_OPEN || $chat['TYPE'] == IM_MESSAGE_OPEN_LINE)
{
CPullWatch::AddToStack('IM_PUBLIC_'.$chatId, $pullMessage);
}
}
else if (intval($dialogId) > 0)
{
\Bitrix\Pull\Event::add($dialogId, Array(
'module_id' => 'im',
'command' => 'startWriting',
'expiry' => 60,
'params' => Array(
'dialogId' => $userId,
'userId' => $userId,
'userName' => $userName
),
'extra' => \Bitrix\Im\Common::getPullExtra()
));
}
foreach(GetModuleEvents("im", "OnStartWriting", true) as $arEvent)
{
ExecuteModuleEventEx($arEvent, array(array(
'DIALOG_ID' => $dialogId,
'CHAT' => $chat,
'RELATION' => $relation,
'USER_ID' => $userId,
'USER_NAME' => $userName,
'BY_EVENT' => $byEvent,
'LINES_SILENT_MODE' => $linesSilentMode
)));
}
return true;
}
return false;
}
public static function PrepareSmiles()
{
return CSmileGallery::getSmilesWithSets();
}
private static function UploadFileFromText($params)
{
$params['CHAT_ID'] = intval($params['CHAT_ID']);
if (empty($params['MESSAGE']) || $params['CHAT_ID'] <= 0)
{
return $params;
}
if (preg_match_all("/\[DISK=([0-9]+)\]/i", $params['MESSAGE'], $matches))
{
$fileFound = false;
$files = [];
foreach ($matches[1] as $fileId)
{
$newFile = CIMDisk::SaveFromLocalDisk($params['CHAT_ID'], $fileId, false, \Bitrix\Im\Common::getUserId());
if ($newFile)
{
$files[] = $newFile;
$fileFound = true;
$params['PARAMS']['FILE_ID'][] = $newFile->getId();
}
}
if ($fileFound)
{
$params['MESSAGE'] = preg_replace("/\[DISK\=([0-9]+)\]/i", "", $params['MESSAGE']);
$params['FILES_FROM_TEXT'] = $files;
}
}
return $params;
}
public static function SendMention($params)
{
$params['CHAT_ID'] = intval($params['CHAT_ID']);
if (!isset($params['MESSAGE']) || $params['CHAT_ID'] <= 0)
{
return false;
}
$userName = \Bitrix\Im\User::getInstance($params['FROM_USER_ID'])->getFullName(false);
$userGender = \Bitrix\Im\User::getInstance($params['FROM_USER_ID'])->getGender();
if (!$userName)
{
return false;
}
$orm = \Bitrix\Im\Model\ChatTable::getById($params['CHAT_ID']);
$chat = $orm->fetch();
if (!$chat)
{
return false;
}
$params['CHAT_TITLE'] = $chat['TITLE'] ?? '';
$params['CHAT_TYPE'] = trim($chat['TYPE'] ?? '');
$params['CHAT_COLOR'] = trim($chat['COLOR'] ?? '');
$params['CHAT_ENTITY_TYPE'] = trim($chat['CHAT_ENTITY_TYPE'] ?? '');
$params['CHAT_AVATAR'] = intval($chat['AVATAR']);
if (!in_array($params['CHAT_TYPE'], Array(IM_MESSAGE_OPEN, IM_MESSAGE_CHAT, IM_MESSAGE_OPEN_LINE)))
{
return false;
}
if (!isset($params['CHAT_RELATION']))
{
$params['CHAT_RELATION'] = CIMChat::GetRelationById($params['CHAT_ID'], false, true, false);
}
$forUsers = Array();
if (preg_match_all("/\[USER=([0-9]+)( REPLACE)?](.*?)\[\/USER]/i", $params['MESSAGE'], $matches))
{
if ($params['CHAT_TYPE'] == IM_MESSAGE_OPEN)
{
foreach($matches[1] as $userId)
{
if (!CIMSettings::GetNotifyAccess($userId, 'im', 'mention', CIMSettings::CLIENT_SITE))
{
continue;
}
if (
!isset($params['CHAT_RELATION'][$userId])
|| $params['CHAT_RELATION'][$userId]['NOTIFY_BLOCK'] == 'Y'
)
{
$forUsers[$userId] = $userId;
}
}
}
else
{
foreach($matches[1] as $userId)
{
if (!CIMSettings::GetNotifyAccess($userId, 'im', 'mention', CIMSettings::CLIENT_SITE))
{
continue;
}
if (
isset($params['CHAT_RELATION'][$userId])
&& $params['CHAT_RELATION'][$userId]['NOTIFY_BLOCK'] == 'Y'
)
{
$forUsers[$userId] = $userId;
}
}
}
}
$chatTitle = mb_substr(htmlspecialcharsback($params['CHAT_TITLE']), 0, 32);
$notifyMail = GetMessage('IM_MESSAGE_MENTION_'.($userGender=='F'?'F':'M'), Array('#TITLE#' => $chatTitle));
$notifyText = GetMessage('IM_MESSAGE_MENTION_'.($userGender=='F'?'F':'M'), Array('#TITLE#' => '[CHAT='.$params['CHAT_ID'].']'.$chatTitle.'[/CHAT]'));
$pushText = GetMessage('IM_MESSAGE_MENTION_PUSH_2_'.($userGender=='F'?'F':'M'), Array('#USER#' => $userName, '#TITLE#' => $chatTitle)).': '.self::PrepareParamsForPush(Array('MESSAGE' => $params['MESSAGE'], 'FILES' => $params['FILES']));
if ($pushText <> '')
{
foreach ($forUsers as $userId)
{
if ($params['FROM_USER_ID'] == $userId)
continue;
$arMessageFields = array(
"TO_USER_ID" => $userId,
"FROM_USER_ID" => $params['FROM_USER_ID'],
"NOTIFY_TYPE" => IM_NOTIFY_FROM,
"NOTIFY_MODULE" => "im",
"NOTIFY_EVENT" => "mention",
"NOTIFY_TAG" => 'IM|MENTION|'.$params['CHAT_ID'],
"NOTIFY_SUB_TAG" => 'IM_MESS_'.$params['CHAT_ID'].'_'.$userId,
"NOTIFY_MESSAGE" => $notifyText,
"NOTIFY_MESSAGE_OUT" => $notifyMail,
);
CIMNotify::Add($arMessageFields);
\Bitrix\Pull\Push::add($userId, self::PreparePushForMentionInChat(Array(
'CHAT_ID' => $params['CHAT_ID'],
'CHAT_TITLE' => $params['CHAT_TITLE'],
'CHAT_TYPE' => $params['CHAT_TYPE'],
'CHAT_AVATAR' => $params['CHAT_AVATAR'],
'CHAT_ENTITY_TYPE' => $params['CHAT_ENTITY_TYPE'],
'FROM_USER_ID' => $params['FROM_USER_ID'],
'MESSAGE' => $pushText,
)));
}
}
return true;
}
public static function PrepareParamsForPull($params)
{
if (!is_array($params))
{
return $params;
}
foreach ($params as $key => $value)
{
if ($key == 'ATTACH')
{
if (is_object($value) && $value instanceof CIMMessageParamAttach)
{
$params[$key] = CIMMessageParamAttach::PrepareAttach($value->GetArray());
}
else
{
foreach ($value as $key2 => $value2)
{
if (is_object($value2) && $value2 instanceof CIMMessageParamAttach)
{
$params[$key][$key2] = CIMMessageParamAttach::PrepareAttach($value2->GetArray());
}
}
}
}
elseif ($key == 'KEYBOARD')
{
if (is_object($value) && $value instanceof \Bitrix\Im\Bot\Keyboard)
{
$params[$key] = $value->getArray();
}
}
elseif ($key == 'MENU')
{
if (is_object($value) && $value instanceof \Bitrix\Im\Bot\ContextMenu)
{
$params[$key] = $value->getArray();
}
}
elseif ($key == 'AVATAR' && intval($value) > 0)
{
$params[$key] = CIMChat::GetAvatarImage($value, 200, false);
}
}
return $params;
}
public static function PreparePushForMentionInChat($params)
{
$params['CHAT_ID'] = intval($params['CHAT_ID']);
if ($params['CHAT_ID'] <= 0)
{
return false;
}
$params['CHAT_TITLE'] = mb_substr(htmlspecialcharsback($params['CHAT_TITLE']), 0, 32);
$pushText = $params['MESSAGE'];
$chatType = \Bitrix\Im\Chat::getType($params);
$avatarUser = \Bitrix\Im\User::getInstance($params['FROM_USER_ID'])->getAvatar();
if ($avatarUser && mb_strpos($avatarUser, 'http') !== 0)
{
$avatarUser = \Bitrix\Im\Common::getPublicDomain().$avatarUser;
}
$avatarChat = \CIMChat::GetAvatarImage($params['CHAT_AVATAR'], 200, false);
if ($avatarChat && mb_strpos($avatarChat, 'http') !== 0)
{
$avatarChat = \Bitrix\Im\Common::getPublicDomain().$avatarChat;
}
$result = Array();
$result['module_id'] = 'im';
$result['push']['params'] = Array(
'TAG' => 'IM_CHAT_'.$params['CHAT_ID'],
'CHAT_TYPE' => $params['CHAT_TYPE'],
'CATEGORY' => 'ANSWER',
'URL' => SITE_DIR.'mobile/ajax.php?mobile_action=im_answer',
'PARAMS' => Array(
'RECIPIENT_ID' => 'chat'.$params['CHAT_ID']
)
);
$result['push']['type'] = $params['PUSH_TYPE']? $params['PUSH_TYPE']: ($params['CHAT_TYPE'] == IM_MESSAGE_OPEN? 'openChat': 'chat');
$result['push']['tag'] = 'IM_CHAT_'.$params['CHAT_ID'];
$result['push']['sub_tag'] = 'IM_MESS';
$result['push']['app_id'] = 'Bitrix24';
$result['push']['message'] = $pushText;
$result['push']['advanced_params'] = array(
"group"=> $chatType == 'lines'? 'im_lines_message': 'im_message',
"avatarUrl"=> $avatarChat? $avatarChat: $avatarUser,
"senderName" => (string)$params['CHAT_TITLE'],
"senderMessage" => $pushText,
);
return $result;
}
public static function PreparePushForChat($params)
{
$pushText = self::PrepareMessageForPush($params['params']);
unset($params['params']['message']['text_push']);
$chatTitle = mb_substr(htmlspecialcharsback($params['params']['chat'][$params['params']['chatId']]['name']), 0, 32);
$chatType = $params['params']['chat'][$params['params']['chatId']]['type'];
$chatAvatar = $params['params']['chat'][$params['params']['chatId']]['avatar'];
$chatTypeLetter = $params['params']['chat'][$params['params']['chatId']]['message_type'];
if (($params['params']['system'] ?? null) === 'Y' || $params['params']['message']['senderId'] <= 0)
{
$avatarUser = '';
$userName = '';
}
else
{
$userName = \Bitrix\Im\User::getInstance($params['params']['message']['senderId'])->getFullName(false);
$avatarUser = \Bitrix\Im\User::getInstance($params['params']['message']['senderId'])->getAvatar();
if ($avatarUser && mb_strpos($avatarUser, 'http') !== 0)
{
$avatarUser = \Bitrix\Im\Common::getPublicDomain().$avatarUser;
}
}
if (
isset(
$params['params']['message']['senderId'],
$params['params']['users'][$params['params']['message']['senderId']]
)
&& $params['params']['users'][$params['params']['message']['senderId']]
)
{
$params['params']['users'] = [
$params['params']['message']['senderId'] => $params['params']['users'][$params['params']['message']['senderId']]
];
}
else
{
$params['params']['users'] = [];
}
if ($chatAvatar == '/bitrix/js/im/images/blank.gif')
{
$chatAvatar = '';
}
else if ($chatAvatar && mb_strpos($chatAvatar, 'http') !== 0)
{
$chatAvatar = \Bitrix\Im\Common::getPublicDomain().$chatAvatar;
}
unset($params['extra']);
array_walk_recursive($params, function(&$item, $key)
{
if (is_null($item))
{
$item = false;
}
else if ($item instanceof \Bitrix\Main\Type\DateTime)
{
$item = date('c', $item->getTimestamp());
}
});
$result = Array();
$result['module_id'] = 'im';
$result['push']['type'] = ($chatType === 'open'? 'openChat': $chatType);
$result['push']['tag'] = 'IM_CHAT_'.intval($params['params']['chatId']);
$result['push']['sub_tag'] = 'IM_MESS';
$result['push']['app_id'] = 'Bitrix24';
$result['push']['message'] = ($userName? $userName.': ': '').$pushText;
$result['push']['advanced_params'] = array(
"group"=> $chatType == 'lines'? 'im_lines_message': 'im_message',
"avatarUrl"=> $chatAvatar? $chatAvatar: $avatarUser,
"senderName" => $chatTitle,
"senderMessage" => ($userName? $userName.': ': '').$pushText,
"senderCut" => mb_strlen($userName? $userName.': ' : ''),
"data" => self::PrepareEventForPush($params['command'], $params['params'])
);
$result['push']['params'] = Array(
'TAG' => 'IM_CHAT_'.$params['params']['chatId'],
'CHAT_TYPE' => $chatTypeLetter? $chatTypeLetter: 'C',
'CATEGORY' => 'ANSWER',
'URL' => SITE_DIR.'mobile/ajax.php?mobile_action=im_answer',
'PARAMS' => Array(
'RECIPIENT_ID' => 'chat'.$params['params']['chatId'],
'MESSAGE_ID' => $params['params']['message']['id']
),
);
return $result;
}
public static function PreparePushForPrivate($params)
{
$pushText = self::PrepareMessageForPush($params['params']);
unset($params['params']['message']['text_push']);
if (isset($params['params']['system']) && $params['params']['system'] == 'Y')
{
$userName = '';
$avatarUser = '';
}
else
{
$userName = \Bitrix\Im\User::getInstance($params['params']['message']['senderId'])->getFullName(false);
$avatarUser = \Bitrix\Im\User::getInstance($params['params']['message']['senderId'])->getAvatar();
if ($avatarUser && mb_strpos($avatarUser, 'http') !== 0)
{
$avatarUser = \Bitrix\Im\Common::getPublicDomain().$avatarUser;
}
}
if ($params['params']['users'][$params['params']['message']['senderId']])
{
$params['params']['users'] = Array(
$params['params']['message']['senderId'] => $params['params']['users'][$params['params']['message']['senderId']]
);
}
else
{
$params['params']['users'] = Array();
}
unset($params['extra']);
array_walk_recursive($params, function(&$item, $key)
{
if (is_null($item))
{
$item = false;
}
else if ($item instanceof \Bitrix\Main\Type\DateTime)
{
$item = date('c', $item->getTimestamp());
}
});
$result = Array();
$result['module_id'] = 'im';
$result['push']['type'] = 'message';
$result['push']['tag'] = 'IM_MESS_'.intval($params['params']['message']['senderId']);
$result['push']['sub_tag'] = 'IM_MESS';
$result['push']['app_id'] = 'Bitrix24';
$result['push']['message'] = $pushText;
$result['push']['advanced_params'] = array(
"group"=> 'im_message',
"avatarUrl"=> $avatarUser,
"senderName" => $userName,
"senderMessage" => $pushText,
"data" => self::PrepareEventForPush($params['command'], $params['params']),
);
$result['push']['params'] = Array(
'TAG' => 'IM_MESS_'.$params['params']['message']['senderId'],
'CATEGORY' => 'ANSWER',
'URL' => SITE_DIR.'mobile/ajax.php?mobile_action=im_answer',
'PARAMS' => Array(
'RECIPIENT_ID' => (int)$params['params']['message']['senderId'],
'MESSAGE_ID' => $params['params']['message']['id']
),
);
return $result;
}
private static function prepareAdvancedParamsForNotificationPush(array $params, string $pushMessage = null): array
{
if ($params['date'] instanceof \Bitrix\Main\Type\DateTime)
{
$params['date'] = date('c', $params['date']->getTimestamp());
}
$params['text'] = self::PrepareMessageForPush(['message' => ['text' => $params['text']]]);
$advancedParams = [
'id' => 'im_notify',
'group' => 'im_notify',
'data' => self::prepareNotificationEventForPush($params, $pushMessage)
];
if (isset($params['userName']))
{
$advancedParams['senderName'] = $params['userName'];
if (isset($params['userAvatar']))
{
$advancedParams['avatarUrl'] = $params['userAvatar'];
}
$advancedParams['senderMessage'] = $pushMessage ?: $params['text'];
}
return $advancedParams;
}
public static function PrepareParamsForPush($params)
{
if (!isset($params['MESSAGE']))
{
$params['MESSAGE'] = '';
}
$params['MESSAGE'] = trim($params['MESSAGE']);
$pushFiles = '';
if (isset($params['FILES']) && count($params['FILES']) > 0)
{
foreach ($params['FILES'] as $file)
{
$pushFiles .= " [".GetMessage('IM_MESSAGE_FILE').": ".$file['name']."]";
}
$params['MESSAGE'] .= $pushFiles;
}
$hasAttach = mb_strpos($params['MESSAGE'], '[ATTACH=') !== false;
$params['MESSAGE'] = preg_replace("/\[CODE\](.*?)\[\/CODE\]/si", " [".GetMessage('IM_MESSAGE_CODE')."] ", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\[s]([^[]*(?:\[(?!s]|\/s])[^[]*)*)\[\/s]/i", "-", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\[b]([^[]*(?:\[(?!b]|\/b])[^[]*)*)\[\/b]/i", "$1", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\[i]([^[]*(?:\[(?!i]|\/i])[^[]*)*)\[\/i]/i", "$1", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\[u]([^[]*(?:\[(?!u]|\/u])[^[]*)*)\[\/u]/i", "$1", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\\[url\\](.*?)\\[\\/url\\]/i".BX_UTF_PCRE_MODIFIER, "$1", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\\[url\\s*=\\s*((?:[^\\[\\]]++|\\[ (?: (?>[^\\[\\]]+) | (?:\\1) )* \\])+)\\s*\\](.*?)\\[\\/url\\]/ixs".BX_UTF_PCRE_MODIFIER, "$2", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace_callback("/\[USER=([0-9]{1,})\]\[\/USER\]/i", Array('\Bitrix\Im\Text', 'modifyShortUserTag'), $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\[USER=([0-9]+)( REPLACE)?](.+?)\[\/USER]/i", "$3", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\[CHAT=([0-9]{1,})\](.*?)\[\/CHAT\]/i", "$2", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace_callback("/\[SEND(?:=(?:.+?))?\](?:.+?)?\[\/SEND]/i", Array("CIMMessenger", "PrepareMessageForPushSendPutCallBack"), $params['MESSAGE']);
$params['MESSAGE'] = preg_replace_callback("/\[PUT(?:=(?:.+?))?\](?:.+?)?\[\/PUT]/i", Array("CIMMessenger", "PrepareMessageForPushSendPutCallBack"), $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\[CALL(?:=(.+?))?\](.+?)?\[\/CALL\]/i", "$2", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace("/\[PCH=([0-9]{1,})\](.*?)\[\/PCH\]/i", "$2", $params['MESSAGE']);
$params['MESSAGE'] = preg_replace_callback("/\[ICON\=([^\]]*)\]/i", Array("CIMMessenger", "PrepareMessageForPushIconCallBack"), $params['MESSAGE']);
$params['MESSAGE'] = preg_replace('#\-{54}.+?\-{54}#s', " [".GetMessage('IM_QUOTE')."] ", str_replace(array("#BR#"), Array(" "), $params['MESSAGE']));
$params['MESSAGE'] = preg_replace('/^(>>(.*)(\n)?)/mi', " [".GetMessage('IM_QUOTE')."] ", str_replace(array("#BR#"), Array(" "), $params['MESSAGE']));
if (!$pushFiles && !$hasAttach && ($params['ATTACH'] ?? null))
{
$params['MESSAGE'] .= " [".GetMessage('IM_MESSAGE_ATTACH')."]";
}
return $params['MESSAGE'];
}
public static function PrepareMessageForPush($message)
{
if (isset($message['message']['text_push']) && $message['message']['text_push'])
{
$message['message']['text'] = $message['message']['text_push'];
}
else
{
if (isset($message['message']['params']['ATTACH']) && count($message['message']['params']['ATTACH']) > 0)
{
$attachText = $message['message']['params']['ATTACH'][0]['DESCRIPTION'];
if (!$attachText)
{
$attachText = \Bitrix\Im\Text::getEmoji('attach').' '.GetMessage('IM_MESSAGE_ATTACH');
}
if ($attachText === \CIMMessageParamAttach::SKIP_MESSAGE)
{
$attachText = '';
}
$message['message']['text'] .=
(empty($message['message']['text'])? '': " ")
.$attachText
;
}
if (isset($message['files']) && count($message['files']) > 0)
{
$file = array_values($message['files'])[0];
if ($file['type'] === 'image')
{
$fileName = \Bitrix\Im\Text::getEmoji($file['type']).' '.GetMessage('IM_MESSAGE_IMAGE');
}
else if ($file['type'] === 'audio')
{
$fileName = \Bitrix\Im\Text::getEmoji($file['type']).' '.GetMessage('IM_MESSAGE_AUDIO');
}
else if ($file['type'] === 'video')
{
$fileName = \Bitrix\Im\Text::getEmoji($file['type']).' '.GetMessage('IM_MESSAGE_VIDEO');
}
else
{
$fileName = \Bitrix\Im\Text::getEmoji('file', GetMessage('IM_MESSAGE_FILE').":")." ".$file['name'];
}
$message['message']['text'] .= trim($fileName);
}
}
$codeIcon = \Bitrix\Im\Text::getEmoji('code', "[".GetMessage('IM_MESSAGE_CODE')."]");
$quoteIcon = \Bitrix\Im\Text::getEmoji('quote', "[".GetMessage('IM_QUOTE')."]");
$message['message']['text'] = str_replace("\n", " ", $message['message']['text']);
$message['message']['text'] = preg_replace("/\[CODE\](.*?)\[\/CODE\]/si", " ".$codeIcon." ", $message['message']['text']);
$message['message']['text'] = preg_replace("/\[s\].*?\[\/s\]/i", "-", $message['message']['text']);
$message['message']['text'] = preg_replace("/\[[bui]\](.*?)\[\/[bui]\]/i", "$1", $message['message']['text']);
$message['message']['text'] = preg_replace("/\\[url\\](.*?)\\[\\/url\\]/i".BX_UTF_PCRE_MODIFIER, "$1", $message['message']['text']);
$message['message']['text'] = preg_replace("/\\[url\\s*=\\s*((?:[^\\[\\]]++|\\[ (?: (?>[^\\[\\]]+) | (?:\\1) )* \\])+)\\s*\\](.*?)\\[\\/url\\]/ixs".BX_UTF_PCRE_MODIFIER, "$2", $message['message']['text']);
$message['message']['text'] = preg_replace_callback("/\[USER=([0-9]{1,})\]\[\/USER\]/i", Array('\Bitrix\Im\Text', 'modifyShortUserTag'), $message['message']['text']);
$message['message']['text'] = preg_replace("/\[USER=([0-9]+)( REPLACE)?](.+?)\[\/USER]/i", "$3", $message['message']['text']);
$message['message']['text'] = preg_replace("/\[CHAT=([0-9]{1,})\](.*?)\[\/CHAT\]/i", "$2", $message['message']['text']);
$message['message']['text'] = preg_replace("/\[context=(chat\d+|\d+:\d+)\/(\d+)](.*?)\[\/context]/i", "$3", $message['message']['text']);
$message['message']['text'] = preg_replace_callback("/\[SEND(?:=(?:.+?))?\](?:.+?)?\[\/SEND]/i", Array("CIMMessenger", "PrepareMessageForPushSendPutCallBack"), $message['message']['text']);
$message['message']['text'] = preg_replace_callback("/\[PUT(?:=(?:.+?))?\](?:.+?)?\[\/PUT]/i", Array("CIMMessenger", "PrepareMessageForPushSendPutCallBack"), $message['message']['text']);
$message['message']['text'] = preg_replace("/\[CALL(?:=(.+?))?\](.+?)?\[\/CALL\]/i", "$2", $message['message']['text']);
$message['message']['text'] = preg_replace("/\[PCH=([0-9]{1,})\](.*?)\[\/PCH\]/i", "$2", $message['message']['text']);
$message['message']['text'] = preg_replace_callback("/\[ICON\=([^\]]*)\]/i", Array("CIMMessenger", "PrepareMessageForPushIconCallBack"), $message['message']['text']);
$message['message']['text'] = preg_replace('#\-{54}.+?\-{54}#s', " ".$quoteIcon." ", str_replace(array("#BR#"), Array(" "), $message['message']['text']));
$message['message']['text'] = preg_replace('/^(>>(.*)(\n)?)/mi', " ".$quoteIcon." ", str_replace(array("#BR#"), Array(" "), $message['message']['text']));
$message['message']['text'] = preg_replace("/\\[color\\s*=\\s*([^\\]]+)\\](.*?)\\[\\/color\\]/is".BX_UTF_PCRE_MODIFIER, "$2", $message['message']['text']);
$message['message']['text'] = preg_replace("/\\[size\\s*=\\s*([^\\]]+)\\](.*?)\\[\\/size\\]/is".BX_UTF_PCRE_MODIFIER, "$2", $message['message']['text']);
return trim($message['message']['text']);
}
public static function PrepareEventForPush($command, $event)
{
$result = [
'cmd' => (string)$command,
'chatId' => (int)$event['chatId'],
'dialogId' => (string)$event['dialogId'],
'counter' => (int)$event['counter'],
];
if ($event['notify'] !== true)
{
$result['notify'] = $event['notify'];
}
if (!empty($event['chat'][$event['chatId']]))
{
$eventChat = $event['chat'][$event['chatId']];
$chat = [
'id' => (int)$eventChat['id'],
'name' => (string)$eventChat['name'],
'owner' => (int)$eventChat['owner'],
'color' => (string)$eventChat['color'],
'type' => (string)$eventChat['type'],
'date_create' => (string)$eventChat['date_create'],
];
if (
!empty($eventChat['avatar'])
&& $eventChat['avatar'] !== '/bitrix/js/im/images/blank.gif'
)
{
$chat['avatar'] = $eventChat['avatar'];
}
if ($eventChat['call'])
{
$chat['call'] = (string)$eventChat['call'];
}
if ($eventChat['call_number'])
{
$chat['call_number'] = (string)$eventChat['call_number'];
}
if ($eventChat['entity_data_1'])
{
$chat['entity_data_1'] = (string)$eventChat['entity_data_1'];
}
if ($eventChat['entity_data_2'])
{
$chat['entity_data_2'] = (string)$eventChat['entity_data_2'];
}
if ($eventChat['entity_data_3'])
{
$chat['entity_data_3'] = (string)$eventChat['entity_data_3'];
}
if ($eventChat['entity_id'])
{
$chat['entity_id'] = (string)$eventChat['entity_id'];
}
if ($eventChat['entity_type'])
{
$chat['entity_type'] = (string)$eventChat['entity_type'];
}
if ($eventChat['extranet'])
{
$chat['extranet'] = true;
}
$result['chat'] = $chat;
}
if (!empty($event['lines']))
{
$result['lines'] = $event['lines'];
}
if (!empty($event['users'][$event['message']['senderId']]))
{
$eventUser = $event['users'][$event['message']['senderId']];
$user = [
'id' => (int)$eventUser['id'],
'name' => (string)$eventUser['name'],
'first_name' => (string)$eventUser['first_name'],
'last_name' => (string)$eventUser['last_name'],
'color' => (string)$eventUser['color'],
];
if (
!empty($eventUser['avatar'])
&& $eventUser['avatar'] !== '/bitrix/js/im/images/blank.gif'
)
{
$user['avatar'] = (string)$eventUser['avatar'];
}
if ($eventUser['absent'])
{
$user['absent'] = true;
}
if (!$eventUser['active'])
{
$user['active'] = $eventUser['active'];
}
if ($eventUser['bot'])
{
$user['bot'] = true;
}
if ($eventUser['extranet'])
{
$user['extranet'] = true;
}
if ($eventUser['network'])
{
$user['network'] = true;
}
if ($eventUser['birthday'])
{
$user['birthday'] = $eventUser['birthday'];
}
if ($eventUser['connector'])
{
$user['connector'] = true;
}
if ($eventUser['external_auth_id'] !== 'default')
{
$user['external_auth_id'] = $eventUser['external_auth_id'];
}
if ($eventUser['gender'] === 'F')
{
$user['gender'] = 'F';
}
if ($eventUser['work_position'])
{
$user['work_position'] = (string)$eventUser['work_position'];
}
$result['users'] = $user;
}
if (!empty($event['files']))
{
foreach ($event['files'] as $key => $value)
{
$file = [
'id' => (int)$value['id'],
'extension' => (string)$value['extension'],
'name' => (string)$value['name'],
'size' => (int)$value['size'],
'type' => (string)$value['type'],
'image' => $value['image'],
'urlDownload' => '',
'urlPreview' => (new \Bitrix\Main\Web\Uri($value['urlPreview']))->deleteParams(['fileName'])->getUri(),
'urlShow' => '',
];
if ($value['image'])
{
$file['image'] = $value['image'];
}
if ($value['progress'] !== 100)
{
$file['progress'] = (int)$value['progress'];
}
if ($value['status'] !== 'done')
{
$file['status'] = $value['status'];
}
$result['files'][$key] = $file;
}
}
if (!empty($event['message']))
{
$eventMessage = $event['message'];
$message = [
'id' => (int)$eventMessage['id'],
'date' => (string)$eventMessage['date'],
'params' => $eventMessage['params'],
'prevId' => (int)$eventMessage['prevId'],
'senderId' => (int)$eventMessage['senderId'],
];
if (isset($message['params']['ATTACH']))
{
unset($message['params']['ATTACH']);
}
if ($eventMessage['system'] === 'Y')
{
$message['system'] = 'Y';
}
$result['message'] = $message;
}
$indexToNameMap = [
"chat" => 1,
"chatId" => 2,
"counter" => 3,
"dialogId" => 4,
"files" => 5,
"message" => 6,
"users" => 8,
"name" => 9,
"avatar" => 10,
"color" => 11,
"notify" => 12,
"type" => 13,
"extranet" => 14,
"date_create" => 20,
"owner" => 21,
"entity_id" => 23,
"entity_type" => 24,
"entity_data_1" => 203,
"entity_data_2" => 204,
"entity_data_3" => 205,
"call" => 201,
"call_number" => 202,
"manager_list" => 209,
"mute_list" => 210,
"first_name" => 40,
"last_name" => 41,
"gender" => 42,
"work_position" => 43,
"active" => 400,
"birthday" => 401,
"bot" => 402,
"connector" => 403,
"external_auth_id" => 404,
"network" => 406,
"textLegacy" => 65,
"date" => 61,
"prevId" => 62,
"params" => 63,
"senderId" => 64,
"system" => 601,
"extension" => 80,
"image" => 81,
"progress" => 82,
"size" => 83,
"status" => 84,
"urlDownload" => 85,
"urlPreview" => 86,
"urlShow" => 87,
"width" => 88,
"height" => 89,
];
return self::PrepareEventForPushChangeKeys($result, $indexToNameMap);
}
/**
* Prepares data for push with encoding fields to numbers. Should be the same structure as for p&p event.
* Decoding is located on mobile side (extension "chat/dataconverter").
*
* @param array $event Array with the same data as for p&p event.
* @param string|null $pushMessage Push notification text.
*
* @return array
*/
private static function prepareNotificationEventForPush(array $event, string $pushMessage = null): array
{
$result = [
'cmd' => 'notifyAdd',
'id' => (int)$event['id'],
'type' => (int)$event['type'],
'date' => (string)$event['date'],
'tag' => (string)$event['tag'],
'onlyFlash' => $event['onlyFlash'],
'originalTag' => (string)$event['originalTag'],
'settingName' => (string)$event['settingName'],
'counter' => (int)$event['counter'],
'userId' => (int)$event['userId'],
'userName' => (string)$event['userName'],
'userColor' => (string)$event['userColor'],
'userAvatar' => (string)$event['userAvatar'],
'userLink' => (string)$event['userLink'],
'params' => $event['params'],
];
if (isset($event['buttons']))
{
$result['buttons'] = $event['buttons'];
}
// We need to save original text ("long") in result only if we have push text ("short").
// "Long" text will be used to render push in notifications list.
if (isset($pushMessage))
{
$result['text'] = $event['text'];
}
$fieldToIndex = [
'id' => 1,
'type' => 2,
'date' => 3,
'text' => 4,
'tag' => 6,
'onlyFlash' => 7,
'originalTag' => 8,
'settingName' => 9,
'counter' => 10,
'userId' => 11,
'userName' => 12,
'userColor' => 13,
'userAvatar' => 14,
'userLink' => 15,
'params' => 16,
'buttons' => 17,
];
return self::PrepareEventForPushChangeKeys($result, $fieldToIndex);
}
private static function PrepareEventForPushChangeKeys($object, $map)
{
$result = [];
foreach($object as $key => $value)
{
$index = isset($map[$key])? $map[$key]: $key;
if (is_null($value))
{
$value = "";
}
if (is_array($value))
{
$result[$index] = self::PrepareEventForPushChangeKeys($value, $map);
}
else
{
$result[$index] = $value;
}
}
return $result;
}
public static function PrepareMessageForPushSendPutCallBack($params)
{
$code = mb_strpos(mb_strtoupper($params[0]), '[SEND') === 0? 'SEND': 'PUT';
return preg_replace("/\[$code(?:=(.+))?\](.+?)?\[\/$code\]/i", "$2", $params[0]);
}
public static function PrepareMessageForPushIconCallBack($params)
{
$text = $params[1];
$title = GetMessage('IM_MESSAGE_ICON');
preg_match('/title\=(.*[^\s\]])/i', $text, $match);
if ($match)
{
$title = $match[1];
if (mb_strpos($title, 'width=') !== false)
{
$title = mb_substr($title, 0, mb_strpos($title, 'width='));
}
if (mb_strpos($title, 'height=') !== false)
{
$title = mb_substr($title, 0, mb_strpos($title, 'height='));
}
if (mb_strpos($title, 'size=') !== false)
{
$title = mb_substr($title, 0, mb_strpos($title, 'size='));
}
$title = trim($title);
}
return '('.$title.')';
}
/* TMP FUNCTION */
public static function GetCachePath($id)
{
return \Bitrix\Im\Common::getCacheUserPostfix($id);
}
function GetSonetCode($user_id, $site_id = SITE_ID)
{
global $DB;
$result = array();
$user_id = intval($user_id);
if($user_id > 0 && IsModuleInstalled('socialnetwork'))
{
$strSQL = "
SELECT CODE, SUM(CNT) CNT
FROM b_sonet_log_counter
WHERE USER_ID = ".$user_id."
AND (SITE_ID = '".$site_id."' OR SITE_ID = '**')
GROUP BY CODE
";
$dbRes = $DB->Query($strSQL, true, "File: ".__FILE__."
Line: ".__LINE__);
while ($arRes = $dbRes->Fetch())
$result[$arRes["CODE"]] = $arRes["CNT"];
}
return $result;
}
public static function EnableMessageCheck()
{
self::$enableMessageCheck++;
return true;
}
public static function DisableMessageCheck()
{
self::$enableMessageCheck--;
return true;
}
public static function IsEnabledMessageCheck()
{
return self::$enableMessageCheck > 0;
}
public static function IsBitrix24UserRestricted()
{
global $USER;
return (
\Bitrix\Main\Loader::includeModule('bitrix24')
&& \Bitrix\Bitrix24\Limits\User::isUserRestricted($USER->GetId())
&& !\Bitrix\Bitrix24\Limits\User::isMoreHitsAvailable($USER->GetId())
);
}
public static function IsMysqlDb()
{
global $DB;
return $DB->type == 'MYSQL';
}
public static function IsAdmin()
{
global $USER;
return $USER->IsAdmin() || CModule::IncludeModule('bitrix24') && CBitrix24::IsPortalAdmin($USER->GetId());
}
public static function GetCurrentUserId()
{
global $USER;
return $USER->GetID();
}
private static function GetEventByCounterGroup($events, $maxUserInGroup = 100)
{
$groups = Array();
foreach ($events as $userId => $event)
{
$eventCode = $event['groupId'];
if (!isset($groups[$eventCode]))
{
$groups[$eventCode]['event'] = $event;
}
$groups[$eventCode]['users'][] = $userId;
$groups[$eventCode]['count'] = count($groups[$eventCode]['users']);
}
\Bitrix\Main\Type\Collection::sortByColumn($groups, Array('count' => SORT_DESC));
$count = 0;
$finalGroup = Array();
foreach ($groups as $eventCode => $event)
{
if ($count >= $maxUserInGroup)
{
if (isset($finalGroup['other']))
{
$finalGroup['other']['users'] = array_unique(array_merge($finalGroup['other']['users'], $event['users']));
}
else
{
$finalGroup['other'] = $event;
$finalGroup['other']['event']['params']['counter'] = 100;
}
}
else
{
$finalGroup[$eventCode] = $event;
}
$count++;
}
\Bitrix\Main\Type\Collection::sortByColumn($finalGroup, Array('count' => SORT_ASC));
return $finalGroup;
}
}