function InviteGuests($ID, $arCalendarEvent, $arGuests, $arParams)
{
$arParams["prop"]["PARENT"] = $ID;
$iblockId = $this->userIblockId;
$userId = $arParams['userId'];
$fullUrl = $arParams['fullUrl'];
$pathToUserCalendar = $arParams['pathToUserCalendar'];
$ownerName = $GLOBALS['USER']->GetFullName();
$arGuestConfirm = array();
$bExchange = CEventCalendar::IsExchangeEnabled() && $arParams['ownerType'] == 'USER';
$loc = '';
if (isset($arParams["prop"]["LOCATION"]) && $arParams["prop"]["LOCATION"] <> '')
{
$arLoc = CEventCalendar::ParseLocation($arParams["prop"]["LOCATION"]);
if (!$arLoc['mrid'] || !$arLoc['mrevid'])
{
$loc = $arLoc['str'];
}
else // Meeting room
{
$MR = CEventCalendar::GetMeetingRoomById(array(
'RMiblockId' => $arParams['RMiblockId'],
'RMPath' => $arParams['RMPath'],
'id' => $arLoc['mrid'],
'VMiblockId' => $arParams['VMiblockId'],
'VMPath' => $arParams['VMPath'],
'VMPathDetail' => $arParams['VMPathDetail'],
));
if ($MR)
{
if($arLoc['mrid'] == $arParams['VMiblockId'] && $arParams['VMPath'] <> '')
{
$url = (CMain::IsHTTPS() ? "https://" : "http://").$_SERVER['HTTP_HOST'].$arParams['VMPathDetail'];
$loc = "[url=".str_replace(Array("#id#", "#conf_id#"), Array($arLoc['mrid'], $arLoc['mrevid']), $url)."]".$MR['NAME']."[/url]";
}
elseif ($arParams['RMPath'] <> '')
{
$url = (CMain::IsHTTPS() ? "https://" : "http://").$_SERVER['HTTP_HOST'].$arParams['RMPath'];
$loc = "[url=".str_replace("#id#", $arLoc['mrid'], $url)."]".$MR['NAME']."[/url]";
}
else
{
$loc = $MR['NAME'];
}
}
}
}
//Guests
$arAllGuests = array();
foreach($arGuests as $guest_id)
{
$guest_id = intval($guest_id);
if($guest_id > 0)
$arAllGuests[$guest_id] = $guest_id;
}
//Find old guests. For new event (or only owner) - it's empty array
if ($arParams['bNew'])
$arOldGuests = array();
else
$arOldGuests = CECEvent::GetGuests($arParams['userIblockId'], $ID, array('bCheckOwner' => true, 'ownerType' => $arParams['ownerType'], 'bHostIsAbsent' => CECEvent::HostIsAbsent($arParams['iblockId'], $ID), 'DontReturnOnlyOwner' => true)); // Get guests
$arParams["prop"]["PRIVATE"] = '';
// Collect all new guests
$arNewGuests = array();
//And existing ones in order to update if event changed
$arUpdGuests = array();
foreach($arAllGuests as $guest_id)
{
if(!array_key_exists($guest_id, $arOldGuests)) // New guests
{
$rsUser = CUser::GetList('', '', array("ID_EQUAL_EXACT" => $guest_id));
$arUser = $rsUser->Fetch();
if($arUser)
{
$arUser["FULL_NAME"] = CEventCalendar::GetFullUserName($arUser);
$arNewGuests[$guest_id] = $arUser;
}
}
else
{
$arUpdGuests[$guest_id] = $arOldGuests[$guest_id];
}
}
//Create child events for new guests
foreach($arNewGuests as $guest_id => $arGuest)
{
$guestSection = CEventCalendar::GetSectionIDByOwnerId($guest_id, 'USER', $iblockId);
$guestCalendarId = false;
$arGuestCalendars = array();
$res = null;
$bForOwner = false;
if($guest_id == $userId)
{
// it's owner
if ($this->ownerType == 'USER')
continue;
$bForOwner = true;
}
if(!$guestSection) // Guest does not have any calendars
{
$guestSection = CEventCalendar::CreateSectionForOwner($guest_id, "USER", $iblockId);
}
else
{
//Section is out there
//so we have chance to get guests calendar
if ($this->bCache)
{
$cachePath = $this->cachePath.$iblockId."/calendars/".$guest_id."/4guests/";
$cacheId = 'g_'.$guestSection.'_'.$iblockId.'_'.$guest_id;
$cacheTime = 2592000; // 1 month
$cache = new CPHPCache;
if ($cache->InitCache($cacheTime, $cacheId, $cachePath))
{
$res = $cache->GetVars();
$arGuestCalendars = $res['calendars'];
}
}
if (!$this->bCache || empty($res['calendars']))
{
$arGuestCalendars = $this->GetCalendars(array(
'sectionId' => $guestSection,
'iblockId' => $iblockId,
'ownerType' => 'USER',
'ownerId' => $guest_id,
'bOwner' => true,
'forExport' => true,
'bOnlyID' => true
));
if ($this->bCache)
{
$cache->StartDataCache($cacheTime, $cacheId, $cachePath);
$cache->EndDataCache(array("calendars" => $arGuestCalendars));
}
}
if(count($arGuestCalendars) > 0)
{
$arUserSet = CEventCalendar::GetUserSettings(array('static' => true, 'userId' => $guest_id));
if ($arUserSet && isset($arUserSet['MeetCalId']) && in_array($arUserSet['MeetCalId'], $arGuestCalendars))
$guestCalendarId = intval($arUserSet['MeetCalId']);
else
$guestCalendarId = $arGuestCalendars[0];
}
}
$eventId = $this->SaveEvent(array(
'bOwner' => true,
'ownerType' => "USER",
'ownerId' => $guest_id,
'iblockId' => $iblockId,
'bNew' => true,
'name' => $arParams['name'],
'desc' => $arParams['desc'],
'calendarId' => $guestCalendarId,
'sectionId' => $guestSection,
'dateFrom' => $arParams["dateFrom"],
'dateTo' => $arParams["dateTo"],
'prop' => $arParams["prop"],
"CONFIRMED" => $bForOwner ? 'Y' : 'Q', // "Y" "Q" "N"
"notDisplayCalendar" => true,
"bCheckPermissions" => false,
'isMeeting' => true
));
$arGuestConfirm[$guest_id] = $bForOwner ? 'Y' : 'Q';
// Send message
if (!$bForOwner)
{
CEventCalendar::SendInvitationMessage(array(
'type' => "invite",
'email' => $arGuest["EMAIL"],
'name' => $arParams['name'],
"from" => $arParams["dateFrom"],
"to" => $arParams["dateTo"],
"location" => $loc,
"pathToUserCalendar" => $pathToUserCalendar,
"meetingText" => $arParams['meetingText'],
"guestId" => $guest_id,
"guestName" => $arGuest["FULL_NAME"],
"userId" => $userId,
"eventId" => $eventId,
"ownerName" => $ownerName
));
}
}
//Delete child events if guest was deleted from the list
$obElement = new CIBlockElement;
$arDeletedUsers = array();
foreach($arOldGuests as $guest_id => $arOldEvent)
{
if($guest_id == $userId)
continue;
if(!array_key_exists($guest_id, $arAllGuests))
{
$res = CECEvent::Delete(array(
'id' => $arOldEvent["ID"],
'iblockId' => $iblockId,
'ownerType' => "USER",
'ownerId' => $guest_id,
'userId' => $userId,
'bJustDel' => true // Just delete iblock element + exchange
));
if ($res !== true)
return $this->ThrowError($res <> '' ? $res : GetMessage('EC_EVENT_DEL_ERROR'));
$arDeletedUsers[] = $arOldEvent["ID"];
if ($arOldEvent["PROPERTY_VALUES"]["CONFIRMED"] != "N") //User
{
// Send message
CEventCalendar::SendInvitationMessage(array(
'type' => "cancel",
'email' => $arOldEvent["CREATED_BY"]["EMAIL"],
'name' => $arOldEvent['NAME'],
"from" => $arOldEvent["ACTIVE_FROM"],
"to" => $arOldEvent["ACTIVE_TO"],
"desc" => $arOldEvent['DETAIL_TEXT'],
"pathToUserCalendar" => $pathToUserCalendar,
"guestId" => $guest_id,
"guestName" => $arOldEvent["CREATED_BY"]["FULL_NAME"],
"userId" => $userId,
"ownerName" => $ownerName
));
}
}
}
// Update info
if(count($arUpdGuests) > 0)
{
$arCalendarEventProps = $arCalendarEvent["PROPERTY_VALUES"];
unset($arCalendarEvent["PROPERTY_VALUES"]);
//Check if we have to update child events
foreach($arUpdGuests as $guest_id => $arOldEvent)
{
if($guest_id == $userId && $this->ownerType == 'USER')
continue;
$bReinvite = false;
$bCH_from = CEventCalendar::TrimTime($arOldEvent["ACTIVE_FROM"]) != CEventCalendar::TrimTime($arCalendarEvent["ACTIVE_FROM"]);
$bCH_to = CEventCalendar::TrimTime($arOldEvent["ACTIVE_TO"]) != CEventCalendar::TrimTime($arCalendarEvent["ACTIVE_TO"]);
$bTimeChanged = $bCH_from || $bCH_to;
$bCH_name = $arOldEvent["NAME"] != $arCalendarEvent["NAME"];
$bCH_desc = $arOldEvent["DETAIL_TEXT"] != $arCalendarEvent["DETAIL_TEXT"];
$bFieldsChanged = $bCH_name || $bCH_desc;
$bCH_loc = $arOldEvent["PROPERTY_VALUES"]["LOCATION"] != $arCalendarEventProps["LOCATION"];
$bCH_repeat = $arOldEvent["PROPERTY_VALUES"]["PERIOD_TYPE"] != $arCalendarEventProps["PERIOD_TYPE"]
|| $arOldEvent["PROPERTY_VALUES"]["PERIOD_COUNT"] != $arCalendarEventProps["PERIOD_COUNT"]
|| $arOldEvent["PROPERTY_VALUES"]["EVENT_LENGTH"] != $arCalendarEventProps["EVENT_LENGTH"]
|| $arOldEvent["PROPERTY_VALUES"]["PERIOD_ADDITIONAL"] != $arCalendarEventProps["PERIOD_ADDITIONAL"];
$bCH_imp = $arOldEvent["PROPERTY_VALUES"]["IMPORTANCE"] != $arCalendarEventProps["IMPORTANCE"];
$bCH_meettxt = $arOldEvent["PROPERTY_VALUES"]["MEETING_TEXT"] != $arCalendarEventProps["MEETING_TEXT"]['VALUE']['TEXT'];
$bPropertyChanged = $bCH_repeat || $bCH_loc || $bCH_meettxt || $bCH_imp;
if (count($arParams['reinviteParamsList']) > 0)
{
$bReinvite = in_array('name', $arParams['reinviteParamsList']) && $bCH_name;
if (!$bReinvite)
$bReinvite = in_array('desc', $arParams['reinviteParamsList']) && $bCH_desc;
if (!$bReinvite)
$bReinvite = in_array('from', $arParams['reinviteParamsList']) && $bCH_from;
if (!$bReinvite)
$bReinvite = in_array('to', $arParams['reinviteParamsList']) && $bCH_to;
if (!$bReinvite)
$bReinvite = in_array('location', $arParams['reinviteParamsList']) && $bCH_loc;
if (!$bReinvite)
$bReinvite = in_array('guest_list', $arParams['reinviteParamsList']) && (count($arDeletedUsers) > 0 || count($arNewGuests) > 0);
if (!$bReinvite)
$bReinvite = in_array('repeating', $arParams['reinviteParamsList']) && $bCH_repeat;
if (!$bReinvite)
$bReinvite = in_array('importance', $arParams['reinviteParamsList']) && $bCH_imp;
if (!$bReinvite)
$bReinvite = in_array('meet_text', $arParams['reinviteParamsList']) && $bCH_meettxt;
}
if($bTimeChanged || $bFieldsChanged || $bPropertyChanged)
{
if($guest_id != $userId)
{
if ($bReinvite)
{
$arCalendarEventProps["CONFIRMED"] = CEventCalendar::GetConfirmedID($iblockId, "Q");
$arGuestConfirm[$guest_id] = 'Q';
}
$arFields = array(
"ACTIVE_FROM" => $arCalendarEvent["ACTIVE_FROM"],
"ACTIVE_TO" => $arCalendarEvent["ACTIVE_TO"],
"NAME" => $arCalendarEvent["NAME"],
"DETAIL_TEXT" => $arCalendarEvent["DETAIL_TEXT"],
"DETAIL_TEXT_TYPE" => 'html',
//"PROPERTY_VALUES" => $arCalendarEventProps
);
// If it's EXCHANGE - we try to save event to exchange
if ($bExchange)
{
foreach($arCalendarEventProps as $prKey => $prVal)
$arFields["PROPERTY_".$prKey] = $prVal;
$calendarXmlId = CECCalendar::GetExchangeXmlId($arOldEvent["IBLOCK_ID"], $arOldEvent['IBLOCK_SECTION_ID']);
if ($calendarXmlId <> '' && $calendarXmlId !== 0) // Synchronize with Exchange
{
$eventModLabel = CECEvent::GetExchModLabel($arOldEvent["IBLOCK_ID"], $arOldEvent["ID"]);
$eventXmlId = CECEvent::GetExchangeXmlId($arOldEvent["IBLOCK_ID"], $arOldEvent["ID"]);
$exchRes = CDavExchangeCalendar::DoUpdateItem($guest_id, $eventXmlId, $eventModLabel, $arFields);
if (!is_array($exchRes) || !array_key_exists("XML_ID", $exchRes))
return CEventCalendar::ThrowError(CEventCalendar::CollectExchangeErros($exchRes));
// It's ok, we successfuly save event to exchange calendar - and save it to DB
$arFields['XML_ID'] = $exchRes['XML_ID'];
//$arFields['PROPERTY_VALUES']['BXDAVEX_LABEL'] = $exchRes['MODIFICATION_LABEL'];
$arCalendarEventProps['BXDAVEX_LABEL'] = $exchRes['MODIFICATION_LABEL'];
}
}
$obElement = new CIBlockElement;
$obElement->SetPropertyValuesEx($arOldEvent["ID"], $arOldEvent["IBLOCK_ID"], $arCalendarEventProps, array("DoNotValidateLists" => true));
if($bTimeChanged || $bFieldsChanged)
$obElement->Update($arOldEvent["ID"], $arFields, false);
}
// Send message
if ($guest_id != $userId)
{
CEventCalendar::SendInvitationMessage(array(
'type' => "change",
'email' => $arOldEvent["CREATED_BY"]["EMAIL"],
'name' => $arOldEvent['NAME'],
"from" => $arOldEvent["ACTIVE_FROM"],
"to" => $arOldEvent["ACTIVE_TO"],
"location" => $loc,
"meetingText" => $arParams['meetingText'],
"pathToUserCalendar" => $pathToUserCalendar,
"guestId" => $guest_id,
"guestName" => $arOldEvent["CREATED_BY"]["FULL_NAME"],
"userId" => $userId,
"eventId" => $arOldEvent["ID"],
"ownerName" => $ownerName
));
}
}
}
}
$this->ClearCache($this->cachePath.'events/'.$iblockId.'/');
return $arGuestConfirm;
}