50 $userSectionPermissions = [],
52 $bClearOperationCache =
false,
57 private static function GetFields()
60 if (empty(self::$Fields))
63 "ID" => [
"FIELD_NAME" =>
"CS.ID",
"FIELD_TYPE" =>
"int"],
64 "NAME" => [
"FIELD_NAME" =>
"CS.NAME",
"FIELD_TYPE" =>
"string"],
65 "XML_ID" => [
"FIELD_NAME" =>
"CS.XML_ID",
"FIELD_TYPE" =>
"string"],
66 "EXTERNAL_ID" => [
"FIELD_NAME" =>
"CS.EXTERNAL_ID",
"FIELD_TYPE" =>
"string"],
67 "ACTIVE" => [
"FIELD_NAME" =>
"CS.ACTIVE",
"FIELD_TYPE" =>
"string"],
68 "COLOR" => [
"FIELD_NAME" =>
"CS.COLOR",
"FIELD_TYPE" =>
"string"],
69 "SORT" => [
"FIELD_NAME" =>
"CS.SORT",
"FIELD_TYPE" =>
"int"],
70 "CAL_TYPE" => [
"FIELD_NAME" =>
"CS.CAL_TYPE",
"FIELD_TYPE" =>
"string",
"PROCENT" =>
"N"],
71 "OWNER_ID" => [
"FIELD_NAME" =>
"CS.OWNER_ID",
"FIELD_TYPE" =>
"int"],
72 "CREATED_BY" => [
"FIELD_NAME" =>
"CS.CREATED_BY",
"FIELD_TYPE" =>
"int"],
73 "PARENT_ID" => [
"FIELD_NAME" =>
"CS.PARENT_ID",
"FIELD_TYPE" =>
"int"],
75 "~FIELD_NAME" =>
"CS.TIMESTAMP_X",
76 "FIELD_NAME" =>
$DB->DateToCharFunction(
"CS.TIMESTAMP_X") .
' as TIMESTAMP_X',
77 "FIELD_TYPE" =>
"date"
80 "~FIELD_NAME" =>
"CS.DATE_CREATE",
81 "FIELD_NAME" =>
$DB->DateToCharFunction(
"CS.DATE_CREATE") .
' as DATE_CREATE',
82 "FIELD_TYPE" =>
"date"
84 "DAV_EXCH_CAL" => [
"FIELD_NAME" =>
"CS.DAV_EXCH_CAL",
"FIELD_TYPE" =>
"string"],
86 "DAV_EXCH_MOD" => [
"FIELD_NAME" =>
"CS.DAV_EXCH_MOD",
"FIELD_TYPE" =>
"string"],
88 "CAL_DAV_CON" => [
"FIELD_NAME" =>
"CS.CAL_DAV_CON",
"FIELD_TYPE" =>
"string"],
90 "CAL_DAV_CAL" => [
"FIELD_NAME" =>
"CS.CAL_DAV_CAL",
"FIELD_TYPE" =>
"string"],
92 "CAL_DAV_MOD" => [
"FIELD_NAME" =>
"CS.CAL_DAV_MOD",
"FIELD_TYPE" =>
"string"],
94 "IS_EXCHANGE" => [
"FIELD_NAME" =>
"CS.IS_EXCHANGE",
"FIELD_TYPE" =>
"string"],
95 "SYNC_TOKEN" => [
"FIELD_NAME" =>
"CS.SYNC_TOKEN",
"FIELD_TYPE" =>
"string"],
96 "PAGE_TOKEN" => [
"FIELD_NAME" =>
"CS.PAGE_TOKEN",
"FIELD_TYPE" =>
"string"],
102 private static function getSectionFields():
array
133 $checkPermissions = (
$params[
'checkPermissions'] ??
null) !==
false;
134 $params[
'joinTypeInfo'] = (bool)(
$params[
'joinTypeInfo'] ??
null);
135 $params[
'checkPermissions'] = $checkPermissions;
136 $params[
'getPermissions'] = (
$params[
'getPermissions'] ??
null) !==
false;
139 $cacheEnabled = CCalendar::CacheTime() > 0;
143 $cache =
new CPHPCache;
144 $cacheId =
'section_list_'.serialize(
$params).(CCalendar::IsSocnetAdmin() ?
'socnet_admin' :
'');
145 $cachePath = CCalendar::CachePath().
'section_list';
147 if ($cache->InitCache(CCalendar::CacheTime(), $cacheId, $cachePath))
149 $res = $cache->GetVars();
151 $sectionIdList =
$res[
"arSectionIds"];
152 $permissions =
$res[
"permissions"];
153 if (is_array($permissions))
155 foreach(
$res[
"permissions"] as $sectionId => $perms)
157 self::$Permissions[$sectionId] = $perms;
163 if (!$cacheEnabled || !isset($sectionIdList))
165 $sectionList = self::getListOrm(
$params);
169 $checkedConnections = [];
170 $isExchangeEnabled = CCalendar::IsExchangeEnabled();
171 $isCalDAVEnabled = CCalendar::IsCalDAVEnabled();
172 $isIntranetEnabled = CCalendar::IsIntranetEnabled();
173 $groupCalType = Dictionary::CALENDAR_TYPE[
'group'];
174 $groupSectionIds = array_filter(
176 static fn (
array $section) => (
177 $section[
'CAL_TYPE'] === $groupCalType ? (
int)$section[
'OWNER_ID'] :
null
184 foreach ($sectionList as $section)
186 $sectId = (int)$section[
'ID'];
188 if (in_array($sectId, $sectionIdList,
true))
193 if ($checkPermissions)
195 self::HandlePermission($section);
198 $sectionType = $section[
'CAL_TYPE'];
203 && !in_array($sectionType, [
204 Dictionary::CALENDAR_TYPE[
'location'],
205 Dictionary::CALENDAR_TYPE[
'open_event']
209 $section[
'OUTLOOK_JS'] =
'needAction';
212 unset($section[
'ACCESS_CODE'], $section[
'TASK_ID']);
214 $sectionIdList[] = $sectId;
216 $section[
'EXPORT'] = [
218 'LINK' => self::GetExportLink($section[
'ID'], $sectionType, $section[
'OWNER_ID'] ??
null)
221 if ($sectionType ===
'user')
223 $section[
'IS_EXCHANGE'] = $section[
'DAV_EXCH_CAL'] && $isExchangeEnabled;
224 if ($section[
'CAL_DAV_CON'] && $isCalDAVEnabled)
226 $connectionId = (int)$section[
"CAL_DAV_CON"];
228 if (isset($checkedConnections[$connectionId]))
230 $section[
'CAL_DAV_CON'] = $checkedConnections[$connectionId] ? $connectionId :
false;
236 [
"ID" => $connectionId]
245 $section[
'CAL_DAV_CON'] =
false;
248 $checkedConnections[$connectionId] = (bool)
$connection;
254 $section[
'IS_EXCHANGE'] =
false;
255 $section[
'CAL_DAV_CON'] =
false;
260 $sectionType === Dictionary::CALENDAR_TYPE[
'group']
261 && in_array((
int)$section[
'OWNER_ID'], $collabIds,
true)
266 $section[
'IS_COLLAB'] = $isCollab;
273 $cache->StartDataCache(CCalendar::CacheTime(), $cacheId, $cachePath);
274 $cache->EndDataCache([
276 "arSectionIds" => $sectionIdList,
277 "permissions" => self::$Permissions,
282 if (($checkPermissions ||
$params[
'getPermissions']) &&
$userId >= 0 && !empty($sectionIdList))
297 private static function getListOrm(
$params)
301 $orderFields =
$params[
'arOrder'] ?? [];
304 $query = SectionTable::query();
312 if (is_string($value) && !$value)
322 case 'EXTERNAL_TYPE':
323 if (is_array($value))
325 $queryFilter->whereIn(
$key, $value);
329 $queryFilter->where(
$key, $value);
335 $queryFilter->where(
'ID',
'>', (
int)$value);
341 $queryFilter->where(
'ACTIVE', $value);
345 if (is_array($value))
347 $params[
'joinTypeInfo'] =
true;
350 ->where(
'TYPE.ACTIVE',
'Y')
351 ->whereIn(
'CAL_TYPE', $value)
356 $queryFilter->where(
'CAL_TYPE', $value);
362 if (is_array($value))
364 $queryFilter->whereIn(
$key, $value);
368 $queryFilter->where(
$key, $value);
382 \Bitrix\Main\ORM\Query\Query::filter()
385 ->where($queryFilter)
393 else if ($queryFilter)
395 $query->where($queryFilter);
400 $query->registerRuntimeField(
402 new \Bitrix\Main\Entity\ReferenceField(
404 \Bitrix\Calendar\Internals\TypeTable::getEntity(),
405 \Bitrix\Main\ORM\Query\Join::on(
'ref.XML_ID',
'this.CAL_TYPE'),
406 [
'join_type' => \Bitrix\Main\ORM\Query\Join::TYPE_INNER]
422 $orderList[
$key] = (mb_strtoupper(
$order) ===
'DESC') ?
'DESC' :
'ASC';
426 if (!empty($orderList))
428 $query->setOrder($orderList);
436 $sectionQuery =
$query->exec();
438 [$sectionIdList,
$result] = self::prepareSectionQueryData($sectionQuery);
448 private static function prepareSectionQueryData(
$query)
453 while ($section =
$query->fetch())
456 $section[
'NAME'] = Emoji::decode($section[
'NAME'] ??
'');
458 if (!empty($section[
'DATE_CREATE']))
460 $section[
'DATE_CREATE'] = (string)$section[
'DATE_CREATE'];
463 if (!empty($section[
'TIMESTAMP_X']))
465 $section[
'TIMESTAMP_X'] = (string)$section[
'TIMESTAMP_X'];
473 return [$sectionIdList,
$result];
476 private static function getSectionAccess($sectionIdList, $sections)
478 if (empty($sectionIdList))
483 $noCacheForSectionIds = array_diff($sectionIdList, array_keys(self::$sectionAccessCache));
484 if (!$noCacheForSectionIds)
487 foreach ($sectionIdList as $sectionId)
495 $accessQuery = \Bitrix\Calendar\Internals\AccessTable::query()
501 ->whereIn(
'SECT_ID', $sectionIdList)
505 while (
$access = $accessQuery->fetch())
507 if (!isset($sections[
$access[
'SECT_ID']][
'ACCESS']))
509 $sections[
$access[
'SECT_ID']][
'ACCESS'] = [];
515 foreach ($sectionIdList as $sectionId)
517 unset(self::$sectionAccessCache[$sectionId]);
524 private static function getListOld(
$params)
529 $sort =
$params[
'arOrder'] ?? [
'SORT' =>
'asc'];
535 $filterKeys = array_keys(
$filter);
536 foreach ($filterKeys as $filterKey)
538 $n = mb_strtoupper($filterKey);
540 if ((
$val ===
'') ||
$val ===
"NOT_REF")
545 if (
$n ===
'CAL_TYPE' && (
$val ===
'company_calendar' ||
$val ===
'calendar_company'))
547 $arSqlSearch[] =
'CS.CAL_TYPE = \'' .
$val .
'\' AND CS.CAL_TYPE IS NOT NULL
';
553 || $n === 'EXTERNAL_TYPE
'
554 // || $n === 'CAL_DAV_CON
'
559 $val = array_map(array($DB, "ForSQL"), $val);
560 $arSqlSearch[] = 'CS.
'.$n.' IN (\
''.implode(
'\',\
'',
$val).
'\')
';
564 $arSqlSearch[] = GetFilterQuery("CS.".$n, $val, 'N
');
567 else if($n === '>ID
' && (int)$val > 0)
569 $arSqlSearch[] = "CS.ID > ". (int)$val;
571 elseif($n === 'ACTIVE
' && $val === "Y")
573 $arSqlSearch[] = "CS.ACTIVE = 'Y
'";
575 elseif ($n === 'CAL_TYPE
' && is_array($val))
577 $params['joinTypeInfo
'] = true;
579 foreach($val as $type)
581 $strType .= ",'" . $DB->ForSql($type) . "'";
583 $arSqlSearch[] = "CS.CAL_TYPE in (".trim($strType, ", ").")";
584 $arSqlSearch[] = "CT.ACTIVE='Y
'";
586 elseif(isset($arFields[$n]))
588 $arSqlSearch[] = GetFilterQuery(
589 $arFields[$n]["FIELD_NAME"],
591 (isset($arFields[$n]["PROCENT"]) && $arFields[$n]["PROCENT"] === "N") ? "N" : "Y"
598 foreach($sort as $by => $order)
600 if(isset($arFields[mb_strtoupper($by)]))
602 $byName = $arFields[mb_strtoupper($by)]["~FIELD_NAME"]
603 ?? $arFields[mb_strtoupper($by)]["FIELD_NAME"]
605 $strOrderBy .= $byName.' '.(mb_strtolower($order) === 'desc
'?'desc
':'asc
').',
';
611 $strOrderBy = "ORDER BY ".rtrim($strOrderBy, ",");
614 $strSqlSearch = GetFilterSqlSearch($arSqlSearch);
616 if (!empty($filter['ADDITIONAL_IDS
'] && is_array($filter['ADDITIONAL_IDS
'])))
619 foreach($filter['ADDITIONAL_IDS
'] as $adid)
621 $strTypes .= ",". (int)$adid;
623 $strSqlSearch = '(
'.$strSqlSearch.') OR ID in(
'.trim($strTypes, ',
').')
';
627 if (isset($params['limit
']) && (int)$params['limit
'] > 0)
629 $strLimit = 'LIMIT
'. (int)$params['limit
'];
633 $from = 'b_calendar_section CS
';
635 // Fetch types info into selection
636 if ($params['joinTypeInfo
'])
638 $select .= ", CT.NAME AS TYPE_NAME, CT.DESCRIPTION AS TYPE_DESC";
639 $from .= "\n INNER JOIN b_calendar_type CT ON (CS.CAL_TYPE=CT.XML_ID)";
642 if ($params['getPermissions
'])
644 $select .= ", CAP.ACCESS_CODE, CAP.TASK_ID";
645 $from .= "\n LEFT JOIN b_calendar_access CAP ON (CS.ID=".$DB->ToNumber('CAP.SECT_ID
').")";
659 $res = $DB->Query($strSql);
661 while ($sect = $res->Fetch())
669 public static function GetSectionPermission(array $array, $getPermissions = null)
674 foreach ($array as $section)
676 $sectId = $section['ID
'];
677 $userId = CCalendar::GetUserId();
679 $accessController = new SectionAccessController($userId);
680 $sectionModel = SectionModel::createFromArray($section);
683 ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME => [],
684 ActionDictionary::ACTION_SECTION_EVENT_VIEW_TITLE => [],
685 ActionDictionary::ACTION_SECTION_EVENT_VIEW_FULL => [],
686 ActionDictionary::ACTION_SECTION_ADD => [],
687 ActionDictionary::ACTION_SECTION_EDIT => [],
688 ActionDictionary::ACTION_SECTION_ACCESS => [],
691 $result = $accessController->batchCheck($request, $sectionModel);
693 if ($result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME])
696 'view_time
' => $result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME],
697 'view_title
' => $result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TITLE],
698 'view_full
' => $result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_FULL],
699 'add
' => $result[ActionDictionary::ACTION_SECTION_ADD],
700 'edit
' => $result[ActionDictionary::ACTION_SECTION_EDIT],
701 'edit_section
' => $result[ActionDictionary::ACTION_SECTION_EDIT],
702 'access
' => $result[ActionDictionary::ACTION_SECTION_ACCESS],
705 if ($getPermissions || $section['PERM
']['access
'] || $section['CAL_TYPE
'] === 'location
')
707 $section['ACCESS
'] = [];
709 isset(self::$Permissions[$sectId])
710 && is_array(self::$Permissions[$sectId])
711 && !empty(self::$Permissions[$sectId])
714 // Add codes to get they full names for interface
715 $currentAccessCodes = array_keys(self::$Permissions[$sectId]);
716 foreach ($currentAccessCodes as $code)
718 if (!in_array($code, $accessCodes, true))
720 $accessCodes[] = $code;
724 $section['ACCESS
'] = self::$Permissions[$sectId];
728 CCalendar::PushAccessNames($accessCodes);
737 public static function GetById(int $id = 0, bool $checkPermissions = true, bool $bRerequest = false)
741 if (!isset(self::$sections[$id]) || $bRerequest)
743 $section = self::GetList([
744 'arFilter
' => ['ID
' => $id],
745 'checkPermissions
' => $checkPermissions,
748 if($section && is_array($section) && is_array($section[0]))
750 self::$sections[$id] = $section[0];
756 return self::$sections[$id];
764 public static function GetSuperposedList($params = [])
767 $checkPermissions = ($params['checkPermissions
'] ?? null) !== false;
768 $userId = isset($params['userId
']) ? (int)$params['userId
'] : CCalendar::GetCurUserId();
777 $helper = Application::getConnection()->getSqlHelper();
779 if ($checkPermissions)
781 $select .= ", CAP.ACCESS_CODE, CAP.TASK_ID";
782 $from .= "\n LEFT JOIN b_calendar_access CAP ON ({$helper->castToChar('CS.ID
')}=CAP.SECT_ID)";
787 if (isset($params['TYPES
']) && is_array($params['TYPES
']))
789 foreach($params['TYPES
'] as $type)
791 $strTypes .= ",'" . $DB->ForSql($type) . "'";
794 $strTypes = trim($strTypes, ", ");
797 $sqlSearch .= "(CS.CAL_TYPE in (" . $strTypes . "))";
805 foreach(
$params[
'GROUPS'] as $ownerId)
807 if ((
int)$ownerId > 0)
809 $strGroups .=
"," . (int)$ownerId;
813 if ($strGroups !=
"0")
815 if ($sqlSearch !=
"")
817 $sqlSearch .=
" OR ";
819 $sqlSearch .=
"(CS.OWNER_ID in (".$strGroups.
") AND CS.CAL_TYPE='group')";
823 if ($sqlSearch !=
"")
828 CT.NAME AS TYPE_NAME, CT.DESCRIPTION AS TYPE_DESC".$select.
"
830 b_calendar_section CS
831 LEFT JOIN b_calendar_type CT ON (CS.CAL_TYPE=CT.XML_ID)".$from.
"
846 if ($checkPermissions)
848 self::HandlePermission(
$arRes);
852 if (!in_array(
$arRes[
'ID'], $arSectionIds))
854 $arSectionIds[] =
$arRes[
'ID'];
865 foreach(
$params[
'USERS'] as $ownerId)
867 if ((
int)$ownerId > 0)
869 $strUsers .=
",". (int)$ownerId;
873 if ($strUsers !=
"0")
878 U.LOGIN AS USER_LOGIN, U.NAME AS USER_NAME, U.LAST_NAME AS USER_LAST_NAME, U.SECOND_NAME AS USER_SECOND_NAME".$select.
"
880 b_calendar_section CS
881 LEFT JOIN b_user U ON (CS.OWNER_ID=U.ID)".$from.
"
886 CS.OWNER_ID in (".$strUsers.
")
896 if ($checkPermissions)
898 self::HandlePermission(
$arRes);
902 if (!in_array(
$arRes[
'ID'], $arSectionIds))
904 $arSectionIds[] =
$arRes[
'ID'];
910 if ($checkPermissions && !empty($arSectionIds))
916 $sectId = $sect[
'ID'];
917 $ownerId = $sect[
'OWNER_ID'];
921 SectionModel::createFromId((
int)$sectId)
922 ->setType($sect[
'CAL_TYPE'])
923 ->setOwnerId((
int)$ownerId)
926 ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME => [],
927 ActionDictionary::ACTION_SECTION_EVENT_VIEW_TITLE => [],
928 ActionDictionary::ACTION_SECTION_EVENT_VIEW_FULL => [],
929 ActionDictionary::ACTION_SECTION_ADD => [],
930 ActionDictionary::ACTION_SECTION_EDIT => [],
931 ActionDictionary::ACTION_SECTION_ACCESS => [],
936 if (
$result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME] && !in_array($sectId, $sectIds))
939 'view_time' =>
$result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME],
940 'view_title' =>
$result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TITLE],
941 'view_full' =>
$result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_FULL],
942 'add' =>
$result[ActionDictionary::ACTION_SECTION_ADD],
943 'edit' =>
$result[ActionDictionary::ACTION_SECTION_EDIT],
944 'edit_section' =>
$result[ActionDictionary::ACTION_SECTION_EDIT],
945 'access' =>
$result[ActionDictionary::ACTION_SECTION_ACCESS],
948 if ($sect[
'CAL_TYPE'] ===
'user')
950 if (isset($sect[
'USER_NAME'], $sect[
'USER_LAST_NAME']))
953 "NAME" => $sect[
'USER_NAME'],
954 "LAST_NAME" => $sect[
'USER_LAST_NAME'],
955 "LOGIN" => $sect[
'USER_LOGIN'],
957 "SECOND_NAME" => $sect[
'USER_SECOND_NAME'])
961 $sect[
'USER_LAST_NAME'],
962 $sect[
'USER_SECOND_NAME'],
971 elseif ($sect[
'CAL_TYPE'] ===
'group' && isset(
$params[
'arGroups']))
973 $sect[
'OWNER_NAME'] =
$params[
'arGroups'][$ownerId][
'NAME'];
977 $sectIds[] = $sectId;
985 if (!empty($section[
'NAME']))
987 $section[
'NAME'] = Emoji::decode($section[
'NAME']);
1049 $originalSection = SectionTable::getById($id);
1051 $originalSection !==
false
1052 && is_array($originalSection)
1053 && $originalSection[
'EXTERNAL_TYPE'] !== self::EXTERNAL_TYPE_LOCAL
1056 $sectionFields[
'EXTERNAL_TYPE'] = $originalSection[
'EXTERNAL_TYPE'];
1061 $strSql =
"UPDATE b_calendar_section SET ". $strUpdate .
" WHERE ID = " . $id;
1070 SectionModel::createFromId($id)
1078 self::SavePermissions(
1090 self::SavePermissions(
1097 if ($isNewSection && $id > 0 && !isset(
$sectionFields[
'ACCESS']))
1099 self::SavePermissions(
1109 SectionTable::update($id, [
1114 CCalendar::ClearCache([
'section_list',
'event_list']);
1116 if ($id > 0 && isset(self::$Permissions[$id]))
1118 unset(self::$Permissions[$id]);
1124 self::onCreateSync($id, [
1132 self::onUpdateSync($id, [
1162 PushCommand::EditSection,
1166 'newSection' => $isNewSection,
1181 if ($checkPermissions !==
false && !$canEdit)
1183 return CCalendar::ThrowError(
'EC_ACCESS_DENIED');
1189 $strSql =
"select CE.ID, CE.PARENT_ID, CE.CREATED_BY
1190 from b_calendar_event CE
1191 where CE.SECTION_ID=".$id.
"
1192 and (CE.IS_MEETING='1' and CE.IS_MEETING is not null)
1193 and (CE.DELETED='N' and CE.DELETED is not null)";
1199 $strSql =
"SELECT CE.ID, CE.PARENT_ID, CE.DELETED, CE.CREATED_BY, CES.SECT_ID, CES.EVENT_ID
1200 FROM b_calendar_event CE
1201 LEFT JOIN b_calendar_event_sect CES ON (CE.ID=CES.EVENT_ID)
1202 WHERE CES.SECT_ID=".$id.
"
1203 AND (CE.IS_MEETING='1' and CE.IS_MEETING is not null)
1204 AND (CE.DELETED='N' and CE.DELETED is not null)";
1208 while($ev =
$res->Fetch())
1210 if ((
int)$ev[
'ID'] === (
int)$ev[
'PARENT_ID'])
1212 $meetingIds[] = (int)$ev[
'PARENT_ID'];
1216 $pullUserId = (int)$ev[
'CREATED_BY'] > 0 ? (
int)$ev[
'CREATED_BY'] : CCalendar::GetCurUserId();
1223 PushCommand::DeleteEvent,
1232 if (!empty($meetingIds))
1234 $DB->Query(
"DELETE from b_calendar_event WHERE PARENT_ID in (".implode(
',', $meetingIds).
")");
1238 self::onDeleteSync($id, [
1239 'originalFrom' =>
$params[
'originalFrom'] ??
'',
1245 $DB->Query(
"DELETE FROM b_calendar_event_sect WHERE SECT_ID=".$id);
1249 $DB->Query(
"DELETE FROM b_calendar_section WHERE ID=".$id);
1251 CCalendarEvent::DeleteEmpty($id);
1252 self::CleanAccessTable($id);
1253 CCalendar::ClearCache(
array(
'section_list',
'event_list'));
1267 PushCommand::DeleteSection,
1282 $params[
'type'] === Dictionary::CALENDAR_TYPE[
'user']
1283 ||
$params[
'type'] === Dictionary::CALENDAR_TYPE[
'group']
1290 $name =
$params[
'type'] ===
'location' ? Loc::getMessage(
'EC_DEF_SECT_LOCATION_CAL') : Loc::getMessage(
'EC_DEF_SECT_GROUP_CAL');
1295 $isCollabSection =
$params[
'type'] === Dictionary::CALENDAR_TYPE[
'group']
1300 if ($isCollabSection)
1308 'CAL_TYPE' =>
$params[
'type'],
1310 'DESCRIPTION' => Loc::getMessage(
'EC_DEF_SECT_DESC'),
1312 'OWNER_ID' =>
$params[
'ownerId'],
1314 'ACCESS' => self::GetDefaultAccess(
$params[
'type'],
$params[
'ownerId']),
1316 'view_time' =>
true,
1317 'view_title' =>
true,
1318 'view_full' =>
true,
1321 'edit_section' =>
true,
1324 'EXTERNAL_TYPE' => self::EXTERNAL_TYPE_LOCAL,
1325 'IS_COLLAB' => $isCollabSection,
1328 if(
$params[
'type'] ===
'location')
1333 $builder = new \Bitrix\Calendar\Core\Builders\Rooms\RoomBuilderFromArray(
$arFields);
1334 $room = $builder->build();
1340 ->eventHandler(
'OnAfterCalendarRoomCreate')
1341 ->addPullEvent(PushCommand::CreateRoom)
1365 $DB->Query(
"DELETE FROM b_calendar_access WHERE SECT_ID='".(
int)$sectId.
"'");
1367 if (is_array($taskPerm))
1369 foreach($taskPerm as $accessCode => $taskId)
1371 if (strpos($accessCode,
"SG") === 0)
1373 $accessCode = self::prepareGroupCode($accessCode);
1376 $insert =
$DB->PrepareInsert(
1377 "b_calendar_access",
1379 "ACCESS_CODE" => $accessCode,
1380 "TASK_ID" => (
int)$taskId,
1381 "SECT_ID" => (
int)$sectId,
1384 $strSql =
"INSERT INTO b_calendar_access(".$insert[0].
") VALUES(".$insert[1].
")";
1385 $DB->Query($strSql );
1390 private static function prepareGroupCode(
$code)
1392 $parsedCode = explode(
'_',
$code);
1394 if (
count($parsedCode) === 1)
1410 $s .=
",'". (int)$id .
"'";
1415 $strSql =
'SELECT SC.ID, CAP.ACCESS_CODE, CAP.TASK_ID, SC.CAL_TYPE, SC.OWNER_ID, SC.CREATED_BY
1416 FROM b_calendar_section SC
1417 LEFT JOIN b_calendar_access CAP ON CAP.SECT_ID = '.$helper->castToChar(
'SC.ID').
'
1418 WHERE SC.ID in ('.$s.
')'
1426 self::HandlePermission(
$arRes);
1430 return self::$Permissions;
1435 self::$bClearOperationCache =
$val;
1442 if ((!
$USER || !is_object(
$USER)) ||
$USER->CanDoOperation(
'edit_php'))
1449 $userId = CCalendar::GetCurUserId();
1453 CCalendar::IsBitrix24()
1455 && CBitrix24::isPortalAdmin(
$userId)
1462 CCalendar::IsSocNet()
1463 && CCalendar::IsSocnetAdmin()
1465 CCalendar::GetType() ===
'group'
1466 || CCalendar::GetType() ===
'user'
1467 || CCalendar::IsBitrix24()
1474 if ((
int)$sectId && (
int)
$userId && !self::$bClearOperationCache)
1476 $sectionPermKey =
$userId .
'|' . $sectId;
1477 if (isset(self::$userSectionPermissions[$sectionPermKey]))
1479 $res = in_array($operation, self::$userSectionPermissions[$sectionPermKey],
true);
1485 $res = in_array($operation, self::GetOperations($sectId,
$userId),
true);
1488 self::$bClearOperationCache =
false;
1496 $userId = CCalendar::GetCurUserId();
1499 if ((
int)$sectId && (
int)
$userId && !self::$bClearOperationCache)
1501 $sectionPermKey =
$userId .
'|' . $sectId;
1502 if (isset(self::$userSectionPermissions[$sectionPermKey]))
1504 return self::$userSectionPermissions[$sectionPermKey];
1510 $key = $sectId.
'|'.implode(
',', $codes);
1511 if (self::$bClearOperationCache || !is_array(self::$arOp[
$key] ??
null))
1513 if (!isset(self::$Permissions[$sectId]))
1515 self::GetArrayPermissions([$sectId]);
1517 $perms = self::$Permissions[$sectId];
1519 self::$arOp[
$key] = [];
1520 if (is_array($perms))
1522 foreach ($perms as
$code => $taskId)
1524 if (in_array(
$code, $codes,
true))
1532 if ((
int)$sectId && (
int)
$userId)
1534 $sectionPermKey =
$userId .
'|' . $sectId;
1535 self::$userSectionPermissions[$sectionPermKey] = self::$arOp[
$key];
1538 self::$bClearOperationCache =
false;
1540 return self::$arOp[
$key];
1547 $arIds = is_array($section) ? $section :
array($section);
1548 $arIds = array_unique($arIds);
1551 foreach($arIds as $id)
1555 $strIds[] = (int)$id;
1559 $strIds = implode(
',', $strIds);
1561 $strSql =
"SELECT ID, CAL_DAV_CON FROM b_calendar_section WHERE ID in (".$strIds.
")";
1569 if (!is_array($section))
1579 $userId = CCalendar::getCurUserId();
1580 $ownerId = (int)$ownerId;
1583 return '&type='.mb_strtolower(
$type)
1586 .
'&'.
'sec_id='.(int)$sectionId
1587 .
'&sign='.self::getSign(
$userId, $sectionId)
1607 $dbFields[$field] =
false;
1610 $DB->Query(
"UPDATE b_calendar_section SET "
1611 .
$DB->PrepareUpdate(
'b_calendar_section', $dbFields)
1612 .
" WHERE ID = " . $sectionId);
1625 private static function onCreateSync(
int $id,
array $params): ?Result
1627 if (!Loader::includeModule(
'dav'))
1632 $originalFrom =
$params[
'params'][
'originalFrom'] ??
null;
1633 if ($originalFrom === (
$params[
'sectionFields'][
'EXTERNAL_TYPE'] ??
null))
1639 !empty(
$params[
'sectionFields'][
'EXTERNAL_TYPE'])
1641 $params[
'sectionFields'][
'EXTERNAL_TYPE'] === Bitrix\Calendar\Sync\Caldav\Helper::CALDAV_TYPE
1642 ||
$params[
'sectionFields'][
'EXTERNAL_TYPE'] === Bitrix\Calendar\Sync\Caldav\Helper::EXCHANGE_TYPE
1649 if (
$params[
'params'][
'arFields'][
'CAL_TYPE'] !==
'user')
1655 $section = (
new Bitrix\Calendar\Core\Mappers\Section())->getById($id);
1661 $factories = FactoriesCollection::createByUserId(
$params[
'userId']);
1662 if ($factories->count() === 0)
1667 $syncManager =
new Synchronization($factories);
1669 if (!empty($originalFrom))
1671 $context->add(
'sync',
'originalFrom', $originalFrom);
1680 foreach ($factories as $factory)
1682 if ($factory->canSubscribeSection())
1684 $outgoingManager = new \Bitrix\Calendar\Sync\Managers\OutgoingManager($factory->getConnection());
1687 ($vendorResult =
$result->getData()[$factory->getCode()])
1688 && $sectionConnection = $vendorResult->getData()[
'sectionConnection']
1691 $outgoingManager->subscribeSection($sectionConnection);
1701 private static function onUpdateSync(
int $id,
array $params)
1703 if (!Loader::includeModule(
'dav'))
1708 if ((
$params[
'params'][
'arFields'][
'CAL_TYPE'] ??
null) !==
'user')
1713 if (empty(
$params[
'params'][
'arFields'][
'NAME']))
1715 return new Result();
1719 $section = (
new Bitrix\Calendar\Core\Mappers\Section())->getById($id);
1725 $factories = FactoriesCollection::createBySection($section);
1726 if ($factories->count() === 0)
1730 $syncManager =
new Synchronization($factories);
1732 if (!empty(
$params[
'params'][
'originalFrom']))
1734 $context->add(
'sync',
'originalFrom',
$params[
'params'][
'originalFrom']);
1737 return $syncManager->updateSection($section,
$context);
1740 private static function onDeleteSync(
int $id,
array $params)
1742 if (!Loader::includeModule(
'dav'))
1747 $section =
new Bitrix\Calendar\Core\Section\Section();
1748 $section->setId($id);
1750 $factories = FactoriesCollection::createBySection($section);
1752 if ($factories->count() === 0)
1754 self::cleanLinkTables($id);
1758 $syncManager =
new Synchronization($factories);
1760 if (!empty(
$params[
'originalFrom']))
1765 return $syncManager->deleteSection($section,
$context);
1772 $DB->Query(
"DELETE FROM b_calendar_event_connection
1773 WHERE EVENT_ID IN (SELECT EV.ID FROM b_calendar_event EV
1774 WHERE EV.SECTION_ID = " . (
int)$sectId .
");"
1777 $DB->Query(
"DELETE FROM b_calendar_section_connection
1778 WHERE SECTION_ID = " . (
int)$sectId .
";"
1784 $userId = CCalendar::GetCurUserId();
1785 return '&user_id='.$userId.
'&sign='.self::GetSign(
$userId,
'superposed_calendars');
1792 return CIntranetUtils::GetStsSyncURL($Params);
1798 private static function GetUniqCalendarId()
1800 $uniq = COption::GetOptionString(
"calendar",
"~export_uniq_id",
"");
1803 $uniq = md5(uniqid(rand(),
true));
1804 COption::SetOptionString(
"calendar",
"~export_uniq_id", $uniq);
1811 return md5(
$userId.
"||".$sectId.
"||".self::GetUniqCalendarId());
1816 return (md5(
$userId.
"||".$sectId.
"||".self::GetUniqCalendarId()) ==
$sign);
1822 $sectId = $Params[
'sectId'];
1823 $userId = (int)$Params[
'userId'];
1824 $sign = $Params[
'sign'];
1825 $type = mb_strtolower($Params[
'type']);
1826 $ownerId = (int)$Params[
'ownerId'];
1829 $GLOBALS[
'APPLICATION']->RestartBuffer();
1833 return CCalendar::ThrowError(Loc::getMessage(
'EC_ACCESS_DENIED'));
1838 'arFilter' =>
array(
'ID' => $sectId),
1839 'checkPermissions' =>
false,
1845 $arEvents = CCalendarEvent::GetList(
1847 'arFilter' =>
array(
1848 'SECTION' => $arSection[
'ID'],
1850 'getUserfields' =>
false,
1851 'parseRecursion' =>
false,
1852 'fetchAttendees' =>
false,
1853 'fetchMeetings' =>
true,
1857 $iCalEvents = self::FormatICal($arSection, $arEvents);
1861 return CCalendar::ThrowError(Loc::getMessage(
'EC_ACCESS_DENIED'));
1864 self::ShowICalHeaders();
1869 private static function ShowICalHeaders()
1871 header(
"Content-Type: text/calendar; charset=UTF-8");
1872 header(
"Accept-Ranges: bytes");
1873 header(
"Connection: Keep-Alive");
1874 header(
"Keep-Alive: timeout=15, max=100");
1877 private static function FormatICal($section, $events)
1881 $res =
'BEGIN:VCALENDAR'.
"\n".
1882 'PRODID:-//Bitrix//Bitrix Calendar//EN'.
"\n".
1884 'CALSCALE:GREGORIAN'.
"\n".
1885 'METHOD:PUBLISH'.
"\n".
1886 'X-WR-CALNAME:'.self::_ICalPaste($section[
'NAME']).
"\n".
1887 'X-WR-CALDESC:'.self::_ICalPaste($section[
'DESCRIPTION']).
"\n";
1889 $localTime =
new DateTime();
1890 $localOffset = $localTime->getOffset();
1892 foreach ($events as
$event)
1896 if (
$event[
'DT_SKIP_TIME'] ===
"Y")
1898 $dtStart = date(
"Ymd", $fromTs);
1899 $dtEnd = date(
"Ymd", $toTs + CCalendar::GetDayLen());
1903 $fromTsUTC = $fromTs -
$event[
'TZ_OFFSET_FROM'];
1904 $toTsUTC = $toTs -
$event[
'TZ_OFFSET_TO'];
1905 $dtStart = date(
"Ymd\THis\Z", $fromTsUTC);
1906 $dtEnd = date(
"Ymd\THis\Z", $toTsUTC);
1909 $dtStamp = str_replace(
'T000000Z',
'', date(
"Ymd\THisZ", CCalendar::Timestamp(
$event[
'TIMESTAMP_X']) - $localOffset));
1910 $uid = md5(uniqid(rand(),
true).
$event[
'ID']).
'@bitrix';
1915 if($rrule && isset($rrule[
'FREQ']) && $rrule[
'FREQ'] !==
'NONE')
1917 $period =
'RRULE:FREQ='.$rrule[
'FREQ'].
';';
1918 $period .=
'INTERVAL='.$rrule[
'INTERVAL'].
';';
1919 if ($rrule[
'FREQ'] ===
'WEEKLY')
1921 $period .=
'BYDAY='.implode(
',', $rrule[
'BYDAY']).
';';
1924 if (isset($rrule[
'COUNT']) && (
int)$rrule[
'COUNT'] > 0)
1926 $period .=
'COUNT='. (int)$rrule[
'COUNT'] .
';';
1930 $until = date(
"Ymd",
$event[
'DATE_TO_TS_UTC']);
1931 if($until !=
'20380101')
1932 $period .=
'UNTIL='.$until.
';';
1934 $period .=
'WKST=MO';
1938 $res .=
'BEGIN:VEVENT'.
"\n";
1940 if (
$event[
'DT_SKIP_TIME'] ===
"Y")
1942 $res .=
'DTSTART;VALUE=DATE:'.$dtStart.
"\n".
1943 'DTEND;VALUE=DATE:'.$dtEnd.
"\n";
1947 $res .=
'DTSTART;VALUE=DATE-TIME:'.$dtStart.
"\n".
1948 'DTEND;VALUE=DATE-TIME:'.$dtEnd.
"\n";
1951 $res .=
'DTSTAMP:'.$dtStamp.
"\n".
1953 'SUMMARY:'.self::_ICalPaste(
$event[
'NAME']).
"\n".
1954 'DESCRIPTION:'.self::_ICalPaste(
$event[
'DESCRIPTION']).
"\n".$period.
"\n".
1955 'LOCATION:'.self::_ICalPaste(CCalendar::GetTextLocation(
$event[
'LOCATION'])).
"\n".
1957 'STATUS:CONFIRMED'.
"\n".
1958 'TRANSP:TRANSPARENT'.
"\n".
1962 $res .=
'END:VCALENDAR';
1967 private static function _ICalPaste(
$str)
1969 $str = preg_replace (
"/\r/i",
'',
$str);
1970 $str = preg_replace (
"/\n/i",
'\\n',
$str);
1979 if ($calendarId[0] === CCalendar::TASK_SECTION_ID)
1981 return CCalendar::Date(round(time() / 180) * 180);
1984 $sectionId = (int)$calendarId[0];
1988 SELECT ".$DB->DateToCharFunction(
"CS.TIMESTAMP_X").
" as TIMESTAMP_X
1989 FROM b_calendar_section CS
1990 WHERE ID=".$sectionId;
1993 if($sect =
$res->Fetch())
1994 return $sect[
'TIMESTAMP_X'];
2002 if (!is_array($arId) && $arId)
2007 $arId = array_unique($arId);
2009 foreach($arId as $id)
2013 $strIds[] = (int)$id;
2016 $strIds = implode(
',', $strIds);
2021 "UPDATE b_calendar_section SET ".
2022 $DB->PrepareUpdate(
"b_calendar_section",
array(
'TIMESTAMP_X' =>
FormatDate(CCalendar::DFormat(
true), time()))).
2023 " WHERE ID in (".$strIds.
")";
2024 $DB->Query($strSql);
2030 if (CCalendar::IsIntranetEnabled())
2032 $access =
array(
'G2' => CCalendar::GetAccessTasksByName(
'calendar_section',
'calendar_view_time'));
2036 $access =
array(
'G2' => CCalendar::GetAccessTasksByName(
'calendar_section',
'calendar_view'));
2039 if (
$type ===
'group' && $ownerId > 0)
2041 $access[
'SG'.$ownerId.
'_A'] = CCalendar::GetAccessTasksByName(
'calendar_section',
'calendar_access');
2042 $access[
'SG'.$ownerId.
'_E'] = CCalendar::GetAccessTasksByName(
'calendar_section',
'calendar_edit');
2043 $access[
'SG'.$ownerId.
'_K'] = CCalendar::GetAccessTasksByName(
'calendar_section',
'calendar_edit');
2045 else if (
$type !==
'user')
2047 $access[
'G2'] = CCalendar::GetAccessTasksByName(
'calendar_section',
'calendar_edit');
2051 if (
$type !==
'user')
2053 $access[
'U'.CCalendar::GetUserId()] = CCalendar::GetAccessTasksByName(
'calendar_section',
'calendar_access');
2059 $accessCodes[] =
$code;
2062 CCalendar::PushAccessNames($accessCodes);
2069 if ((!isset(self::$authHashiCal) || empty(self::$authHashiCal)) &&
$USER && is_object(
$USER))
2071 self::$authHashiCal = $USER::GetHitAuthHash(
$path,
$userId);
2072 if (empty(self::$authHashiCal))
2074 self::$authHashiCal = $USER::AddHitAuthHash(
$path,
$userId);
2077 return self::$authHashiCal;
2094 return $userSettings[
'lastUsedSection'];
2100 $autoCreated =
false;
2107 $res = self::GetList([
2109 'CAL_TYPE' =>
$type,
2110 'OWNER_ID' => $ownerId,
2113 'GAPI_CALENDAR_ID' =>
null,
2115 'checkPermissions' =>
false,
2116 'getPermissions' =>
false,
2120 $section =
$res[0] ??
false;
2124 $ownerId = $section[
'OWNER_ID'];
2125 $sectionId = $section[
'ID'];
2128 if (!$section && $autoCreate)
2130 $section = self::CreateDefault([
2132 'ownerId' => $ownerId,
2135 $autoCreated =
true;
2136 $sectionId = $section[
'ID'];
2140 'sectionId' => $sectionId,
2141 'autoCreated' => $autoCreated,
2142 'section' => $section
2148 if ($section && $section[
'ID'])
2150 $sectionId = $section[
'ID'];
2151 if (!isset(self::$Permissions[$sectionId]) || !is_array(self::$Permissions[$sectionId]))
2153 self::$Permissions[$sectionId] = [];
2156 if (isset($section[
'ACCESS_CODE']) && $section[
'ACCESS_CODE'] && $section[
'ACCESS_CODE'] !==
'0' && (
int)$section[
'TASK_ID'] > 0)
2158 self::$Permissions[$sectionId][$section[
'ACCESS_CODE']] = (int)$section[
'TASK_ID'];
2161 if (isset($section[
'ACCESS']) && $section[
'ACCESS'])
2163 self::$Permissions[$sectionId] = $section[
'ACCESS'];
2166 if ($section[
'CAL_TYPE'] !==
'group' && (
int)$section[
'OWNER_ID'] > 0)
2168 self::$Permissions[$sectionId][
'U'.$section[
'OWNER_ID']] = CCalendar::GetAccessTasksByName(
'calendar_section',
'calendar_access');
2171 if ($section[
'CAL_TYPE'] ===
'group' && (
int)$section[
'OWNER_ID'] > 0)
2173 self::$Permissions[$sectionId][
'SG'.$section[
'OWNER_ID'].
'_A'] = CCalendar::GetAccessTasksByName(
'calendar_section',
'calendar_access');
2181 if (empty($sectionId))
2188 $DB->Query(
"DELETE FROM b_calendar_access WHERE SECT_ID = '" . $sectionId .
"'");
2198 return $davXmlId !==
'' && (preg_match(
'/@virtual\/events\//i', (
string)$davXmlId)
2199 || preg_match(
'/@group\.v\.calendar\.google/i', (
string)$davXmlId)
2209 $res =
$DB->Query(
'select count(*) as c from b_calendar_section');
2221 $resDb = EventTable::getList([
2222 'select' => [
'SECTION_ID',
'OWNER_ID',
'CAL_TYPE'],
2223 'filter' => [
'ID' => $id],
2226 return $resDb->fetch();
2231 if (
$type !==
'user')
2236 if ($sections && is_array($sections))
2238 foreach ($sections as $section)
2241 $section[
'EXTERNAL_TYPE'] === self::EXTERNAL_TYPE_LOCAL
2242 && $section[
'CAL_TYPE'] ===
'user'
2243 && (
int)$section[
'OWNER_ID'] === CCalendar::GetOwnerId()
2265 public static function getAllSectionsForVendor(
int $connectionId,
array $type)
2267 if (!Loader::includeModule(
'dav'))
2270 'status' =>
'error',
2271 'message' => Loc::getMessage(
'EC_SYNCAJAX_DAV_REQUIRED'),
2275 $mapperFactory = \Bitrix\Main\DI\ServiceLocator::getInstance()->get(
'calendar.service.mappers.factory');
2276 if (
$connection = $mapperFactory->getConnection()->getById($connectionId))
2278 $userId = \CCalendar::GetUserId();
2285 return SectionTable::query()
2286 ->setSelect([
'*',
'CONNECTION_ID' =>
'LINK.CONNECTION_ID'])
2287 ->where(
'CAL_TYPE',
'user')
2289 ->whereIn(
'EXTERNAL_TYPE',
$type)
2290 ->where(
'CONNECTION_ID', $connectionId)
2291 ->registerRuntimeField(
2292 new \Bitrix\Main\Entity\ReferenceField(
2294 SectionConnectionTable::class,
2295 [
'=this.ID' =>
'ref.SECTION_ID'],
2296 [
'join_type' =>
'INNER']
2298 )->exec()->fetchAll()
2307 $userId = CCalendar::GetCurUserId();
2310 $isNotInternalUser =
2314 if ($isNotInternalUser)
2317 if (
$type ===
'group')
2319 $perm = CCalendar::GetPermissions([
2321 'ownerId' => $ownerId,
2323 'setProperties' =>
false
2338 in_array(
$type, [
'user', Dictionary::CALENDAR_TYPE[
'open_event']],
true)
2342 $type = [
'user', Dictionary::CALENDAR_TYPE[
'open_event']];
2343 $ownerId = [$ownerId, 0];
2346 $sectionList = CCalendar::getSectionList([
2347 'CAL_TYPE' =>
$type,
2348 'OWNER_ID' => $ownerId,
2350 'ADDITIONAL_IDS' => $followedSectionList,
2351 'checkPermissions' =>
true,
2352 'getPermissions' =>
true,
2356 $sectionList = array_merge($sectionList, CCalendar::getSectionListAvailableForUser(
$userId));
2358 $sectionIdList = [];
2360 foreach ($sectionList as $section)
2362 if (!in_array((
int)$section[
'ID'], $sectionIdList))
2364 if (in_array($section[
'ID'], $followedSectionList))
2366 $section[
'SUPERPOSED'] =
true;
2369 if (!empty($section[
'NAME']))
2373 $sections[] = $section;
2374 $sectionIdList[] = (int) $section[
'ID'];
2390 $noCacheForSectionIds = array_diff($sectionIdList, array_keys(self::$sectionConnectionCache));
2392 if (!$noCacheForSectionIds)
2395 foreach ($sectionIdList as $sectionId)
2397 $result = [...$result, ...self::$sectionConnectionCache[$sectionId]];
2410 ->whereIn(
'SECTION_ID', $sectionIdList)
2414 foreach ($sectionIdList as $sectionId)
2416 self::$sectionConnectionCache[$sectionId] = [];
2419 foreach ($sectionConnections as $sectionConnection)
2421 self::$sectionConnectionCache[$sectionConnection->getSectionId()][] = $sectionConnection;
2424 return $sectionConnections->getAll();
if($strVal !='') $sectionFields
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static createInstanceWithRoom(Room $room)
const ACCESS_ROLE_TO_EXTERNAL_TYPE
static getFollowedSectionIdList($userId=false)
static isSectionStructureConverted()
static addPullEvent(PushCommand $command, int $userId, array $params=[])
static getPathToCalendar(?int $ownerId, ?string $type)
static getUserAccessCodes(int $userId)
static getConnection($name="")
static includeModule($moduleName)
static getString($length, $caseSensitive=false)
static GetOperations($ID, $return_names=false)
static ParseRRULE($rule=null)
static Color($color='', $defaultColor=true)
static Timestamp($date, $bRound=true, $bTime=true)
static GetUserName($user)
static OnDeleteCalendarEventEntry($eventId)
static getAuthHash(int $userId, string $path)
const OPERATION_EDIT_SECTION
static CleanFieldsValueById(int $sectionId, array $fields)
static GetModificationLabel($calendarId)
static prepareSectionListResponse(string $type, string $ownerId)
static CreateDefault($params=[])
static getSectionConnectionList(array $sectionIdList)
static GetLastUsedSection($type, $ownerId, $userId)
static UpdateModificationLabel($arId=[])
static $sectionAccessCache
static SetClearOperationCache($val=true)
static cleanLinkTables($sectId)
static CleanAccessTable(string $sectionId)
static HandlePermission($section=[])
static CheckGoogleVirtualSection($davXmlId='', $externalType='')
static CheckSign($sign, $userId, $sectId)
static $sectionConnectionCache
static GetDefaultAccess($type, $ownerId)
static GetOutlookLink($Params)
static GetList($params=[])
const OPERATION_VIEW_TIME
const OPERATION_VIEW_FULL
static GetSectionForOwner($type, $ownerId, $autoCreate=true)
static GetArrayPermissions($arSections=[])
static GetSectionByEventId($id)
static Delete($id, $checkPermissions=true, $params=[])
static ReturnICal($Params)
static GetSign($userId, $sectId)
static containsLocalSection($sections, $type)
static SavePermissions($sectId, $taskPerm)
static CanDo($operation, $sectId=0, $userId=null)
static GetExportLink($sectionId, $type='', $ownerId=null)
static GetCalDAVConnectionId($section=0)
const EXTERNAL_TYPE_LOCAL
static GetOperations($sectId, $userId=null)
const OPERATION_EDIT_ACCESS
const OPERATION_VIEW_TITLE
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
if(!is_array($deviceNotifyCodes)) $access
ExecuteModuleEventEx($arEvent, $arParams=[])
FormatDate($format="", $timestamp=false, $now=false, ?string $languageId=null)
$GLOBALS['____1690880296']
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']