• Модуль: calendar
  • Путь к файлу: ~/bitrix/modules/calendar/classes/general/calendar_livefeed.php
  • Класс: CCalendarLiveFeed
  • Вызов: CCalendarLiveFeed::OnEditCalendarEventEntry
static function OnEditCalendarEventEntry($params): void
{
	$eventId = (int)$params['eventId'];

	$currentEvent = CCalendarEvent::GetList(
		[
			'arFilter' => [
				"PARENT_ID" => $eventId,
				"ID" => $eventId,
				"DELETED" => "N",
			],
			'parseRecursion' => false,
			'fetchAttendees' => true,
			'fetchMeetings' => true,
			'checkPermissions' => false,
			'setDefaultLimit' => false,
		]
	);

	if ($currentEvent && count($currentEvent) > 0)
	{
		$currentEvent = $currentEvent[0];
	}
	$arFields = $params['arFields'];
	$attendeesCodes = $params['attendeesCodes'];

	if (isset($attendeesCodes) && !is_array($attendeesCodes))
	{
		$attendeesCodes = explode(',', $attendeesCodes);
	}
	if (empty($attendeesCodes) && $arFields['CREATED_BY'])
	{
		$attendeesCodes[] = 'U' . (int)$arFields['CREATED_BY'];
	}
	if (!is_array($attendeesCodes))
	{
		$attendeesCodes = [];
	}

	$folowersList = [];
	$unfolowersList = [];

	if (
		$currentEvent['IS_MEETING']
		&& !empty($currentEvent['ATTENDEE_LIST'])
		&& is_array($currentEvent['ATTENDEE_LIST'])
	)
	{
		foreach ($currentEvent['ATTENDEE_LIST'] as $attendee)
		{
			if ($attendee['status'] !== 'N')
			{
				$folowersList[] = (int)$attendee['id'];
			}
			else
			{
				$unfolowersList[] = $attendee['id'];
			}
		}
	}
	else
	{
		$folowersList[] = (int)$arFields['CREATED_BY'];
	}

	$newlogId = false;

	if ($eventId > 0)
	{
		$arSoFields = Array(
			"ENTITY_ID" => $arFields["CREATED_BY"],
			"USER_ID" => $arFields["CREATED_BY"],
			"=LOG_DATE" => CDatabase::CurrentTimeFunction(),
			"TITLE_TEMPLATE" => "#TITLE#",
			"TITLE" => $arFields["NAME"],
			"MESSAGE" => "",
			"TEXT_MESSAGE" => ""
		);

		$arAccessCodes = [];
		foreach ($attendeesCodes as $value)
		{
			$arAccessCodes[] = ($value === "UA") ? "G2" : $value;
		}

		$dbRes = CSocNetLog::GetList(
			array("ID" => "DESC"),
			array(
				"EVENT_ID" => "calendar",
				"SOURCE_ID" => $eventId
			),
			false,
			false,
			array("ID")
		);

		$arCodes = [];
		foreach ($arAccessCodes as $value)
		{
			if (mb_strpos($value, 'U') === 0)
			{
				$attendeeId = (int)mb_substr($value, 1);
				if (in_array($attendeeId, $folowersList, true))
				{
					$arCodes[] = $value;
				}
			}
			else
			{
				if (mb_strpos($value, 'SG') === 0)
				{
					$arCodes[] = $value . '_K';
				}
				$arCodes[] = $value;
			}
		}

		if (
			$arFields['IS_MEETING']
			&& $arFields['MEETING_HOST']
			&& !in_array('U' . $arFields['MEETING_HOST'], $arCodes, true)
		)
		{
			$arCodes[] = 'U'.$arFields['MEETING_HOST'];
		}
		$arCodes = array_unique($arCodes);

		if ($arRes = $dbRes->Fetch())
		{
			if (
				isset($arRes["ID"])
				&& (int)$arRes["ID"] > 0
			)
			{
				CSocNetLog::Update($arRes["ID"], $arSoFields);
				CSocNetLogRights::DeleteByLogID($arRes["ID"]);
				CSocNetLogRights::Add($arRes["ID"], $arCodes);

				foreach ($unfolowersList as $value)
				{
					CSocNetLogFollow::Set((int)$value, "L" . $arRes["ID"], 'N');
				}
			}
		}
		else
		{
			$arSoFields = array_merge($arSoFields, array(
				"ENTITY_TYPE" => SONET_SUBSCRIBE_ENTITY_USER,
				"EVENT_ID" => "calendar",
				"SITE_ID" => SITE_ID,
				"SOURCE_ID" => $eventId,
				"ENABLE_COMMENTS" => "Y",
				"CALLBACK_FUNC" => false,
				"PARAMS" => $arFields['RELATIONS'] ?? '',
			));

			$newlogId = CSocNetLog::Add($arSoFields, false);
			CSocNetLogRights::Add($newlogId, $arCodes);

			// Increment counter in live feed (mantis:#108212)
			CSocNetLog::counterIncrement(array(
				"ENTITY_ID" => $newlogId,
				"EVENT_ID" => 'calendar',
				"TYPE" => "L",
				"FOR_ALL_ACCESS" => false,
				"SEND_TO_AUTHOR" => "N"
			));

			if (!empty($arFields['RELATIONS']) && Loader::includeModule('forum'))
			{
				$commentsXmlId = CCalendarEvent::GetEventCommentXmlId($arFields);
				$calendarSettings = CCalendar::GetSettings();
				$forumID = $calendarSettings['forum_id'] ?? null;

				CForumTopic::Add([
					'TITLE' => $commentsXmlId,
					'TAGS' => '',
					'MESSAGE' => $commentsXmlId,
					'AUTHOR_ID' => 0,
					'AUTHOR_NAME' => 'SYSTEM',
					'FORUM_ID' => $forumID,
					'USER_START_ID' => 0,
					'USER_START_NAME' => 'SYSTEM',
					'LAST_POSTER_NAME' => 'SYSTEM',
					'XML_ID' => $commentsXmlId,
					'APPROVED' => 'Y',
				]);
			}

			foreach ($unfolowersList as $value)
			{
				CSocNetLogFollow::Set((int)$value, "L" . $newlogId, 'N');
			}
		}

		// Find if we already have socialnetwork livefeed entry for this event
		if ($newlogId && ($arFields['RECURRENCE_ID'] ?? null) > 0)
		{
			$commentXmlId = false;
			if (!empty($arFields['RELATIONS']))
			{
				if (!isset($arFields['~RELATIONS']) || !is_array($arFields['~RELATIONS']))
				{
					$arFields['~RELATIONS'] = unserialize($arFields['RELATIONS'], ['allowed_classes' => false]);
				}
				if (is_array($arFields['~RELATIONS']) && array_key_exists('COMMENT_XML_ID', $arFields['~RELATIONS']) && $arFields['~RELATIONS']['COMMENT_XML_ID'])
				{
					$commentXmlId = $arFields['~RELATIONS']['COMMENT_XML_ID'];
				}
			}

			$dbRes = CSocNetLog::GetList(
				array("ID" => "DESC"),
				array(
					"EVENT_ID" => "calendar",
					"SOURCE_ID" => $arFields['RECURRENCE_ID']
				),
				false,
				false,
				array("ID", "SOURCE_ID", "PARAMS", "COMMENTS_COUNT")
			);


			$event = CCalendarEvent::GetById($arFields['RECURRENCE_ID']);

			$rrule = CCalendarEvent::ParseRRULE($event['RRULE'] ?? null);
			$until = $rrule['~UNTIL'] ?? null;

			while ($arRes = $dbRes->Fetch())
			{
				if (isset($arRes['PARAMS']) && is_string($arRes['PARAMS']))
				{
					$arRes['PARAMS'] = unserialize($arRes['PARAMS'], ['allowed_classes' => false]);
					if (!is_array($arRes['PARAMS']))
					{
						$arRes['PARAMS'] = [];
					}
				}

				if (isset($arRes['PARAMS']['COMMENT_XML_ID']))
				{
					if ($commentXmlId && $arRes['PARAMS']['COMMENT_XML_ID'] === $commentXmlId)
					{
						// Move comments from old entry to new one
						CSocNetLogComments::BatchUpdateLogId($arRes['ID'], $newlogId);

						// Delete old entry
						CSocNetLog::Delete($arRes['ID']);

						// Update comments count for new entry
						// And put COMMENT_XML_ID from old antry to preserve syncrinization
						CSocNetLog::Update($newlogId, array(
							"COMMENTS_COUNT" => (int)($arRes['COMMENTS_COUNT'] ?? 0),
							"PARAMS" => serialize(array(
								"COMMENT_XML_ID" => $commentXmlId
							))
						));
					}
					else
					{
						$instanceDate = CCalendarEvent::ExtractDateFromCommentXmlId($arRes['PARAMS']['COMMENT_XML_ID']);
						if ($instanceDate && $until)
						{
							$untilTs = CCalendar::Timestamp($until);
							$instanceDateTs = CCalendar::Timestamp($instanceDate);
							if ($instanceDateTs >= $untilTs)
							{
								CSocNetLog::Update($arRes['ID'], array(
									"SOURCE_ID" => $eventId
								));
							}
						}
					}
				}
			}
		}
	}
}