function UpdateListItems($listName, $updates)
{
global $USER;
$arStatusValues = array_flip($this->arStatusValues);
$arPriorityValues = array_flip($this->arPriorityValues);
if (!$listName_original = CIntranetUtils::checkGUID($listName))
{
return new CSoapFault('Data error', 'Wrong GUID - ' . $listName);
}
$obResponse = new CXMLCreator('Results');
$listName = ToUpper(CIntranetUtils::makeGUID($listName_original));
$arSections = CCalendarSect::GetList(array('arFilter' => array('XML_ID' => $listName_original)));
if (!$arSections || !is_array($arSections[0]))
{
return new CSoapFault(
'List not found',
'List with ' . $listName . ' GUID not found'
);
}
$arSection = $arSections[0];
$bGroup = $arSection['CAL_TYPE'] === 'group';
$calType = $arSection['CAL_TYPE'];
$ownerId = $arSection['OWNER_ID'];
if ($bGroup)
{
BitrixMainLoader::includeModule('socialnetwork');
$arGroupTmp = CSocNetGroup::GetByID($arSection['SOCNET_GROUP_ID']);
if ($arGroupTmp["CLOSED"] === "Y")
{
if (COption::GetOptionString("socialnetwork", "work_with_closed_groups", "N") !== "Y")
{
return new CSoapFault(
'Cannot modify archive group calendar',
'Cannot modify archive group calendar'
);
}
}
}
$obBatch = $updates->children[0];
// $atrONERROR = $obBatch->getAttribute('OnError');
// $atrDATEINUTC = $obBatch->getAttribute('DateInUtc');
// $atrPROPERTIES = $obBatch->getAttribute('Properties');
$arChanges = $obBatch->children;
//$arResultIDs = array();
//$dateStart = ConvertTimeStamp(strtotime('-1 hour'), 'FULL');
$responseRows = array();
$replicationId = array();
$userId = (is_object($USER) && $USER->GetID()) ? $USER->GetID() : 1;
foreach ($arChanges as $obMethod)
{
$arData = array('_command' => $obMethod->getAttribute('Cmd'));
foreach ($obMethod->children as $obField)
{
$name = $obField->getAttribute('Name');
if ($name === 'MetaInfo')
{
$name .= '_' . $obField->getAttribute('Property');
}
$arData[$name] = $obField->content;
}
if ($arData['_command'] === 'Delete')
{
$obRes = new CXMLCreator('Result');
$obRes->setAttribute('ID', $obMethod->getAttribute('ID').','.$arData['_command']);
$obRes->setAttribute('List', $listName);
$obRes->addChild($obNode = new CXMLCreator('ErrorCode'));
$res = CCalendar::DeleteEvent($arData['ID']);
if ($res === true)
{
$obNode->setData('0x00000000');
}
else
{
$obNode->setData('0x81020014');
}
/*
0x00000000 - ok
0x81020015 - data conflict
0x81020014 - generic error such as invalid value for Field
0x81020016 - item does not exist
*/
$obResponse->addChild($obRes);
}
elseif ($arData['_command'] === 'New' || $arData['_command'] === 'Update')
{
$arData['Location'] = trim($arData['Location']);
$arData['EventType'] = (int)$arData['EventType'];
if ((int)$arData['EventType'] === 2)
{
$arData['EventType'] = 0;
}
if ($arData['EventType'] > 2 /* || ($arData['EventType'] == 1 && !$arData['RecurrenceData'])*/)
{
return new CSoapFault(
'Unsupported event type',
'Event type unsupported'
);
}
$id = $arData['_command'] === 'New' ? 0 : (int)$arData['ID'];
$arData['fRecurrence'] = (int)$arData['fRecurrence'];
$arData['RRULE'] = '';
if (isset($arData['EventDate']))
{
$fromTsUTC = $this->__makeTS($arData['EventDate']);
if ($arData['RecurrenceData'] && $arData['fAllDayEvent'])
{
$toTsUTC = $fromTsUTC;
}
elseif (!$arData['RecurrenceData'] && $arData['fAllDayEvent'])
{
$toTsUTC = $this->__makeTS($arData['EndDate']) - 86340;
}
else
{
$toTsUTC = $this->__makeTS($arData['EndDate']);
}
$skipTime = $arData['fAllDayEvent'] ? 'Y' : 'N';
$fromTs = $fromTsUTC;
$toTs = $toTsUTC;
if (!$arData['fAllDayEvent'])
{
$fromTs += CCalendar::GetCurrentOffsetUTC($userId);
$toTs += CCalendar::GetCurrentOffsetUTC($userId);
}
}
else
{
$fromTs = $toTs = $fromTsUTC = $toTsUTC = false;
$skipTime = false;
}
if ($arData['RecurrenceData'] && isset($arData['EventDate']))
{
$xmlstr = $arData['RecurrenceData'];
$obRecurData = new CDataXML();
$obRecurData->LoadString($xmlstr);
$obRecurRule = $obRecurData->tree->children[0]->children[0];
$obRecurRepeat = $obRecurRule->children[1];
$obNode = $obRecurRepeat->children[0];
$arData['RRULE'] = [];
switch($obNode->name)
{
case 'daily':
// hack. we have no "work days" daily recurence
if ($obNode->getAttribute('weekday') === 'TRUE')
{
$arData['RRULE']['FREQ'] = 'WEEKLY';
$arData['RRULE']['BYDAY'] = 'MO,TU,WE,TH,FR';
$arData['RRULE']['INTERVAL'] = 1;
}
else
{
$arData['RRULE']['FREQ'] = 'DAILY';
$arData['RRULE']['INTERVAL'] = $obNode->getAttribute('dayFrequency');
}
$time_end = strtotime(
date(date('Y-m-d', $fromTsUTC).' H:i:s', $toTsUTC)
);
$arData['DT_LENGTH'] = $time_end - $fromTsUTC;
break;
case 'weekly':
$arData['RRULE']['FREQ'] = 'WEEKLY';
$arData['RRULE']['BYDAY'] = [];
$arWeekDays = ['mo', 'tu', 'we', 'th', 'fr', 'sa', 'su'];
foreach ($arWeekDays as $day => $value)
{
if ($obNode->getAttribute($value))
{
$arData['RRULE']['BYDAY'][] = mb_strtoupper($value);
}
}
$arData['RRULE']['BYDAY'] = implode(',', $arData['RRULE']['BYDAY']);
$arData['RRULE']['INTERVAL'] = $obNode->getAttribute('weekFrequency');
$time_end = strtotime(date(date('Y-m-d', $fromTsUTC).' H:i:s', $toTsUTC));
$arData['DT_LENGTH'] = $time_end - $fromTsUTC;
break;
case 'monthly':
$arData['RRULE']['FREQ'] = 'MONTHLY';
$arData['RRULE']['INTERVAL'] = $obNode->getAttribute('monthFrequency');
$time_end = strtotime(date(date('Y-m', $fromTsUTC).'-d H:i:s', $toTsUTC));
$arData['DT_LENGTH'] = $time_end - $fromTsUTC;
break;
case 'yearly':
$arData['RRULE']['FREQ'] = 'YEARLY';
$arData['RRULE']['INTERVAL'] = $obNode->getAttribute('yearFrequency');
$time_end = strtotime(date(date('Y', $fromTsUTC).'-m-d H:i:s', $toTsUTC));
$arData['DT_LENGTH'] = $time_end - $fromTsUTC;
break;
}
if ((int)$arData['DT_LENGTH'] === 0 && isset($arData['RRULE']['FREQ']))
{
$arData['DT_LENGTH'] = 86400;
}
$obWhile = $obRecurRule->children[2];
if ($obWhile->name === 'repeatForever')
{
$arData['RRULE']['UNTIL'] = MakeTimeStamp('');;
}
elseif ($obWhile->name === 'windowEnd')
{
$toTsUTC = $this->__makeTS($obWhile->textContent());
$arData['RRULE']['UNTIL'] = ConvertTimeStamp($toTsUTC, 'FULL');
}
elseif ($obWhile->name === 'repeatInstances')
{
$arData['RRULE']['COUNT'] = intval($obWhile->textContent());
}
}
elseif(($arData['fRecurrence'] === -1) && ($id > 0))
{
$arData['RRULE'] = -1;
}
$arFields = [
"ID" => $id,
'CAL_TYPE' => $calType,
'OWNER_ID' => $ownerId,
'CREATED_BY' => $userId,
'NAME' => $arData['Title'],
'DESCRIPTION' => self::ClearOutlookHtml($arData['Description']),
'SECTIONS' => [$arSection['ID']],
'ACCESSIBILITY' => $arStatusValues[$arData['MetaInfo_BusyStatus']],
'IMPORTANCE' => $arPriorityValues[$arData['MetaInfo_Priority']],
'RRULE' => $arData['RRULE'],
'LOCATION' => BitrixCalendarRoomsUtil::unParseTextLocation($arData['Location'])
];
if ($fromTs && $toTs)
{
$arFields['DATE_FROM'] = CCalendar::Date($fromTs, $skipTime === 'N');
$arFields['DATE_TO'] = CCalendar::Date($toTs, $skipTime === 'N');
$arFields['DT_SKIP_TIME'] = $skipTime;
}
if (isset($arData['DT_LENGTH']) && $arData['DT_LENGTH'] > 0)
{
$arFields['DT_LENGTH'] = $arData['DT_LENGTH'];
}
$eventId = CCalendar::SaveEvent(
[
'arFields' => $arFields,
'fromWebservice' => true
]
);
if ($eventId && ((int)$eventId) > 0)
{
$eventId = (int)$eventId;
$replicationId[$eventId] = $arData['MetaInfo_ReplicationID'];
$responseRows[$eventId] = new CXMLCreator('Result');
$responseRows[$eventId]->setAttribute('ID', $obMethod->getAttribute('ID').','.$arData['_command']);
$responseRows[$eventId]->setAttribute('List', $listName);
$responseRows[$eventId]->addChild($obNode = new CXMLCreator('ErrorCode'));
$obNode->setData('0x00000000');
//$responseRows[$eventId]->setAttribute('Version', 3);
}
}
}
$userId = (is_object($USER) && $USER->GetID()) ? $USER->GetID() : 1;
$fetchMeetings = (int)CCalendar::GetMeetingSection($userId) === (int)$arSection['ID'];
$arEvents = CCalendarEvent::GetList(
[
'arFilter' => [
'CAL_TYPE' => $calType,
'OWNER_ID' => $ownerId,
'SECTION' => $arSection['ID']
],
'getUserfields' => false,
'parseRecursion' => false,
'fetchAttendees' => false,
'fetchMeetings' => $fetchMeetings,
'userId' => $userId
]
);
foreach ($arEvents as $event)
{
if ($responseRows[$event['ID']])
{
$last_change = 0;
$obRow = $this->__getRow($event, $listName, $last_change);
$obRow->setAttribute('xmlns:z', "#RowsetSchema");
if ($replicationId[$event['ID']])
{
$obRow->setAttribute('MetaInfo_ReplicationID', $replicationId[$event['ID']]);
}
$responseRows[$event['ID']]->addChild($obRow);
}
$obResponse->addChild($responseRows[$event['ID']]);
}
return ['UpdateListItemsResult' => $obResponse];
}