static function GetNearestEventsList($params = [])
{
$type = $params['bCurUserList'] ? 'user' : $params['type'];
$isFromRest = ($params['fromRest'] ?? false) === true;
// Get current user id
if (!isset($params['userId']) || $params['userId'] <= 0)
{
$curUserId = self::GetCurUserId();
}
else
{
$curUserId = (int)$params['userId'];
}
$accessController = new TypeAccessController($curUserId);
if (!$accessController->check(ActionDictionary::ACTION_TYPE_VIEW, TypeModel::createFromXmlId($type)))
{
return 'access_denied';
}
if (
$params['bCurUserList']
&& (
$curUserId <= 0
|| (
class_exists('CSocNetFeatures')
&& !CSocNetFeatures::IsActiveFeature(SONET_ENTITY_USER, $curUserId, "calendar")
)
)
)
{
return 'inactive_feature';
}
$maxAmount = isset($params['maxAmount']) && (int)$params['maxAmount'] > 0
? (int)$params['maxAmount']
: 75;
$arFilter = array(
'CAL_TYPE' => $type,
'FROM_LIMIT' => $params['fromLimit'],
'TO_LIMIT' => $params['toLimit'],
'DELETED' => 'N',
'ACTIVE_SECTION' => 'Y',
);
if ($params['bCurUserList'])
{
$arFilter['OWNER_ID'] = $curUserId;
}
if (isset($params['sectionId']) && $params['sectionId'])
{
$arFilter["SECTION"] = $params['sectionId'];
}
if ($type === 'user')
{
unset($arFilter['CAL_TYPE']);
}
$selectFields = [
'ID',
'PARENT_ID',
'NAME',
'OWNER_ID',
'RRULE',
'EXDATE',
'DATE_FROM',
'DATE_TO',
'TZ_FROM',
'TZ_TO',
'TZ_OFFSET_FROM',
'TZ_OFFSET_TO',
'IS_MEETING',
'MEETING_STATUS',
'CAL_TYPE',
'DT_LENGTH',
'DT_SKIP_TIME',
'SECTION_ID',
'DATE_FROM_TS_UTC',
'DATE_TO_TS_UTC',
];
if ($isFromRest)
{
$selectFields = array_merge($selectFields, [
'DELETED',
'SYNC_STATUS',
'EVENT_TYPE',
'CREATED_BY',
'ORIGINAL_DATE_FROM',
'TIMESTAMP_X',
'DATE_CREATE',
'ACCESSIBILITY',
'MEETING_HOST',
'MEETING',
'LOCATION',
'REMIND',
'COLOR',
'ATTENDEES_CODES',
'DAV_XML_ID',
'DAV_EXCH_LABEL',
'G_EVENT_ID',
'CAL_DAV_LABEL',
'VERSION',
'RECURRENCE_ID',
'RELATIONS',
]);
}
$eventsList = CCalendarEvent::GetList(
[
'arFilter' => $arFilter,
'arSelect' => $selectFields,
'parseRecursion' => true,
'fetchAttendees' => $isFromRest,
'userId' => $curUserId,
'fetchMeetings' => $type === 'user',
'preciseLimits' => true,
'skipDeclined' => true,
'getUserfields' => $isFromRest,
]
);
$pathToCalendar = self::GetPathForCalendarEx($curUserId);
if (self::Date(time(), false) === $params['fromLimit'])
{
$limitTime = time();
}
else
{
$limitTime = self::Timestamp($params['fromLimit']);
}
$limitTime -= (int)date("Z", $limitTime);
$entryList = [];
foreach ($eventsList as $event)
{
if ($event['IS_MEETING'] && $event["MEETING_STATUS"] === 'N')
{
continue;
}
if ($type === 'user' && !$event['IS_MEETING'] && $event['CAL_TYPE'] !== 'user')
{
continue;
}
$fromTs = self::Timestamp($event['DATE_FROM']);
$toTs = $fromTs + $event['DT_LENGTH'];
$toTsUtc = $toTs - $event['TZ_OFFSET_FROM'];
if ($toTsUtc >= $limitTime)
{
if ($event['DT_SKIP_TIME'] !== "Y")
{
$fromTs -= $event['~USER_OFFSET_FROM'];
$toTs -= $event['~USER_OFFSET_TO'];
}
$event['DATE_FROM'] = self::Date($fromTs, $event['DT_SKIP_TIME'] !== 'Y');
$event['DATE_TO'] = self::Date($toTs, $event['DT_SKIP_TIME'] !== 'Y');
unset($event['TZ_FROM'], $event['TZ_TO'], $event['TZ_OFFSET_FROM'], $event['TZ_OFFSET_TO']);
$event['DT_FROM_TS'] = $fromTs;
$event['DT_TO_TS'] = $toTs;
$event['~URL'] = CHTTP::urlAddParams($pathToCalendar, [
'EVENT_ID' => $event['ID'],
'EVENT_DATE' => self::Date($fromTs, false),
]);
$event['~WEEK_DAY'] = FormatDate("D", $fromTs);
$event['~FROM_TO_HTML'] = self::GetFromToHtml(
$fromTs,
$toTs,
$event['DT_SKIP_TIME'] === 'Y',
$event['DT_LENGTH']
);
$entryList[] = $event;
}
}
// Sort by DATE_FROM_TS
usort($entryList, static function($a, $b){
if ($a['DT_FROM_TS'] === $b['DT_FROM_TS'])
{
return 0;
}
return $a['DT_FROM_TS'] < $b['DT_FROM_TS'] ? -1 : 1;
});
array_splice($entryList, $maxAmount);
return $entryList;
}