static function ModifyEvent($calendarId, $arFields, $params = [])
{
[$sectionId, $entityType, $entityId] = $calendarId;
$userId = $entityType === 'user' ? $entityId : 0;
$eventId = false;
$bExchange = CCalendar::IsExchangeEnabled($userId) && $entityType === 'user';
CCalendar::SetSilentErrorMode();
if ($sectionId && ($section = CCalendarSect::GetById((int)$sectionId, false)))
{
CCalendar::SetOffset(false, CCalendar::GetOffset($userId));
$eventId = ((isset($arFields['ID']) && ((int)$arFields['ID'] > 0)) ? (int)$arFields['ID'] : 0);
$arNewFields = [
'DAV_XML_ID' => $arFields['XML_ID'],
'CAL_DAV_LABEL' => (isset($arFields['PROPERTY_BXDAVCD_LABEL']) && $arFields['PROPERTY_BXDAVCD_LABEL']) ? $arFields['PROPERTY_BXDAVCD_LABEL'] : '',
'DAV_EXCH_LABEL' => (isset($arFields['PROPERTY_BXDAVEX_LABEL']) && $arFields['PROPERTY_BXDAVEX_LABEL']) ? $arFields['PROPERTY_BXDAVEX_LABEL'] : '',
'ID' => $eventId,
'NAME' => $arFields['NAME'] ?: GetMessage('EC_NONAME_EVENT'),
'CAL_TYPE' => $section['CAL_TYPE'],
'OWNER_ID' => $section['OWNER_ID'],
'DESCRIPTION' => $arFields['DESCRIPTION'] ?? '',
'SECTIONS' => [$sectionId],
'ACCESSIBILITY' => $arFields['ACCESSIBILITY'] ?? 'busy',
'IMPORTANCE' => $arFields['IMPORTANCE'] ?? 'normal',
'REMIND' => (isset($arFields['REMIND']) && is_array($arFields['REMIND'])) ? $arFields['REMIND'] : [],
'RRULE' => (isset($arFields['RRULE']) && is_array($arFields['RRULE'])) ? $arFields['RRULE'] : [],
'VERSION' => isset($arFields['VERSION']) ? (int)$arFields['VERSION'] : 1,
'PRIVATE_EVENT' => (bool)($arFields['PRIVATE_EVENT'] ?? null)
];
$currentEvent = CCalendarEvent::getList([
'arFilter' => [
'DAV_XML_ID' => $arNewFields['DAV_XML_ID'],
'DELETED' => 'N'
]
]);
if ($currentEvent)
{
$currentEvent = $currentEvent[0];
}
$arNewFields['DATE_FROM'] = $arFields['DATE_FROM'];
$arNewFields['DATE_TO'] = $arFields['DATE_TO'];
$arNewFields['TZ_FROM'] = $arFields['TZ_FROM'];
$arNewFields['TZ_TO'] = $arFields['TZ_TO'];
$arNewFields['SKIP_TIME'] = $arFields['SKIP_TIME'];
if (isset($arFields['RECURRENCE_ID']))
{
$arNewFields['RECURRENCE_ID'] = $arFields['RECURRENCE_ID'];
}
if (isset($arFields['RECURRENCE_ID_DATE']) && $arFields['RECURRENCE_ID_DATE'])
{
$arNewFields['ORIGINAL_DATE_FROM'] = $arFields['RECURRENCE_ID_DATE'];
}
if (isset($arNewFields['SKIP_TIME']) && $arNewFields['SKIP_TIME'])
{
$arNewFields['DATE_FROM'] = CCalendar::Date(CCalendar::Timestamp($arNewFields['DATE_FROM']), false);
$arNewFields['DATE_TO'] = CCalendar::Date(CCalendar::Timestamp($arNewFields['DATE_TO']) - CCalendar::GetDayLen(), false);
}
if (!empty($arFields['PROPERTY_REMIND_SETTINGS']))
{
if (is_array($arFields['PROPERTY_REMIND_SETTINGS']))
{
foreach ($arFields['PROPERTY_REMIND_SETTINGS'] as $remindSetting)
{
$ar = explode('_', $remindSetting);
$arNewFields = self::prepareRemind($ar, $arNewFields);
}
}
else
{
$ar = explode('_', $arFields['PROPERTY_REMIND_SETTINGS']);
$arNewFields = self::prepareRemind($ar, $arNewFields);
}
}
if (!empty($arFields['PROPERTY_ACCESSIBILITY']))
{
$arNewFields['ACCESSIBILITY'] = $arFields['PROPERTY_ACCESSIBILITY'];
}
if (!empty($arFields['PROPERTY_IMPORTANCE']))
{
$arNewFields['IMPORTANCE'] = $arFields['PROPERTY_IMPORTANCE'];
}
if (!empty($arFields['PROPERTY_LOCATION']))
{
$arNewFields['LOCATION'] = BitrixCalendarRoomsUtil::unParseTextLocation($arFields['PROPERTY_LOCATION']);
}
if (!empty($arFields['DETAIL_TEXT']))
{
if (empty($arFields['MEETING']['LANGUAGE_ID']))
{
$arNewFields['MEETING']['LANGUAGE_ID'] = CCalendar::getUserLanguageId((int)$arNewFields['OWNER_ID']);
}
$arNewFields['DESCRIPTION'] = self::CutAttendeesFromDescription(
$arFields['DETAIL_TEXT'],
self::getAttendeesCodesForCut($currentEvent['ATTENDEES_CODES'] ?? null),
$arNewFields['MEETING']['LANGUAGE_ID']
);
}
$arNewFields['DESCRIPTION'] = CCalendar::ClearExchangeHtml($arNewFields['DESCRIPTION']);
if (isset($arFields['PROPERTY_PERIOD_TYPE']) && in_array($arFields['PROPERTY_PERIOD_TYPE'], ["DAILY", "WEEKLY", "MONTHLY", "YEARLY"]))
{
$arNewFields['RRULE']['FREQ'] = $arFields["PROPERTY_PERIOD_TYPE"];
$arNewFields['RRULE']['INTERVAL'] = $arFields["PROPERTY_PERIOD_COUNT"];
if (!isset($arNewFields['DT_LENGTH']) && !empty($arFields['PROPERTY_EVENT_LENGTH']))
{
$arNewFields['DT_LENGTH'] = (int)$arFields['PROPERTY_EVENT_LENGTH'];
}
else if (isset($arFields['DT_TO_TS'], $arFields['DT_FROM_TS']))
{
$arNewFields['DT_LENGTH'] = $arFields['DT_TO_TS'] - $arFields['DT_FROM_TS'];
}
else
{
$arNewFields['DT_LENGTH'] = null;
}
if ($arNewFields['RRULE']['FREQ'] === "WEEKLY" && !empty($arFields['PROPERTY_PERIOD_ADDITIONAL']))
{
$arNewFields['RRULE']['BYDAY'] = [];
$bydays = explode(',',$arFields['PROPERTY_PERIOD_ADDITIONAL']);
foreach($bydays as $day)
{
$day = CCalendar::WeekDayByInd($day, false);
if ($day !== false)
{
$arNewFields['RRULE']['BYDAY'][] = $day;
}
}
$arNewFields['RRULE']['BYDAY'] = implode(',',$arNewFields['RRULE']['BYDAY']);
}
if (isset($arFields['PROPERTY_RRULE_COUNT']))
{
$arNewFields['RRULE']['COUNT'] = $arFields['PROPERTY_RRULE_COUNT'];
}
elseif (isset($arFields['PROPERTY_PERIOD_UNTIL']))
{
$arNewFields['RRULE']['UNTIL'] = $arFields['PROPERTY_PERIOD_UNTIL'];
}
else
{
$arNewFields['RRULE']['UNTIL'] = $arFields['DT_TO_TS'] ?? null;
}
if (isset($arFields['EXDATE']))
{
$arNewFields['EXDATE'] = $arFields["EXDATE"];
}
}
if (
isset($arFields['IS_MEETING'])
&& $arFields['IS_MEETING']
&& (($bExchange && self::isExchangeMeetingEnabled()) || $params['handleMeetingParams'])
)
{
$arNewFields['IS_MEETING'] = $arFields['IS_MEETING'];
$arNewFields['MEETING_HOST'] = $arFields['MEETING_HOST'];
$arNewFields['MEETING'] = $arFields['MEETING'];
$arNewFields['ATTENDEES_CODES'] = $arFields['ATTENDEES_CODES'];
}
$eventId = CCalendar::SaveEvent([
'arFields' => $arNewFields,
'userId' => $userId,
'bAffectToDav' => false, // Used to prevent synchro with calDav again
'bSilentAccessMeeting' => true,
'autoDetectSection' => false,
'sendInvitations' => ($params['sendInvitations'] ?? null) !== false,
'syncCaldav' => $params['caldav'] ?? null,
]);
if ($eventId)
{
// Event actually is editing, but when it changes calendar category and
// comes from the external device it looks like its new event.
// But here we're trying to find original event and
// if it was in DB - we delete it to avoid duplication
if (
$currentEvent
&& $currentEvent['ID']
&& (int)$sectionId !== (int)$currentEvent['SECTION_ID']
&& !$currentEvent['RECURRENCE_ID']
&& $arNewFields['OWNER_ID'] === $currentEvent['OWNER_ID']
)
{
CCalendar::DeleteEvent($currentEvent['ID']);
}
}
else
{
CCalendarSect::UpdateModificationLabel($sectionId);
}
if (
$eventId
&& ($arFields['IS_MEETING'] ?? null)
&& ($arFields['ATTENDEES_RESPONSE'] ?? null)
&& $bExchange
&& self::isExchangeMeetingEnabled()
)
{
foreach($arFields['ATTENDEES_RESPONSE'] as $attendeeId => $status)
{
CCalendarEvent::SetMeetingStatus([
'userId' => $attendeeId,
'eventId' => $eventId,
'status' => $status,
'personalNotification' => false,
'hostNotification' => false,
'affectRecRelatedEvents' => false,
'updateDescription' => false,
]);
}
}
}
CCalendar::SetSilentErrorMode(false);
return $eventId;
}