static function SaveExternalEvents(array $externalEvents, array $localEvents, $localCalendar): void
{
foreach ($externalEvents as $externalEvent)
{
$eventExists = !empty($localEvents[$externalEvent['G_EVENT_ID']]);
// find parent event
if (
isset($externalEvent['recurringEventId'])
&& $externalEvent['isRecurring'] === 'Y'
&& !isset($localEvents[$externalEvent['recurringEventId']])
)
{
$parentEvent = self::getLocalEventsList($localCalendar, [$externalEvent['recurringEventId']]);
if (!empty($parentEvent))
{
$localEvents[$externalEvent['recurringEventId']] = $parentEvent[$externalEvent['recurringEventId']];
}
}
// delete events
if ($externalEvent['status'] === 'cancelled')
{
$originalEvent = $localEvents[$externalEvent['G_EVENT_ID']];
// event exists
if ($eventExists)
{
if (!empty($externalEvents[$externalEvent['recurringEventId']])
&& $externalEvents[$externalEvent['recurringEventId']]['status'] === 'cancelled'
&& !empty($localEvents[$externalEvent['recurringEventId']])
&& (int)$originalEvent['ID'] === (int)$originalEvent['PARENT_ID']
)
{
CCalendarEvent::Delete([
'id' => $localEvents[$externalEvent['recurringEventId']]['ID'],
'bMarkDeleted' => true,
'Event' => $localEvents[$externalEvent['recurringEventId']],
'userId' => $localCalendar['OWNER_ID'],
'sendNotification' => false
]);
}
if (!empty($localEvents[$externalEvent['G_EVENT_ID']]['IS_MEETING']) && $localEvents[$externalEvent['G_EVENT_ID']]['IS_MEETING'])
{
self::$doNotSendToGoogle = false;
}
//if host single event then delete instance and change meeting status if invitation
if ((int)$originalEvent['ID'] !== (int)$originalEvent['PARENT_ID'])
{
CCalendarEvent::SetMeetingStatus([
'userId' => (int)$originalEvent['OWNER_ID'],
'eventId' => (int)$originalEvent['ID'],
'status' => 'N',
'personalNotification' => true
]);
}
else // delete event
{
CCalendarEvent::Delete([
'id' => $originalEvent['ID'],
'bMarkDeleted' => true,
'Event' => $originalEvent,
'userId' => $localCalendar['OWNER_ID'],
'sendNotification' => false
]);
}
if (!empty($originalEvent['IS_MEETING']) && $originalEvent['IS_MEETING'])
{
self::$doNotSendToGoogle = true;
}
// enumeration local instances and change status if invitation or delete if host instance
foreach ($localEvents as $localEvent)
{
if (
!empty($localEvent['RECURRENCE_ID'])
&& $localEvent['RECURRENCE_ID'] === $originalEvent['ID']
)
{
if ((int)$localEvent['ID'] !== (int)$localEvent['PARENT_ID'])
{
CCalendarEvent::SetMeetingStatus([
'userId' => (int)$localEvent['OWNER_ID'],
'eventId' => (int)$localEvent['ID'],
'status' => 'N',
'personalNotification' => true
]);
}
else
{
CCalendarEvent::Delete([
'id' => $localEvent['ID'],
'bMarkDeleted' => true,
'Event' => $localEvent,
'userId' => $localCalendar['OWNER_ID'],
'sendNotification' => false
]);
}
}
}
}
elseif (!empty($externalEvent['recurringEventId'])
&& !empty($localEvents[$externalEvent['recurringEventId']])
&& $externalEvent['isRecurring'] === 'Y'
) // update parent event exdate
{
$excludeDates = CCalendarEvent::GetExDate($localEvents[$externalEvent['recurringEventId']]['EXDATE']);
$excludeDates[] = $externalEvent['EXDATE'];
$localEvents[$externalEvent['recurringEventId']]['EXDATE'] = implode(';', $excludeDates);
$newParentData = [
'arFields' => $localEvents[$externalEvent['recurringEventId']],
'userId' => $localCalendar['OWNER_ID'],
'fromWebservice' => true
];
$newParentData['arFields']['EXDATE'] = CCalendarEvent::SetExDate($excludeDates);
$newParentData['arFields']['RRULE'] = CCalendarEvent::ParseRRULE($newParentData['arFields']['RRULE']);
CCalendar::SaveEvent($newParentData);
}
continue;
}
// handle single or recurrence events
if ($externalEvent['isRecurring'] === "N")
{
//new event
if (!$eventExists)
{
$newEventData = array_merge(
$externalEvent,
[
'SECTIONS' => [$localCalendar['ID']],
'OWNER_ID' => $localCalendar['OWNER_ID'],
'userId' => $localCalendar['OWNER_ID']
]
);
$newEvent = $newEventData;
$newEvent['ID'] = CCalendarEvent::Edit(['arFields' => $newEventData, 'path' => CCalendar::GetPath('user', $newEventData['OWNER_ID'])]);
$localEvents[$externalEvent['DAV_XML_ID']] = $newEvent;
}
else // event exists
{
$newParentData = [
'arFields' => array_merge([
'ID' => $localEvents[$externalEvent['G_EVENT_ID']]['ID'],
'MEETING' => $localEvents[$externalEvent['G_EVENT_ID'] . '@google.com']['MEETING'],
], $externalEvent),
'userId' => $localCalendar['OWNER_ID'],
'fromWebservice' => true
];
// update do not sync with google
if (!empty($localEvents[$externalEvent['G_EVENT_ID']]['IS_MEETING']) && $localEvents[$externalEvent['G_EVENT_ID']]['IS_MEETING'])
{
self::$doNotSendToGoogle = false;
}
if (empty($newParentData['arFields']['MEETING']['LANGUAGE_ID']))
{
$newParentData['arFields']['MEETING']['LANGUAGE_ID'] = CCalendar::getUserLanguageId((int)$newParentData['arFields']['OWNER_ID']);
}
$newParentData['arFields']['DESCRIPTION'] = self::CutAttendeesFromDescription(
$newParentData['arFields']['DESCRIPTION'],
self::getAttendeesCodesForCut($localEvents[$externalEvent['G_EVENT_ID']]['ATTENDEES_CODES'] ?? null),
$newParentData['arFields']['MEETING']['LANGUAGE_ID']
);
$newParentData['dontSyncParent'] = true;
$newParentData['arFields']['SYNC_STATUS'] = GoogleDictionary::SYNC_STATUS['success'];
CCalendar::SaveEvent($newParentData);
if (!empty($localEvents[$externalEvent['G_EVENT_ID']]['IS_MEETING']) && $localEvents[$externalEvent['G_EVENT_ID']]['IS_MEETING'])
{
self::$doNotSendToGoogle = true;
}
}
}
elseif ($externalEvent['isRecurring'] === "Y") // is instance
{
// change time
if ($externalEvent['status'] === 'confirmed' && $externalEvent['hasMoved'] === "Y")
{
// find parent event
$recurrentParentEventExists = !empty($localEvents[$externalEvent['recurringEventId']]);
if (empty($recurrentParentEventExists))
{
// $parentGEventId = str_replace('@google.com', '', $externalEvent['recurringEventId']);
$parentEvent = self::getLocalEventsList($localCalendar, [$externalEvent['recurringEventId']]);
if (!empty($parentEvent))
{
$localEvents[$externalEvent['recurringEventId']] = $parentEvent[$externalEvent['recurringEventId']];
$recurrentParentEventExists = $parentEvent[$externalEvent['recurringEventId']];
}
}
// update exdate to parent event
if ($recurrentParentEventExists)
{
$recurrenceId = NULL;
if ($localEvents[$externalEvent['recurringEventId']])
{
$recurrenceId = $localEvents[$externalEvent['recurringEventId']]['ID'];
$excludeDates = CCalendarEvent::GetExDate($localEvents[$externalEvent['recurringEventId']]['EXDATE']);
$excludeDates[] = $externalEvent['EXDATE'];
$localEvents[$externalEvent['recurringEventId']]['EXDATE'] = implode(';', $excludeDates);
$newParentData = [
'arFields' => $localEvents[$externalEvent['recurringEventId']],
'userId' => $localCalendar['OWNER_ID'],
'fromWebservice' => true
];
$newParentData['arFields']['EXDATE'] = CCalendarEvent::SetExDate($excludeDates);
$newParentData['arFields']['RRULE'] = CCalendarEvent::ParseRRULE($newParentData['arFields']['RRULE']);
$newParentData['arFields']['SYNC_STATUS'] = GoogleDictionary::SYNC_STATUS['success'];
$newParentData['sync'] = true;
CCalendar::SaveEvent($newParentData);
}
// find meeting field in instance exists or parent event
if (empty($externalEvent['MEETING']))
{
$externalEvent['MEETING'] = !empty($localEvents[$externalEvent['G_EVENT_ID'] . '@google.com']['MEETING'])
? $localEvents[$externalEvent['G_EVENT_ID'] . '@google.com']['MEETING']
: $localEvents[$externalEvent['DAV_XML_ID']]['MEETING'];
}
// set lang id
if (empty($externalEvent['MEETING']['LANGUAGE_ID']))
{
$externalEvent['MEETING']['LANGUAGE_ID'] = CCalendar::getUserLanguageId((int)$externalEvent['OWNER_ID']);
}
// handle description
if (isset($externalEvent['DESCRIPTION']))
{
$externalEvent['DESCRIPTION'] = self::CutAttendeesFromDescription(
$externalEvent['DESCRIPTION'],
self::getAttendeesCodesForCut($localEvents[$externalEvent['recurringEventId']]['ATTENDEES_CODES'] ?? null),
$externalEvent['MEETING']['LANGUAGE_ID']
);
}
// save instance
CCalendar::SaveEvent([
'arFields' => array_merge($externalEvent, [
'RECURRENCE_ID' => $recurrenceId,
'DATE_FROM' => $externalEvent['DATE_FROM'],
'SECTIONS' => [$localCalendar['ID']],
'DATE_TO' => $externalEvent['DATE_TO'],
'SYNC_STATUS' => GoogleDictionary::SYNC_STATUS['success'],
'ATTENDEES' => !empty($localEvents[$externalEvent['G_EVENT_ID']]['ATTENDEES'])
? $localEvents[$externalEvent['G_EVENT_ID']]['ATTENDEES']
: $localEvents[$externalEvent['DAV_XML_ID']]['ATTENDEES'],
'ATTENDEES_CODES' => !empty($localEvents[$externalEvent['G_EVENT_ID']]['ATTENDEES_CODES'])
? $localEvents[$externalEvent['G_EVENT_ID']]['ATTENDEES_CODES']
: $localEvents[$externalEvent['DAV_XML_ID']]['ATTENDEES_CODES'],
'IS_MEETING' => !empty($localEvents[$externalEvent['G_EVENT_ID']]['IS_MEETING'])
? $localEvents[$externalEvent['G_EVENT_ID']]['IS_MEETING']
: $localEvents[$externalEvent['DAV_XML_ID']]['IS_MEETING'],
'MEETING_STATUS' => !empty($localEvents[$externalEvent['G_EVENT_ID']]['MEETING_STATUS'])
? $localEvents[$externalEvent['G_EVENT_ID']]['MEETING_STATUS']
: $localEvents[$externalEvent['DAV_XML_ID']]['MEETING_STATUS'],
]),
'userId' => $localCalendar['OWNER_ID'],
'fromWebservice' => true,
'sync' => true,
]);
}
}
}
}
}