• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/lib/integration/forum/task/comment.php
  • Класс: BitrixTasksIntegrationForumTaskComment
  • Вызов: Comment::onAfterAdd
static function onAfterAdd($entityType, $taskId, $arData)
{
	static $parser = null;

	// 'TK' is our entity type
	if ($entityType !== 'TK')
	{
		return;
	}

	if (!(CTaskAssert::isLaxIntegers($taskId) && ((int) $taskId >= 1)))
	{
		CTaskAssert::logWarning('[0xc4b31fa6] Expected integer $taskId >= 1');
		return;
	}

	$arData['PARAMS'] = (isset($arData['PARAMS']) && is_array($arData['PARAMS']) ? $arData['PARAMS'] : []);

	$aux = (isset($arData['PARAMS']['AUX']) && $arData['PARAMS']['AUX'] == "Y");
	$isFileVersionUpdateComment = (
		isset($arData['PARAMS']['UF_FORUM_MESSAGE_VER'])
		&& !empty($arData['PARAMS']['UF_FORUM_MESSAGE_VER'])
	);
	$messageId  = $arData['MESSAGE_ID'];
	$strMessage = $arData['PARAMS']['POST_MESSAGE'];

	if ($parser === null)
	{
		$parser = new CTextParser();
	}

	$messageAuthorId = null;
	$messageEditDate = null;
	$messagePostDate = null;

	if (
		array_key_exists('AUTHOR_ID', $arData['PARAMS'])
		&& array_key_exists('EDIT_DATE', $arData['PARAMS'])
		&& array_key_exists('POST_DATE', $arData['PARAMS'])
	)
	{
		$messageAuthorId = $arData['PARAMS']['AUTHOR_ID'];
		$messageEditDate = $arData['PARAMS']['POST_DATE'];
	}
	else
	{
		$arMessage = CForumMessage::GetByID($messageId);

		$messageAuthorId = $arMessage['AUTHOR_ID'];
		$messageEditDate = $arMessage['POST_DATE'];
	}

	$occurAsUserId = static::getOccurAsId($messageAuthorId);
	$messageEditDateTimeStamp = MakeTimeStamp($messageEditDate, CSite::GetDateFormat()) - CTimeZone::getOffset();

	if (
		isset($arData['MESSAGE']['SERVICE_DATA'])
		&& $arData['MESSAGE']['SERVICE_DATA'] === ResultManager::COMMENT_SERVICE_DATA
	)
	{
		(new ResultManager(User::getId()))->createFromComment((int)$messageId);
	}

	TaskTable::update($taskId, ['ACTIVITY_DATE' => DateTime::createFromTimestamp($messageEditDateTimeStamp)]);

	try
	{
		$oTask = new CTaskItem($taskId, User::getAdminId());
		$arTask = $oTask->getData();
	}
	catch (TasksException | CTaskAssertException $e)
	{
		return;
	}

	if ($arTask['GROUP_ID'] > 0)
	{
		ProjectLastActivityTable::update(
			$arTask['GROUP_ID'],
			['ACTIVITY_DATE' => DateTime::createFromTimestamp($messageEditDateTimeStamp)]
		);
	}

	if (!$aux)
	{
		SearchIndex::setCommentSearchIndex($taskId, $messageId, $strMessage);
	}

	// sonet log
	if (
		Socialnetwork::includeModule()
		&& (
			SocialNetwork::isEnabled()
			|| $aux
		)
	)
	{
		$bCrmTask = (
			isset($arTask["UF_CRM_TASK"])
			&& (
				(
					is_array($arTask["UF_CRM_TASK"])
					&& (
						isset($arTask["UF_CRM_TASK"][0])
						&& $arTask["UF_CRM_TASK"][0] <> ''
					)
				)
				||
				(
					!is_array($arTask["UF_CRM_TASK"])
					&& $arTask["UF_CRM_TASK"] <> ''
				)
			)
		);

		if (!$bCrmTask)
		{
			$dbRes = CSocNetLog::getList(
				array("ID" => "DESC"),
				array(
					"EVENT_ID" => "tasks",
					"SOURCE_ID" => $taskId
				),
				false,
				false,
				array("ID", "ENTITY_TYPE", "ENTITY_ID", "TMP_ID")
			);
			if ($arRes = $dbRes->fetch())
			{
				$log_id = $arRes["ID"];
				$entity_type = $arRes["ENTITY_TYPE"];
				$entity_id = $arRes["ENTITY_ID"];
			}
			else
			{
				$entity_type = ($arTask["GROUP_ID"] ? SONET_ENTITY_GROUP : SONET_ENTITY_USER);
				$entity_id = ($arTask["GROUP_ID"] ? $arTask["GROUP_ID"] : $arTask["CREATED_BY"]);

				// todo: refactor when user cache implemented
				$rsUser = CUser::getByID($arTask["CREATED_BY"]);
				if ($arUser = $rsUser->fetch())
				{
					$arSoFields = array(
						"ENTITY_TYPE" => $entity_type,
						"ENTITY_ID" => $entity_id,
						"EVENT_ID" => "tasks",
						"LOG_DATE" => $arTask["CREATED_DATE"],
						"TITLE_TEMPLATE" => "#TITLE#",
						"TITLE" => $arTask["TITLE"],
						"MESSAGE" => "",
						"TEXT_MESSAGE" => '',// $strMsgNewTask,
						"MODULE_ID" => "tasks",
						"CALLBACK_FUNC" => false,
						"SOURCE_ID" => $taskId,
						"ENABLE_COMMENTS" => "Y",
						"USER_ID" => $arTask["CREATED_BY"],
						"URL" => CTaskNotifications::getNotificationPath($arUser, $taskId),
						"PARAMS" => serialize(array("TYPE" => "create"))
					);
					$log_id = CSocNetLog::Add($arSoFields, false);
					if (intval($log_id) > 0)
					{
						CSocNetLog::Update($log_id, array("TMP_ID" => $log_id));
						$arRights = CTaskNotifications::__UserIDs2Rights(static::getTaskMembersByTaskId($taskId));
						if($arTask["GROUP_ID"])
						{
							$arRights[] = "S".SONET_ENTITY_GROUP.$arTask["GROUP_ID"];
						}
						CSocNetLogRights::Add($log_id, $arRights);
					}
				}
			}
		}

		if ((int)($log_id ?? null) > 0)
		{
			$filtered = (COption::GetOptionString("forum", "FILTER", "Y") == "Y");
			$sText = ($filtered ? $arMessage["POST_MESSAGE_FILTER"] : $arMessage["POST_MESSAGE"]);
			$arTagInline = $parser->detectTags($sText);

			CSocNetLog::Update(
				$log_id,
				array(
					'PARAMS' => serialize(array('TYPE' => 'comment'))
				)
			);

			// todo: some garbage?
			$strURL = $GLOBALS['APPLICATION']->getCurPageParam("", array("IFRAME", "IFRAME_TYPE", "MID", "SEF_APPLICATION_CUR_PAGE_URL", BX_AJAX_PARAM_ID, "result"));
			$strURL = ForumAddPageParams(
				$strURL,
				array(
					"MID" => $messageId,
					"result" => "reply"
				),
				false,
				false
			);

			$arFieldsForSocnet = array(
				"ENTITY_TYPE" => $entity_type,
				"ENTITY_ID" => $entity_id,
				"EVENT_ID" => "tasks_comment",
				"MESSAGE" => $sText,
				"TEXT_MESSAGE" => $parser->convert4mail($sText),
//					"URL" => str_replace("?IFRAME=Y", "", str_replace("&IFRAME=Y", "", str_replace("IFRAME=Y&", "", $strURL))),
				"MODULE_ID" => "tasks",
				"SOURCE_ID" => $messageId,
				"LOG_ID" => $log_id,
				"RATING_TYPE_ID" => "FORUM_POST",
				"RATING_ENTITY_ID" => $messageId
			);

			if (!empty($arTagInline))
			{
				$arFieldsForSocnet["TAG"] = $arTagInline;
			}

			$arFieldsForSocnet["USER_ID"] = $occurAsUserId;
			$arFieldsForSocnet["=LOG_DATE"] = $GLOBALS['DB']->CurrentTimeFunction();

			$ufFileID = array();
			$dbAddedMessageFiles = CForumFiles::GetList(array("ID" => "ASC"), array("MESSAGE_ID" => $messageId));
			while ($arAddedMessageFiles = $dbAddedMessageFiles->Fetch())
			{
				$ufFileID[] = $arAddedMessageFiles["FILE_ID"];
			}

			if (count($ufFileID) > 0)
			{
				$arFieldsForSocnet["UF_SONET_COM_FILE"] = $ufFileID;
			}

			$ufDocID = $GLOBALS["USER_FIELD_MANAGER"]->GetUserFieldValue("FORUM_MESSAGE", "UF_FORUM_MESSAGE_DOC", $messageId, LANGUAGE_ID);
			if ($ufDocID)
			{
				$arFieldsForSocnet["UF_SONET_COM_DOC"] = $ufDocID;
			}

			$ufUrlPreview = $GLOBALS["USER_FIELD_MANAGER"]->GetUserFieldValue("FORUM_MESSAGE", "UF_FORUM_MES_URL_PRV", $messageId, LANGUAGE_ID);
			if ($ufUrlPreview)
			{
				$signer = new BitrixMainSecuritySignSigner();
				$arFieldsForSocnet["UF_SONET_COM_URL_PRV"] = $signer->sign((string)$ufUrlPreview, BitrixMainUrlPreviewUrlPreview::SIGN_SALT);
			}

			$ufVersionId = $GLOBALS["USER_FIELD_MANAGER"]->GetUserFieldValue("FORUM_MESSAGE", "UF_FORUM_MESSAGE_VER", $messageId, LANGUAGE_ID);
			if ($ufVersionId)
			{
				$arFieldsForSocnet["UF_SONET_COM_VER"] = $ufVersionId;
			}

			if (!empty($arData['AUX_DATA']))
			{
				$arFieldsForSocnet['MESSAGE'] = $arFieldsForSocnet['TEXT_MESSAGE'] = BitrixSocialnetworkCommentAuxTaskInfo::getPostText();
			}

			$comment_id = CSocNetLogComments::Add($arFieldsForSocnet, [
				'SET_SOURCE' => false,
				'SEND_EVENT' => false,
				'SUBSCRIBE' => false,
			]);

			if (BitrixSocialnetworkComponentHelper::checkLivefeedTasksAllowed())
			{
				$bHasAccessAll = CSocNetLogRights::CheckForUserAll($log_id);
				$arUserIdToPush = array();

				if (!$bHasAccessAll)
				{
					$dbRight = CSocNetLogRights::GetList(array(), array("LOG_ID" => $log_id));
					while ($arRight = $dbRight->Fetch())
					{
						if (preg_match('/^U(d+)$/', $arRight["GROUP_CODE"], $matches))
						{
							$arUserIdToPush[] = $matches[1];
						}
						elseif (!in_array($arRight["GROUP_CODE"], array("SA")))
						{
							$arUserIdToPush = array();
							break;
						}
					}
				}

				$isNew = false;
				if (
					isset($_POST['ACTION'][0]['OPERATION'])
					&& $_POST['ACTION'][0]['OPERATION'] === 'task.add'
				)
				{
					$isNew = true;
				}

				if (!$isNew)
				{
					CSocNetLog::CounterIncrement(
						$comment_id,
						false,
						false,
						"LC",
						$bHasAccessAll
					);
				}
			}
		}

		if (
			array_key_exists('GROUP_ID', $arTask)
			&& $arTask['GROUP_ID']
		)
		{
			CSocNetGroup::SetLastActivity((int)$arTask['GROUP_ID']);
		}
	}

	$commentType = CommentsInternalsComment::TYPE_DEFAULT;
	if (isset($arData['PARAMS']['UF_TASK_COMMENT_TYPE']) && !empty($arData['PARAMS']['UF_TASK_COMMENT_TYPE']))
	{
		$commentType = (int)$arData['PARAMS']['UF_TASK_COMMENT_TYPE'];
	}

	$isPingComment = 'N';
	if ($aux)
	{
		$commentReader = CommentsTaskCommentReader::getInstance($taskId, $messageId);
		$commentReader->setCommentData([
			'MESSAGE' => '',
			'AUTHOR_ID' => (int)$messageAuthorId,
			'TYPE' => $commentType,
			'AUX_DATA' => (is_array($arData['AUX_DATA']) ? serialize($arData['AUX_DATA']) : $arData['AUX_DATA']),
		]);

		$isPingComment = ($commentReader->isContainCodes(['COMMENT_POSTER_COMMENT_TASK_PINGED_STATUS']) ? 'Y' : 'N');
		$arData['PARAMS']['IS_PING_COMMENT'] = $isPingComment;
	}

	if ((!$aux && !$isFileVersionUpdateComment) || $isPingComment === 'Y')
	{
		UserOption::delete($taskId, (int)$messageAuthorId, UserOptionOption::MUTED);
	}

	$recipientsIds = static::getTaskMembersByTaskId($taskId, $occurAsUserId);
	$userIdToShareList = static::processMentions($arData);

	if (is_array($userIdToShareList))
	{
		foreach ($userIdToShareList as $userId)
		{
			$viewedDate = DateTime::createFromTimestamp($messageEditDateTimeStamp);
			$viewedDate->addSecond(-1);

			ViewedTable::set($taskId, $userId, $viewedDate);
		}

		$recipientsIds = array_merge($recipientsIds, $userIdToShareList);
	}

	$newCommentsCount = CommentsTask::getNewCommentsCountForTasks([$taskId], (int)$messageAuthorId);
	if (!$newCommentsCount[$taskId])
	{
		ViewedTable::set($taskId, (int)$messageAuthorId, DateTime::createFromTimestamp($messageEditDateTimeStamp));
	}

	CounterCounterService::addEvent(
		CounterEventEventDictionary::EVENT_AFTER_COMMENT_ADD,
		[
			'TASK_ID' => (int) $taskId,
			'USER_ID' => (int) $occurAsUserId,
			'SERVICE_TYPE' => $commentType
		]
	);

	$isCompleteComment = false;
	if ($aux)
	{
		$commentReader->read();
		$isCompleteComment = $commentReader->isContainCodes([
			'COMMENT_POSTER_COMMENT_TASK_UPDATE_STATUS_5_V2',
			'COMMENT_POSTER_COMMENT_TASK_UPDATE_STATUS_5_APPROVE_V2',
		]);
	}

	if (Loader::includeModule('pull'))
	{
		$taskParticipants = array_unique(array_merge($recipientsIds, [$occurAsUserId]));

		$groupId = (int)$arTask['GROUP_ID'];
		$pushRecipients = $taskParticipants;
		if ($groupId > 0)
		{
			$pushRecipients = array_unique(
				array_merge(
					$taskParticipants,
					SocialNetworkUser::getUsersCanPerformOperation($groupId, 'view_all')
				)
			);
		}

		PushService::addEvent($pushRecipients, [
			'module_id' => 'tasks',
			'command' => PushCommand::COMMENT_ADDED,
			'params' => [
				'taskId' => $taskId,
				'entityXmlId' => $arData['PARAMS']['XML_ID'],
				'ownerId' => $occurAsUserId,
				'messageId' => $messageId,
				'groupId' => $groupId,
				'participants' => $taskParticipants,
				'pullComment' => ($commentType !== CommentsInternalsComment::TYPE_EXPIRED),
				'isCompleteComment' => $isCompleteComment,
			],
		]);
	}

	if (!$aux)
	{
		$messageData = ['ID' => $messageId, 'POST_MESSAGE' => $strMessage];
		static::sendNotification($messageData, $arTask, $occurAsUserId, $recipientsIds, $arData);
	}

	if ((!$aux && !$isFileVersionUpdateComment) || $isPingComment === 'Y')
	{
		self::addToAuditor((int)$messageAuthorId, (int)$taskId);
	}

	if (!isset($arData['replica']))
	{
		static::addLogItem(array(
			"TASK_ID" => $taskId,
			"USER_ID" => $occurAsUserId,
			"CREATED_DATE" => (
				$messageEditDate
					? ConvertTimeStamp(MakeTimeStamp($messageEditDate, CSite::GetDateFormat()), "FULL")
					: $messagePostDate
			),
			"FIELD" => "COMMENT",
			"TO_VALUE" => $messageId
		));

		$fileIds = [];
		$urlPreviewId = '';

		if (isset($arData['PARAMS']['UF_FORUM_MESSAGE_DOC']) && !empty($arData['PARAMS']['UF_FORUM_MESSAGE_DOC']))
		{
			$fileIds = $arData['PARAMS']['UF_FORUM_MESSAGE_DOC'];
		}
		if (isset($arData['PARAMS']['UF_FORUM_MES_URL_PRV']) && !empty($arData['PARAMS']['UF_FORUM_MES_URL_PRV']))
		{
			$urlPreviewId = $arData['PARAMS']['UF_FORUM_MES_URL_PRV'];
		}

		static::fireEvent('Add', $taskId, $arData, $fileIds, $urlPreviewId);
		// skip system comments
		if (!isset($arData['PARAMS']['AUX']) || $arData['PARAMS']['AUX'] !== 'Y')
		{
			$message = ForumMessageTable::getById($messageId)->fetchObject();
			(new TimeLineManager($taskId, $occurAsUserId))->onTaskCommentAdd($message)->save();
		}
	}
}