static function SendMessageToSocNet($arFields, $bSpawnedByAgent, $arChanges = null, $arTask = null, array $parameters = array())
{
global $DB;
$effectiveUserId = self::getEffectiveUserId($arFields, array(), $bSpawnedByAgent, $parameters);
if ( ! CModule::IncludeModule('socialnetwork') )
return (null);
$arLogFilter = array();
$bCrmTask = false;
if (!empty($arTask))
{
$bCrmTask = self::isCrmTask($arTask);
$arLogFilter = self::getSonetLogFilter($arTask["ID"], $bCrmTask);
if (empty($arLogFilter))
{
return (null);
}
}
static $arCheckedUsers = array(); // users that checked for their existing
static $cachedSiteTimeFormat = -1;
// select "real" author
$occurAsUserId = CTasksTools::getOccurAsUserId();
if ( ! $occurAsUserId )
$occurAsUserId = $effectiveUserId;
if ($cachedSiteTimeFormat === -1)
$cachedSiteTimeFormat = CSite::GetDateFormat('FULL', SITE_ID);
static $cachedAllSitesIds = -1;
if ($cachedAllSitesIds === -1)
{
$cachedAllSitesIds = array();
$dbSite = CSite::GetList(
'sort',
'desc',
array('ACTIVE' => 'Y')
);
while ($arSite = $dbSite->Fetch())
$cachedAllSitesIds[] = $arSite['ID'];
}
// Check that user exists
if ( ! in_array( (int) $arFields["CREATED_BY"], $arCheckedUsers, true) )
{
$rsUser = CUser::GetList(
'ID',
'ASC',
array('ID' => $arFields["CREATED_BY"]),
array('FIELDS' => array('ID'))
);
if ( ! ($arUser = $rsUser->Fetch()) )
return (false);
$arCheckedUsers[] = (int) $arFields["CREATED_BY"];
}
if (is_array($arChanges))
{
if (!empty($arLogFilter) && empty($arChanges))
{
$rsSocNetLogItems = CSocNetLog::GetList(
["ID" => "DESC"],
$arLogFilter,
false,
false,
["ID", "ENTITY_TYPE", "ENTITY_ID"]
);
while ($log = $rsSocNetLogItems->Fetch())
{
$logId = (int)$log['ID'];
$authorId = (
isset($arFields['CREATED_BY']) ? (int)$arFields['CREATED_BY'] : (int)$arTask['CREATED_BY']
);
$oldForumTopicId = $arTask['FORUM_TOPIC_ID'];
$newForumTopicId = ($arFields['FORUM_TOPIC_ID'] ?? null);
$forumTopicAdded = $oldForumTopicId == 0 && isset($newForumTopicId) && $newForumTopicId > 0;
// Add author to list of users that view log about task in livefeed
// But only when some other person change task
// or if added FORUM_TOPIC_ID
if (($authorId !== $effectiveUserId) || $forumTopicAdded)
{
$authorGroupCode = 'U'.$authorId;
$rightsResult = CSocNetLogRights::GetList([], [
'LOG_ID' => $logId,
'GROUP_CODE' => $authorGroupCode,
]);
// If task's author hasn't rights yet, give them
if (!$rightsResult->fetch())
{
$follow = !UserOption::isOptionSet($arTask['ID'], $authorId, (UserOptionOption::MUTED));
CSocNetLogRights::Add($logId, [$authorGroupCode], false, $follow);
}
}
}
return null;
}
if (count($arChanges) === 1 && isset($arChanges['STATUS']))
{
return null; // if only status changes - don't send message, because it will be sent by SendStatusMessage()
}
}
if ($bSpawnedByAgent === 'Y')
$bSpawnedByAgent = true;
elseif ($bSpawnedByAgent === 'N')
$bSpawnedByAgent = false;
if ( ! is_bool($bSpawnedByAgent) )
return (false);
$taskId = false;
if (is_array($arFields) && isset($arFields['ID']) && ($arFields['ID'] > 0))
$taskId = $arFields['ID'];
elseif (is_array($arTask) && isset($arTask['ID']) && ($arTask['ID'] > 0))
$taskId = $arTask['ID'];
// We will mark this to false, if we send update message and log item already exists
$bSocNetAddNewItem = true;
$logDate = $DB->CurrentTimeFunction();
$curTimeTimestamp = time() + CTimeZone::GetOffset();
if (!$bCrmTask)
{
$arSoFields = array(
'EVENT_ID' => 'tasks',
'TITLE' => $arFields['TITLE'],
'MESSAGE' => '',
'MODULE_ID' => 'tasks'
);
}
else
{
$arSoFields = array();
}
// If changes and task data given => we are prepare "update" message,
// or "add" message otherwise
if (is_array($arChanges) && is_array($arTask))
{ // Prepare "update" message here
if ($arFields["CHANGED_DATE"] <> '')
{
$createdDateTimestamp = MakeTimeStamp(
$arFields["CHANGED_DATE"],
$cachedSiteTimeFormat
);
if ($createdDateTimestamp > $curTimeTimestamp)
{
$logDate = BitrixTasksUtilDb::charToDateFunction(
$arFields["CHANGED_DATE"],
"FULL",
SITE_ID
);
}
}
$arChangesFields = array_keys($arChanges);
$arSoFields['TEXT_MESSAGE'] = str_replace(
'#CHANGES#',
implode(
', ',
CTaskNotifications::__Fields2Names($arChangesFields)
),
GetMessage('TASKS_SONET_TASK_CHANGED_MESSAGE')
);
if (!$bCrmTask)
{
if (
(($arFields["GROUP_ID"] ?? null) === null && $arTask['GROUP_ID']) // If tasks has group and it not deleted
|| ($arFields['GROUP_ID'] ?? null) // Or new group_id set
)
{
$arSoFields["ENTITY_TYPE"] = SONET_ENTITY_GROUP;
$arSoFields["ENTITY_ID"] = (($arFields["GROUP_ID"] ?? null) ?: $arTask['GROUP_ID']);
}
else
{
$arSoFields["ENTITY_TYPE"] = SONET_ENTITY_USER;
$arSoFields["ENTITY_ID"] = ($arFields["CREATED_BY"] ?: $arTask["CREATED_BY"]);
}
}
$arSoFields['PARAMS'] = serialize([
'TYPE' => 'modify',
'CHANGED_FIELDS' => $arChangesFields,
'CREATED_BY' => ($arFields["CREATED_BY"] ?: $arTask["CREATED_BY"]),
'CHANGED_BY' => ($occurAsUserId ?: $arFields['CHANGED_BY']),
'PREV_REAL_STATUS' => ($arTask['REAL_STATUS'] ?? false),
]);
if (!empty($arLogFilter))
{
// Determine, does item exists in sonet log
$rsSocNetLogItems = CSocNetLog::GetList(
array("ID" => "DESC"),
$arLogFilter,
false,
false,
array("ID", "ENTITY_TYPE", "ENTITY_ID")
);
if ($rsSocNetLogItems->Fetch())
{
$bSocNetAddNewItem = false; // item already exists, update it, not create.
}
}
}
else // Prepare "add" message here
{
if (($arFields["CREATED_DATE"] ?? null) <> '')
{
$createdDateTimestamp = MakeTimeStamp(
$arFields["CREATED_DATE"],
$cachedSiteTimeFormat
);
if ($createdDateTimestamp > $curTimeTimestamp)
{
$logDate = BitrixTasksUtilDb::charToDateFunction(
$arFields["CREATED_DATE"],
"FULL",
SITE_ID
);
}
}
$arSoFields['TEXT_MESSAGE'] = GetMessage('TASKS_SONET_NEW_TASK_MESSAGE');
if (isset($arFields["GROUP_ID"]) && $arFields["GROUP_ID"])
{
$arSoFields["ENTITY_TYPE"] = SONET_ENTITY_GROUP;
$arSoFields["ENTITY_ID"] = $arFields["GROUP_ID"];
}
else
{
$arSoFields["ENTITY_TYPE"] = SONET_ENTITY_USER;
$arSoFields["ENTITY_ID"] = $arFields["CREATED_BY"];
}
$arParamsLog = array(
'TYPE' => 'create',
'CREATED_BY' => ($arFields["CREATED_BY"] ?: $arTask["CREATED_BY"]),
'PREV_REAL_STATUS' => $arTask['REAL_STATUS'] ?? false
);
if ($occurAsUserId)
{
$arParamsLog["CREATED_BY"] = $occurAsUserId;
}
$arSoFields['PARAMS'] = serialize($arParamsLog);
}
// rating entity id (ilike)
$arSoFields["RATING_ENTITY_ID"] = $taskId;
$arSoFields["RATING_TYPE_ID"] = "TASK";
if (IsModuleInstalled("webdav") || IsModuleInstalled("disk"))
{
$ufDocID = $GLOBALS["USER_FIELD_MANAGER"]->GetUserFieldValue("TASKS_TASK", "UF_TASK_WEBDAV_FILES", $taskId, LANGUAGE_ID);
if ($ufDocID)
{
$arSoFields["UF_SONET_LOG_DOC"] = $ufDocID;
}
}
// Do we need add new item to socnet?
// We adds new item, if it is not exists.
$logId = false;
if ($bSocNetAddNewItem)
{
$arSoFields['=LOG_DATE'] = $logDate;
$arSoFields['CALLBACK_FUNC'] = false;
$arSoFields['SOURCE_ID'] = $taskId;
$arSoFields['ENABLE_COMMENTS'] = 'Y';
$arSoFields['URL'] = ''; // url is user-specific, cant keep in database
$arSoFields['USER_ID'] = $arFields['CREATED_BY'];
$arSoFields['TITLE_TEMPLATE'] = '#TITLE#';
// Set all sites because any user from any site may be
// added to task in future. For example, new auditor, etc.
$arSoFields['SITE_ID'] = $cachedAllSitesIds;
$logId = (int)CSocNetLog::Add($arSoFields, false);
if ($logId > 0)
{
$logFields = [
'TMP_ID' => $logId,
'TAG' => [],
];
$tagsResult = CTaskTags::getList([], ['TASK_ID' => $taskId]);
while ($row = $tagsResult->fetch())
{
$logFields['TAG'][] = $row['NAME'];
}
CSocNetLog::Update($logId, $logFields);
$taskMembers = CTaskNotifications::GetRecipientsIDs($arFields, false);
$logCanViewedBy = (
self::$sonetLogNotifyAuthor
? $taskMembers
: array_diff($taskMembers, [$arFields['CREATED_BY']])
);
$rights = CTaskNotifications::__UserIDs2Rights($logCanViewedBy);
if (isset($arFields['GROUP_ID']))
{
$rights = array_merge(
$rights,
self::prepareRightsCodesForViewInGroupLiveFeed($logId, $arFields['GROUP_ID'])
);
}
CSocNetLogRights::Add($logId, $rights);
CSocNetLog::SendEvent($logId, "SONET_NEW_EVENT", $logId);
}
}
elseif (!empty($arLogFilter)) // Update existing log item
{
$arSoFields['=LOG_DATE'] = $logDate;
$arSoFields['=LOG_UPDATE'] = $logDate;
// All tasks posts in live feed should be from director
if (isset($arFields['CREATED_BY']))
{
$arSoFields['USER_ID'] = $arFields['CREATED_BY'];
}
else if (isset($arTask['CREATED_BY']))
{
$arSoFields['USER_ID'] = $arTask['CREATED_BY'];
}
else if ($occurAsUserId)
{
$arSoFields['USER_ID'] = $occurAsUserId;
}
else
{
unset($arSoFields['USER_ID']);
}
$rsSocNetLogItems = CSocNetLog::GetList(
["ID" => "DESC"],
$arLogFilter,
false,
false,
["ID", "ENTITY_TYPE", "ENTITY_ID"]
);
while ($log = $rsSocNetLogItems->Fetch())
{
$logId = (int)$log['ID'];
$arSoFields['TAG'] = [];
$tagsResult = CTaskTags::getList([], ['TASK_ID' => $taskId]);
while ($tag = $tagsResult->fetch())
{
$arSoFields['TAG'][] = $tag['NAME'];
}
CSocNetLog::Update($logId, $arSoFields);
$params = [
'LOG_ID' => $logId,
'EFFECTIVE_USER_ID' => $effectiveUserId,
];
self::setSonetLogRights($params, $arFields, $arTask);
}
}
return ($logId);
}