%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/modules/im/lib/replica/
Upload File :
Create Path :
Current File : /home/bitrix/www/bitrix/modules/im/lib/replica/messagehandler.php

<?php
namespace Bitrix\Im\Replica;

use Bitrix\Main\Loader;

if (Loader::includeModule('replica'))
{
	class MessageHandler extends \Bitrix\Replica\Client\BaseHandler
	{
		protected $tableName = "b_im_message";
		protected $moduleId = "im";
		protected $className = "\\Bitrix\\Im\\Model\\MessageTable";
		protected $primary = array(
			"ID" => "auto_increment",
		);
		protected $predicates = array(
			"AUTHOR_ID" => "b_user.ID",
			"CHAT_ID" => "b_im_chat.ID",
		);
		protected $translation = array(
			"ID" => "b_im_message.ID",
			"CHAT_ID" => "b_im_chat.ID",
			"AUTHOR_ID" => "b_user.ID",
		);
		protected $fields = array(
			"DATE_CREATE" => "datetime",
			"MESSAGE" => "text",
			"MESSAGE_OUT" => "text",
		);

		const LOADER_PLACEHOLDER = '[B][/B]';

		/**
		 * Called before log write. You may return false and not log write will take place.
		 *
		 * @param array $record Database record.
		 * @return boolean
		 */
		public function beforeLogInsert(array $record)
		{
			if ($record["NOTIFY_TYPE"] <= 0)
			{
				return true;
			}
			else
			{
				return false;
			}
		}

		/**
		 * Method will be invoked before new database record inserted.
		 * When an array returned the insert will be cancelled and map for
		 * returned record will be added.
		 *
		 * @param array &$newRecord All fields of inserted record.
		 *
		 * @return null|array
		 */
		public function beforeInsertTrigger(array &$newRecord)
		{
			if ($newRecord["CHAT_ID"] <= 0)
			{
				return array("ID" => 0);
			}

			$newRecord["MESSAGE"] = $this->fixMessage($newRecord["MESSAGE"]);
			if ($newRecord["MESSAGE"] == "")
			{
				$newRecord["MESSAGE"] = self::LOADER_PLACEHOLDER;
			}
			return null;
		}

		/**
		 * Method will be invoked before an database record updated.
		 *
		 * @param array $oldRecord All fields before update.
		 * @param array &$newRecord All fields after update.
		 *
		 * @return void
		 */
		public function beforeUpdateTrigger(array $oldRecord, array &$newRecord)
		{
			if (array_key_exists("MESSAGE", $newRecord))
			{
				$newRecord["MESSAGE"] = $this->fixMessage($newRecord["MESSAGE"]);
			}
		}

		/**
		 * Replaces some BB codes on receiver to display them properly.
		 *
		 * @param string $message A message.
		 *
		 * @return string
		 */
		protected function fixMessage($message)
		{
			$fixed = preg_replace("/\\[CHAT=[0-9]+\\](.*?)\\[\\/CHAT\\]/", "\\1", $message);
			if ($fixed == null)
			{
				return $message;
			}
			$fixed = preg_replace("/\\[USER=[0-9]+\\](.*?)\\[\\/USER\\]/", "\\1", $fixed);

			if ($fixed == null)
			{
				return $message;
			}

			return $fixed;
		}

		/**
		 * Method will be invoked after new database record inserted.
		 *
		 * @param array $newRecord All fields of inserted record.
		 *
		 * @return void
		 */
		public function afterInsertTrigger(array $newRecord)
		{
			$arParams = array();

			$chatId = $newRecord['CHAT_ID'];
			$arRel = \CIMChat::GetRelationById($chatId);

			$arFields['MESSAGE_TYPE'] = '';
			foreach ($arRel as $rel)
			{
				$arFields['MESSAGE_TYPE'] = $rel["MESSAGE_TYPE"];
				break;
			}
			$arFields['PARAMS'] = Array();
			$arFields['FILES'] = Array();

			if ($arFields['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE)
			{
				foreach ($arRel as $rel)
				{
					if ($rel['USER_ID'] == $newRecord['AUTHOR_ID'])
						$arFields['FROM_USER_ID'] = $rel['USER_ID'];
					else
						$arFields['TO_USER_ID'] = $rel['USER_ID'];
				}

				foreach ($arRel as $rel)
				{
					\CIMContactList::SetRecent(Array(
						'ENTITY_ID' => $rel['USER_ID'] == $arFields['TO_USER_ID']? $arFields['FROM_USER_ID']: $arFields['TO_USER_ID'],
						'MESSAGE_ID' => $newRecord['ID'],
						'CHAT_TYPE' => IM_MESSAGE_PRIVATE,
						'USER_ID' => $rel['USER_ID'],
						'CHAT_ID' => $chatId,
						'RELATION_ID' => $rel['ID']
					));
				}

				if (\CModule::IncludeModule('pull'))
				{
					$pullMessage = Array(
						'module_id' => 'im',
						'command' => 'message',
						'params' => \CIMMessage::GetFormatMessage(Array(
							'ID' => $newRecord['ID'],
							'CHAT_ID' => $chatId,
							'TO_USER_ID' => $arFields['TO_USER_ID'],
							'FROM_USER_ID' => $arFields['FROM_USER_ID'],
							'SYSTEM' => $newRecord['NOTIFY_EVENT'] == 'private_system'? 'Y': 'N',
							'MESSAGE' => $newRecord['MESSAGE'],
							'DATE_CREATE' => time(),
							'PARAMS' => $arFields['PARAMS'],
							'FILES' => $arFields['FILES'],
							'NOTIFY' => true
						)),
						'extra' => \Bitrix\Im\Common::getPullExtra()
					);
					$pullMessageTo = $pullMessage;

					if (\CPullOptions::GetPushStatus())
					{
						if (\CIMSettings::GetNotifyAccess($arFields["TO_USER_ID"], 'im', 'message', \CIMSettings::CLIENT_PUSH))
						{
							$pushParams = $pullMessage;
							$pushParams['params']['message']['text_push'] = $newRecord['MESSAGE'];
							$pushParams = \CIMMessenger::PreparePushForPrivate($pushParams);
							$pullMessageTo = array_merge($pullMessage, $pushParams);
						}
					}

					\Bitrix\Pull\Event::add($arFields['TO_USER_ID'], $pullMessageTo);
					\Bitrix\Pull\Event::add($arFields['FROM_USER_ID'], $pullMessage);

					\CPushManager::DeleteFromQueueBySubTag($arFields['FROM_USER_ID'], 'IM_MESS');
				}
			}
			else if ($arFields['MESSAGE_TYPE'] == IM_MESSAGE_CHAT || $arFields['MESSAGE_TYPE'] == IM_MESSAGE_OPEN || $arFields['MESSAGE_TYPE'] == IM_MESSAGE_OPEN_LINE)
			{
				$chat = \Bitrix\Im\Model\ChatTable::getById($chatId);
				$chatData = $chat->fetch();

				foreach ($arRel as $relation)
				{
					if ($relation["EXTERNAL_AUTH_ID"] == \Bitrix\Im\Bot::EXTERNAL_AUTH_ID)
					{
						continue;
					}
					if ($chatData['ENTITY_TYPE'] == "LINES" && $relation["EXTERNAL_AUTH_ID"] == 'imconnector')
					{
						continue;
					}

					\CIMContactList::SetRecent(Array(
						'ENTITY_ID' => $relation['CHAT_ID'],
						'MESSAGE_ID' => $newRecord['ID'],
						'CHAT_TYPE' => $relation['MESSAGE_TYPE'],
						'USER_ID' => $relation['USER_ID'],
						'CHAT_ID' => $relation['CHAT_ID'],
						'RELATION_ID' => $relation['ID'],
					));
				}

				if (\CModule::IncludeModule('pull'))
				{
					$pullMessage = Array(
						'module_id' => 'im',
						'command' => 'messageChat',
						'params' => \CIMMessage::GetFormatMessage(Array(
							'ID' => $newRecord['ID'],
							'CHAT_ID' => $chatId,
							'TO_CHAT_ID' => $chatId,
							'FROM_USER_ID' => $newRecord['AUTHOR_ID'],
							'MESSAGE' => $newRecord['MESSAGE'],
							'SYSTEM' => $newRecord['AUTHOR_ID'] > 0? 'N': 'Y',
							'DATE_CREATE' => time(),
							'PARAMS' => $arFields['PARAMS'],
							'FILES' => $arFields['FILES'],
							'NOTIFY' => true
						)),
						'extra' => \Bitrix\Im\Common::getPullExtra()
					);

					if ($chatData && \CPullOptions::GetPushStatus())
					{
						$pushParams = $pullMessage;
						$pushParams['params']['message']['text_push'] = $newRecord['MESSAGE'];
						$pushParams = \CIMMessenger::PreparePushForChat($pushParams);
						$pullMessage = array_merge($pullMessage, $pushParams);
					}

					$pullUsers = Array();
					$pullUsersSkip = Array();
					foreach ($arRel as $rel)
					{
						if ($chatData['ENTITY_TYPE'] == "LINES" && $rel["EXTERNAL_AUTH_ID"] == 'imconnector')
						{
						}
						if ($rel['USER_ID'] == $newRecord['AUTHOR_ID'])
						{
							$pullUsers[] = $rel['USER_ID'];
							$pullUsersSkip[] = $rel['USER_ID'];
							\CPushManager::DeleteFromQueueBySubTag($newRecord['AUTHOR_ID'], 'IM_MESS');
						}
						else
						{
							$pullUsers[] = $rel['USER_ID'];
							if ($rel['NOTIFY_BLOCK'] == 'Y' || !\CIMSettings::GetNotifyAccess($rel['USER_ID'], 'im', ($arFields['MESSAGE_TYPE'] == IM_MESSAGE_OPEN? 'openChat': 'chat'), \CIMSettings::CLIENT_PUSH))
							{
								$pullUsersSkip[] = $rel['USER_ID'];
							}
						}
					}
					$pullMessage['push']['skip_users'] = $pullUsersSkip;

					\Bitrix\Pull\Event::add($pullUsers, $pullMessage);

					if ($arFields['MESSAGE_TYPE'] == IM_MESSAGE_OPEN  || $arFields['MESSAGE_TYPE'] == IM_MESSAGE_OPEN_LINE)
					{
						\CPullWatch::AddToStack('IM_PUBLIC_'.$chatId, $pullMessage);
					}

					/*
					\CIMMessenger::SendMention(Array(
						'CHAT_ID' => $chatId,
						'CHAT_TITLE' => $chatData['TITLE'],
						'CHAT_RELATION' => $arRel,
						'CHAT_TYPE' => $chatData['TYPE'],
						'MESSAGE' => $newRecord['MESSAGE'],
						'FILES' => $arFields['FILES'],
						'FROM_USER_ID' => $newRecord['AUTHOR_ID'],
					));
					*/

					foreach(\GetModuleEvents("im", "OnAfterMessagesAdd", true) as $arEvent)
						\ExecuteModuleEventEx($arEvent, array($newRecord['ID'], $newRecord));
				}
			}
		}

		/**
		 * Method will be invoked after an database record updated.
		 *
		 * @param array $oldRecord All fields before update.
		 * @param array $newRecord All fields after update.
		 *
		 * @return void
		 */
		public function afterUpdateTrigger(array $oldRecord, array $newRecord)
		{
			if (!\Bitrix\Main\Loader::includeModule('pull'))
				return;

			if ($oldRecord["MESSAGE"] == self::LOADER_PLACEHOLDER && $newRecord["MESSAGE"] == "")
				return;

			$arFields = \CIMMessenger::GetById($newRecord['ID'], Array('WITH_FILES' => 'Y'));
			if (!$arFields)
				return;

			$relations = \CIMChat::GetRelationById($arFields['CHAT_ID']);

			$arPullMessage = Array(
				'id' => $arFields['ID'],
				'type' => $arFields['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE? 'private': 'chat',
				'text' => \Bitrix\Im\Text::parse($arFields['MESSAGE']),
				'date' => \Bitrix\Main\Type\DateTime::createFromTimestamp($arFields['DATE_CREATE']),
			);
			if ($arFields['MESSAGE_TYPE'] == IM_MESSAGE_PRIVATE)
			{
				$arFields['FROM_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'] = $arFields['FROM_USER_ID'];
				$arPullMessage['toUserId'] = $arFields['TO_USER_ID'];
			}
			else
			{
				$arPullMessage['chatId'] = $arFields['CHAT_ID'];
				$arPullMessage['senderId'] = $arFields['AUTHOR_ID'];

				if ($arFields['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), $p=Array(
				'module_id' => 'im',
				'command' => $arFields['PARAMS']['IS_DELETED']==='Y'? 'messageDelete': 'messageUpdate',
				'params' => $arPullMessage,
				'extra' => \Bitrix\Im\Common::getPullExtra()
			));
			foreach ($relations as $rel)
			{
				$obCache = new \CPHPCache();
				$obCache->CleanDir('/bx/imc/recent'.\CIMMessenger::GetCachePath($rel['USER_ID']));
			}
			if ($newRecord['MESSAGE_TYPE'] == IM_MESSAGE_OPEN || $newRecord['MESSAGE_TYPE'] == IM_MESSAGE_OPEN_LINE)
			{
				\CPullWatch::AddToStack('IM_PUBLIC_'.$arFields['CHAT_ID'], Array(
					'module_id' => 'im',
					'command' => $arFields['PARAMS']['IS_DELETED']==='Y'? 'messageDelete': 'messageUpdate',
					'params' => $arPullMessage,
					'extra' => \Bitrix\Im\Common::getPullExtra()
				));
			}

			foreach(\GetModuleEvents("im", "OnAfterMessagesUpdate", true) as $arEvent)
				\ExecuteModuleEventEx($arEvent, array(intval($newRecord['ID']), $arFields));
		}

		/**
		 * Called before record transformed for log writing.
		 *
		 * @param array &$record Database record.
		 *
		 * @return void
		 */
		public function beforeLogFormat(array &$record)
		{
			global $USER;

			if (\Bitrix\Im\User::getInstance($record['AUTHOR_ID'])->isBot())
			{
				$record['MESSAGE'] = "[b]".\Bitrix\Im\User::getInstance($record['AUTHOR_ID'])->getFullName()."[/b] \n ".$record['MESSAGE'];
				$record['AUTHOR_ID'] = 0;
			}
		}
	}
}

Zerion Mini Shell 1.0