• Модуль: calendar
  • Путь к файлу: ~/bitrix/modules/calendar/classes/general/calendar_sync.php
  • Класс: CCalendarSync
  • Вызов: CCalendarSync::ModifyEvent
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;
}