["FIELD_NAME" => "CS.ID", "FIELD_TYPE" => "int"], "NAME" => ["FIELD_NAME" => "CS.NAME", "FIELD_TYPE" => "string"], "XML_ID" => ["FIELD_NAME" => "CS.XML_ID", "FIELD_TYPE" => "string"], "EXTERNAL_ID" => ["FIELD_NAME" => "CS.EXTERNAL_ID", "FIELD_TYPE" => "string"], "ACTIVE" => ["FIELD_NAME" => "CS.ACTIVE", "FIELD_TYPE" => "string"], "COLOR" => ["FIELD_NAME" => "CS.COLOR", "FIELD_TYPE" => "string"], "SORT" => ["FIELD_NAME" => "CS.SORT", "FIELD_TYPE" => "int"], "CAL_TYPE" => ["FIELD_NAME" => "CS.CAL_TYPE", "FIELD_TYPE" => "string", "PROCENT" => "N"], "OWNER_ID" => ["FIELD_NAME" => "CS.OWNER_ID", "FIELD_TYPE" => "int"], "CREATED_BY" => ["FIELD_NAME" => "CS.CREATED_BY", "FIELD_TYPE" => "int"], "PARENT_ID" => ["FIELD_NAME" => "CS.PARENT_ID", "FIELD_TYPE" => "int"], "TIMESTAMP_X" => [ "~FIELD_NAME" => "CS.TIMESTAMP_X", "FIELD_NAME" => $DB->DateToCharFunction("CS.TIMESTAMP_X") . ' as TIMESTAMP_X', "FIELD_TYPE" => "date" ], "DATE_CREATE" => [ "~FIELD_NAME" => "CS.DATE_CREATE", "FIELD_NAME" => $DB->DateToCharFunction("CS.DATE_CREATE") . ' as DATE_CREATE', "FIELD_TYPE" => "date" ], "DAV_EXCH_CAL" => ["FIELD_NAME" => "CS.DAV_EXCH_CAL", "FIELD_TYPE" => "string"], // Exchange calendar "DAV_EXCH_MOD" => ["FIELD_NAME" => "CS.DAV_EXCH_MOD", "FIELD_TYPE" => "string"], // Exchange calendar modification label "CAL_DAV_CON" => ["FIELD_NAME" => "CS.CAL_DAV_CON", "FIELD_TYPE" => "string"], // CalDAV connection "CAL_DAV_CAL" => ["FIELD_NAME" => "CS.CAL_DAV_CAL", "FIELD_TYPE" => "string"], // CalDAV calendar "CAL_DAV_MOD" => ["FIELD_NAME" => "CS.CAL_DAV_MOD", "FIELD_TYPE" => "string"], // CalDAV calendar modification label "IS_EXCHANGE" => ["FIELD_NAME" => "CS.IS_EXCHANGE", "FIELD_TYPE" => "string"], "SYNC_TOKEN" => ["FIELD_NAME" => "CS.SYNC_TOKEN", "FIELD_TYPE" => "string"], "PAGE_TOKEN" => ["FIELD_NAME" => "CS.PAGE_TOKEN", "FIELD_TYPE" => "string"], ]; } return self::$Fields; } public static function GetList($params = []) { global $DB; $result = false; $filter = $params['arFilter']; $sort = $params['arOrder'] ?? ['SORT' => 'asc']; $params['joinTypeInfo'] = (bool)($params['joinTypeInfo'] ?? null); $checkPermissions = ($params['checkPermissions'] ?? null) !== false; $params['checkPermissions'] = $checkPermissions; $getPermissions = ($params['getPermissions'] ?? null) !== false; $params['getPermissions'] = $getPermissions; $userId = ($params['userId'] ?? false) ? (int)$params['userId'] : CCalendar::GetCurUserId(); $params['userId'] = $userId; $cacheEnabled = CCalendar::CacheTime() > 0; if ($cacheEnabled) { $cache = new CPHPCache; $cacheId = 'section_list_'.serialize($params).(CCalendar::IsSocnetAdmin() ? 'socnet_admin' : ''); $cachePath = CCalendar::CachePath().'section_list'; if ($cache->InitCache(CCalendar::CacheTime(), $cacheId, $cachePath)) { $res = $cache->GetVars(); $result = $res["arResult"]; $arSectionIds = $res["arSectionIds"]; $permissions = $res["permissions"]; if (is_array($permissions)) { foreach($res["permissions"] as $sectionId => $perms) { self::$Permissions[$sectionId] = $perms; } } } } if (!$cacheEnabled || !isset($arSectionIds)) { $arFields = self::GetFields(); $arSqlSearch = []; if(is_array($filter)) { $filterKeys = array_keys($filter); foreach ($filterKeys as $filterKey) { $n = mb_strtoupper($filterKey); $val = $filter[$filterKey] ?? ''; if (($val === '') || $val === "NOT_REF") { continue; } if ($n === 'CAL_TYPE' && ($val === 'company_calendar' || $val === 'calendar_company')) { $arSqlSearch[] = 'CS.CAL_TYPE = \'' . $val . '\' AND CS.CAL_TYPE IS NOT NULL'; } else if ( $n === 'ID' || $n === 'XML_ID' || $n === 'OWNER_ID' || $n === 'EXTERNAL_TYPE' // || $n === 'CAL_DAV_CON' ) { if (is_array($val)) { $val = array_map(array($DB, "ForSQL"), $val); $arSqlSearch[] = 'CS.'.$n.' IN (\''.implode('\',\'', $val).'\')'; } else { $arSqlSearch[] = GetFilterQuery("CS.".$n, $val, 'N'); } } else if($n === '>ID' && (int)$val > 0) { $arSqlSearch[] = "CS.ID > ". (int)$val; } elseif($n === 'ACTIVE' && $val === "Y") { $arSqlSearch[] = "CS.ACTIVE = 'Y'"; } elseif ($n === 'CAL_TYPE' && is_array($val)) { $params['joinTypeInfo'] = true; $strType = ""; foreach($val as $type) { $strType .= ",'" . $DB->ForSql($type) . "'"; } $arSqlSearch[] = "CS.CAL_TYPE in (".trim($strType, ", ").")"; $arSqlSearch[] = "CT.ACTIVE='Y'"; } elseif(isset($arFields[$n])) { $arSqlSearch[] = GetFilterQuery( $arFields[$n]["FIELD_NAME"], $val, (isset($arFields[$n]["PROCENT"]) && $arFields[$n]["PROCENT"] === "N") ? "N" : "Y" ); } } } $strOrderBy = ''; foreach($sort as $by => $order) { if(isset($arFields[mb_strtoupper($by)])) { $byName = $arFields[mb_strtoupper($by)]["~FIELD_NAME"] ?? $arFields[mb_strtoupper($by)]["FIELD_NAME"] ; $strOrderBy .= $byName.' '.(mb_strtolower($order) === 'desc'?'desc':'asc').','; } } if($strOrderBy) { $strOrderBy = "ORDER BY ".rtrim($strOrderBy, ","); } $strSqlSearch = GetFilterSqlSearch($arSqlSearch); if (isset($filter['ADDITIONAL_IDS']) && is_array($filter['ADDITIONAL_IDS']) && count($filter['ADDITIONAL_IDS']) > 0) { $strTypes = ""; foreach($filter['ADDITIONAL_IDS'] as $adid) { $strTypes .= ",". (int)$adid; } $strSqlSearch = '('.$strSqlSearch.') OR ID in('.trim($strTypes, ', ').')'; } $strLimit = ''; if (isset($params['limit']) && (int)$params['limit'] > 0) { $strLimit = 'LIMIT '. (int)$params['limit']; } $select = 'CS.*'; $from = 'b_calendar_section CS'; // Fetch types info into selection if ($params['joinTypeInfo']) { $select .= ", CT.NAME AS TYPE_NAME, CT.DESCRIPTION AS TYPE_DESC"; $from .= "\n INNER JOIN b_calendar_type CT ON (CS.CAL_TYPE=CT.XML_ID)"; } if ($getPermissions) { $select .= ", CAP.ACCESS_CODE, CAP.TASK_ID"; $from .= "\n LEFT JOIN b_calendar_access CAP ON (CS.ID=CAP.SECT_ID)"; } $strSql = " SELECT $select FROM $from WHERE $strSqlSearch $strOrderBy $strLimit"; $res = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); $result = []; $arSectionIds = []; $isExchangeEnabled = CCalendar::IsExchangeEnabled(); $isCalDAVEnabled = CCalendar::IsCalDAVEnabled(); while($section = $res->Fetch()) { $sectId = (int)$section['ID']; if ($checkPermissions) { self::HandlePermission($section); } if (in_array($sectId, $arSectionIds, true)) { continue; } $sectionType = $section['CAL_TYPE']; // Outlook js if ( $sectionType !== Rooms\Manager::TYPE && CCalendar::IsIntranetEnabled() ) { $section['OUTLOOK_JS'] = 'needAction'; } unset($section['ACCESS_CODE'], $section['TASK_ID']); $section['COLOR'] = CCalendar::Color($section['COLOR']); $section['NAME'] = Emoji::decode($section['NAME']); $arSectionIds[] = $sectId; $section['EXPORT'] = [ 'ALLOW' => true, 'LINK' => self::GetExportLink($section['ID'], $sectionType, $section['OWNER_ID']) ]; if ($sectionType === 'user') { $section['IS_EXCHANGE'] = $section['DAV_EXCH_CAL'] && $isExchangeEnabled; if ($section['CAL_DAV_CON'] && $isCalDAVEnabled) { $section['CAL_DAV_CON'] = (int)$section['CAL_DAV_CON']; $connection = CDavConnection::GetList( ["ID" => "ASC"], ["ID" => $section["CAL_DAV_CON"]] ); if ($connection) { $section['CAL_DAV_CON'] = $connection["ID"]; } else { $section['CAL_DAV_CON'] = false; } } } else { $section['IS_EXCHANGE'] = false; $section['CAL_DAV_CON'] = false; } $result[] = $section; } if ($cacheEnabled) { $cache->StartDataCache(CCalendar::CacheTime(), $cacheId, $cachePath); $cache->EndDataCache(array( "arResult" => $result, "arSectionIds" => $arSectionIds, "permissions" => self::$Permissions, )); } } if (($checkPermissions || $getPermissions) && $userId >= 0 && count($arSectionIds) > 0) { $result = self::GetSectionPermission($result, $getPermissions); } return $result; } public static function GetSectionPermission(array $array, $getPermissions = null) { $res = []; $arAccessCodes = []; $settings = CCalendar::GetSettings(array('request' => false)); foreach ($array as $section) { $sectId = $section['ID']; $userId = CCalendar::GetUserId(); $accessController = new SectionAccessController($userId); $sectionModel = SectionModel::createFromArray($section); $request = [ ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME => [], ActionDictionary::ACTION_SECTION_EVENT_VIEW_TITLE => [], ActionDictionary::ACTION_SECTION_EVENT_VIEW_FULL => [], ActionDictionary::ACTION_SECTION_ADD => [], ActionDictionary::ACTION_SECTION_EDIT => [], ActionDictionary::ACTION_SECTION_ACCESS => [], ]; $result = $accessController->batchCheck($request, $sectionModel); if ($result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME]) { $section['PERM'] = [ 'view_time' => $result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME], 'view_title' => $result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TITLE], 'view_full' => $result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_FULL], 'add' => $result[ActionDictionary::ACTION_SECTION_ADD], 'edit' => $result[ActionDictionary::ACTION_SECTION_EDIT], 'edit_section' => $result[ActionDictionary::ACTION_SECTION_EDIT], 'access' => $result[ActionDictionary::ACTION_SECTION_ACCESS], ]; if ($getPermissions || $section['PERM']['access'] || $section['CAL_TYPE'] === 'location') { $section['ACCESS'] = []; if ( isset(self::$Permissions[$sectId]) && is_array(self::$Permissions[$sectId]) && !empty(self::$Permissions[$sectId]) ) { // Add codes to get they full names for interface $arAccessCodes = array_merge($arAccessCodes, array_keys(self::$Permissions[$sectId])); $section['ACCESS'] = self::$Permissions[$sectId]; } } CCalendar::PushAccessNames($arAccessCodes); $res[] = $section; } } return $res; } public static function GetById(int $id = 0, bool $checkPermissions = true, bool $bRerequest = false) { if ($id > 0) { if (!isset(self::$sections[$id]) || $bRerequest) { $section = self::GetList([ 'arFilter' => ['ID' => $id], 'checkPermissions' => $checkPermissions, ]); if($section && is_array($section) && is_array($section[0])) { self::$sections[$id] = $section[0]; return $section[0]; } } else { return self::$sections[$id]; } } return false; } // public static function GetSuperposedList($params = []) { global $DB; $checkPermissions = ($params['checkPermissions'] ?? null) !== false; $userId = isset($params['userId']) ? (int)$params['userId'] : CCalendar::GetCurUserId(); $arResult = []; $arSectionIds = []; $sqlSearch = ""; $select = ''; $from = ''; if ($checkPermissions) { $select .= ", CAP.ACCESS_CODE, CAP.TASK_ID"; $from .= "\n LEFT JOIN b_calendar_access CAP ON (CS.ID=CAP.SECT_ID)"; } // Common types $strTypes = ""; if (isset($params['TYPES']) && is_array($params['TYPES'])) { foreach($params['TYPES'] as $type) { $strTypes .= ",'" . $DB->ForSql($type) . "'"; } $strTypes = trim($strTypes, ", "); if ($strTypes != "") { $sqlSearch .= "(CS.CAL_TYPE in (" . $strTypes . "))"; } } // Group's calendars $strGroups = "0"; if (!empty($params['GROUPS']) && is_array($params['GROUPS'])) { foreach($params['GROUPS'] as $ownerId) { if ((int)$ownerId > 0) { $strGroups .= "," . (int)$ownerId; } } if ($strGroups != "0") { if ($sqlSearch != "") { $sqlSearch .= " OR "; } $sqlSearch .= "(CS.OWNER_ID in (".$strGroups.") AND CS.CAL_TYPE='group')"; } } if ($sqlSearch != "") { $strSql = " SELECT CS.*, CT.NAME AS TYPE_NAME, CT.DESCRIPTION AS TYPE_DESC".$select." FROM b_calendar_section CS LEFT JOIN b_calendar_type CT ON (CS.CAL_TYPE=CT.XML_ID)".$from." WHERE ( CT.ACTIVE='Y' AND CS.ACTIVE='Y' AND ( $sqlSearch ))"; $res = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); while($arRes = $res->Fetch()) { if ($checkPermissions) { self::HandlePermission($arRes); unset($arRes['ACCESS_CODE'], $arRes['TASK_ID']); } if (!in_array($arRes['ID'], $arSectionIds)) { $arSectionIds[] = $arRes['ID']; $arResult[] = $arRes; } } } // User's calendars $strUsers = "0"; if (isset($params['USERS']) && is_array($params['USERS']) && count($params['USERS']) > 0) { foreach($params['USERS'] as $ownerId) { if ((int)$ownerId > 0) { $strUsers .= ",". (int)$ownerId; } } if ($strUsers != "0") { $strSql = " SELECT CS.*, 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." FROM b_calendar_section CS LEFT JOIN b_user U ON (CS.OWNER_ID=U.ID)".$from." WHERE ( CS.ACTIVE='Y' AND CS.OWNER_ID in (".$strUsers.") AND CS.CAL_TYPE='user' )"; $res = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); } while($arRes = $res->Fetch()) { if ($checkPermissions) { self::HandlePermission($arRes); unset($arRes['ACCESS_CODE'], $arRes['TASK_ID']); } if (!in_array($arRes['ID'], $arSectionIds)) { $arSectionIds[] = $arRes['ID']; $arResult[] = $arRes; } } } if ($checkPermissions && count($arSectionIds) > 0) { $res = []; $sectIds = []; foreach($arResult as $sect) { $sectId = $sect['ID']; $ownerId = $sect['OWNER_ID']; $accessController = new SectionAccessController($userId); $sectionModel = SectionModel::createFromId((int)$sectId) ->setType($sect['CAL_TYPE']) ->setOwnerId((int)$ownerId) ; $request = [ ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME => [], ActionDictionary::ACTION_SECTION_EVENT_VIEW_TITLE => [], ActionDictionary::ACTION_SECTION_EVENT_VIEW_FULL => [], ActionDictionary::ACTION_SECTION_ADD => [], ActionDictionary::ACTION_SECTION_EDIT => [], ActionDictionary::ACTION_SECTION_ACCESS => [], ]; $result = $accessController->batchCheck($request, $sectionModel); if ($result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME] && !in_array($sectId, $sectIds)) { $sect['PERM'] = [ 'view_time' => $result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TIME], 'view_title' => $result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_TITLE], 'view_full' => $result[ActionDictionary::ACTION_SECTION_EVENT_VIEW_FULL], 'add' => $result[ActionDictionary::ACTION_SECTION_ADD], 'edit' => $result[ActionDictionary::ACTION_SECTION_EDIT], 'edit_section' => $result[ActionDictionary::ACTION_SECTION_EDIT], 'access' => $result[ActionDictionary::ACTION_SECTION_ACCESS], ]; if ($sect['CAL_TYPE'] === 'user') { if (isset($sect['USER_NAME'], $sect['USER_LAST_NAME'])) { $sect['OWNER_NAME'] = CCalendar::GetUserName(array( "NAME" => $sect['USER_NAME'], "LAST_NAME" => $sect['USER_LAST_NAME'], "LOGIN" => $sect['USER_LOGIN'], "ID" => $ownerId, "SECOND_NAME" => $sect['USER_SECOND_NAME']) ); unset( $sect['USER_LOGIN'], $sect['USER_LAST_NAME'], $sect['USER_SECOND_NAME'], $sect['USER_NAME'] ); } else { $sect['OWNER_NAME'] = CCalendar::GetUserName($ownerId); } } elseif ($sect['CAL_TYPE'] === 'group' && isset($params['arGroups'])) { $sect['OWNER_NAME'] = $params['arGroups'][$ownerId]['NAME']; } $res[] = $sect; $sectIds[] = $sectId; } } $arResult = $res; } foreach ($arResult as &$section) { if (!empty($section['NAME'])) { $section['NAME'] = Emoji::decode($section['NAME']); } } return $arResult; } public static function Edit($params) { global $DB; $sectionFields = $params['arFields']; $userId = (isset($params['userId']) ? (int)$params['userId'] : CCalendar::GetCurUserId()); $isNewSection = !isset($sectionFields['ID']) || $sectionFields['ID'] <= 0; if (isset($sectionFields['COLOR']) || $isNewSection) { $sectionFields['COLOR'] = CCalendar::Color($sectionFields['COLOR'] ?? null); } $sectionFields['TIMESTAMP_X'] = CCalendar::Date(time()); if (isset($sectionFields['EXPORT']) && is_array($sectionFields['EXPORT'])) { $sectionFields['EXPORT'] = [ 'ALLOW' => (bool)$sectionFields['EXPORT']['ALLOW'], 'SET' => (in_array($sectionFields['EXPORT']['set'] ?? null, array('all', '3_9', '6_12'))) ? $sectionFields['EXPORT']['set'] : 'all', ]; $sectionFields['EXPORT'] = serialize($sectionFields['EXPORT']); } if (!empty($sectionFields['NAME'])) { $sectionFields['NAME'] = Emoji::encode($sectionFields['NAME']); } if ($isNewSection) // Add { if (!isset($sectionFields['DATE_CREATE'])) { $sectionFields['DATE_CREATE'] = CCalendar::Date(time()); } if ((!isset($sectionFields['CREATED_BY']) || !$sectionFields['CREATED_BY'])) { $sectionFields['CREATED_BY'] = CCalendar::GetCurUserId(); } unset($sectionFields['ID']); $id = $DB->Add("b_calendar_section", $sectionFields, ['DESCRIPTION']); } else // Update { $id = (int)$sectionFields['ID']; $originalSection = SectionTable::getById($id); if ( $originalSection !== false && is_array($originalSection) && $originalSection['EXTERNAL_TYPE'] !== self::EXTERNAL_TYPE_LOCAL ) { $sectionFields['EXTERNAL_TYPE'] = $originalSection['EXTERNAL_TYPE']; } unset($sectionFields['ID']); $strUpdate = $DB->PrepareUpdate("b_calendar_section", $sectionFields); $strSql = "UPDATE b_calendar_section SET ". $strUpdate . " WHERE ID = " . $id; $DB->QueryBind($strSql, array('DESCRIPTION' => $sectionFields['DESCRIPTION'] ?? null)); } //SaveAccess if ($id > 0 && isset($sectionFields['ACCESS']) && is_array($sectionFields['ACCESS'])) { $sectionModel = SectionModel::createFromId($id) ->setType($sectionFields['CAL_TYPE']) ->setOwnerId((int)($sectionFields['OWNER_ID'] ?? null)) ; if ((new SectionAccessController($userId))->check(ActionDictionary::ACTION_SECTION_ACCESS, $sectionModel)) { if (empty($sectionFields['ACCESS'])) { self::SavePermissions( $id, self::GetDefaultAccess($sectionFields['CAL_TYPE'], $sectionFields['OWNER_ID'] ?? null) ); } else { self::SavePermissions($id, $sectionFields['ACCESS']); } } elseif($isNewSection) { self::SavePermissions( $id, self::GetDefaultAccess($sectionFields['CAL_TYPE'], $sectionFields['OWNER_ID']) ); } } if ($isNewSection && $id > 0 && !isset($sectionFields['ACCESS'])) { self::SavePermissions( $id, self::GetDefaultAccess($sectionFields['CAL_TYPE'], $sectionFields['OWNER_ID']) ); } if ($isNewSection && $id && !isset($sectionFields['XML_ID'])) { $xmlId = md5($sectionFields['CAL_TYPE'] . '_' . $id . '_' . Random::getString(8)); SectionTable::update($id, [ 'XML_ID' => $xmlId ]); } CCalendar::ClearCache(['section_list', 'event_list']); if ($id > 0 && isset(self::$Permissions[$id])) { unset(self::$Permissions[$id]); self::$arOp = []; } if ($isNewSection) { self::onCreateSync($id, [ 'params' => $params, 'sectionFields' => $sectionFields, 'userId' => $userId, ]); } else { self::onUpdateSync($id, [ 'params' => $params, 'sectionFields' => $sectionFields, 'userId' => $userId, ]); } if ($isNewSection) { foreach(EventManager::getInstance()->findEventHandlers("calendar", "OnAfterCalendarSectionAdd") as $event) { ExecuteModuleEventEx($event, [$id, $sectionFields]); } } else { foreach(EventManager::getInstance()->findEventHandlers("calendar", "OnAfterCalendarSectionUpdate") as $event) { ExecuteModuleEventEx($event, array($id, $sectionFields)); } } $pullUserId = (int) ($sectionFields['CREATED_BY'] ?? $userId); Util::addPullEvent( 'edit_section', $pullUserId, [ 'fields' => $sectionFields, 'newSection' => $isNewSection, ] ); return $id; } public static function Delete($id, $checkPermissions = true, $params = []) { global $DB; $id = (int)$id; $sectionFields = self::GetById($id); $canEdit = $sectionFields['PERM']['edit'] ?? false; if ($checkPermissions !== false && !$canEdit) { return CCalendar::ThrowError('EC_ACCESS_DENIED'); } $meetingIds = []; if (Util::isSectionStructureConverted()) { $strSql = "select CE.ID, CE.PARENT_ID, CE.CREATED_BY from b_calendar_event CE where CE.SECTION_ID=".$id." and (CE.IS_MEETING='1' and CE.IS_MEETING is not null) and (CE.DELETED='N' and CE.DELETED is not null)"; } else { // Here we don't use GetList to speed up delete process // mantis: 82918 $strSql = "SELECT CE.ID, CE.PARENT_ID, CE.DELETED, CE.CREATED_BY, CES.SECT_ID, CES.EVENT_ID FROM b_calendar_event CE LEFT JOIN b_calendar_event_sect CES ON (CE.ID=CES.EVENT_ID) WHERE CES.SECT_ID=".$id." AND (CE.IS_MEETING='1' and CE.IS_MEETING is not null) AND (CE.DELETED='N' and CE.DELETED is not null)"; } $res = $DB->Query($strSql , false, "File: ".__FILE__."
Line: ".__LINE__); while($ev = $res->Fetch()) { if ((int)$ev['ID'] === (int)$ev['PARENT_ID']) { $meetingIds[] = (int)$ev['PARENT_ID']; CCalendarLiveFeed::OnDeleteCalendarEventEntry($ev['PARENT_ID']); } $pullUserId = (int)$ev['CREATED_BY'] > 0 ? (int)$ev['CREATED_BY'] : CCalendar::GetCurUserId(); if ($pullUserId) { Bitrix\Calendar\Util::addPullEvent( 'delete_event', $pullUserId, [ 'fields' => $ev, ] ); } } if (count($meetingIds) > 0) { $DB->Query("DELETE from b_calendar_event WHERE PARENT_ID in (".implode(',', $meetingIds).")", false, "File: ".__FILE__."
Line: ".__LINE__); } //delete section in services self::onDeleteSync($id, [ 'originalFrom' => $params['originalFrom'] ?? '', ]); // Del link from table if (!Util::isSectionStructureConverted()) { $DB->Query("DELETE FROM b_calendar_event_sect WHERE SECT_ID=".$id, false, "FILE: ".__FILE__."
LINE: ".__LINE__); } // Del from $DB->Query("DELETE FROM b_calendar_section WHERE ID=".$id, false, "FILE: ".__FILE__."
LINE: ".__LINE__); CCalendarEvent::DeleteEmpty(); self::CleanAccessTable(); CCalendar::ClearCache(array('section_list', 'event_list')); foreach(EventManager::getInstance()->findEventHandlers("calendar", "OnAfterCalendarSectionDelete") as $event) { ExecuteModuleEventEx($event, array($id)); } $pullUserId = (int)$sectionFields['CREATED_BY'] > 0 ? (int)$sectionFields['CREATED_BY'] : CCalendar::GetCurUserId(); if ($pullUserId) { Util::addPullEvent( 'delete_section', $pullUserId, [ 'fields' => $sectionFields, ] ); } return true; } public static function CreateDefault($params = []) { if ($params['type'] === 'user' || $params['type'] === 'group') { $name = CCalendar::GetOwnerName($params['type'], $params['ownerId']); } else { $name = $params['type'] === 'location' ? Loc::getMessage('EC_DEF_SECT_LOCATION_CAL') : Loc::getMessage('EC_DEF_SECT_GROUP_CAL'); } $userId = $params['type'] === 'user' ? $params['ownerId'] : CCalendar::GetCurUserId(); if ($userId > 0) { $arFields = [ 'CAL_TYPE' => $params['type'], 'NAME' => $name, 'DESCRIPTION' => Loc::getMessage('EC_DEF_SECT_DESC'), 'COLOR' => CCalendar::Color(), 'OWNER_ID' => $params['ownerId'], 'IS_EXCHANGE' => 0, 'ACCESS' => CCalendarSect::GetDefaultAccess($params['type'], $params['ownerId']), 'PERM' => [ 'view_time' => true, 'view_title' => true, 'view_full' => true, 'add' => true, 'edit' => true, 'edit_section' => true, 'access' => true, ], 'EXTERNAL_TYPE' => self::EXTERNAL_TYPE_LOCAL, ]; if($params['type'] === 'location') { $arFields['NECESSITY'] = 'N'; $arFields['CAPACITY'] = 0; $builder = new \Bitrix\Calendar\Core\Builders\Rooms\RoomBuilderFromArray($arFields); $room = $builder->build(); Rooms\Manager::createInstanceWithRoom($room) ->createRoom() ->saveAccess() ->clearCache() ->eventHandler('OnAfterCalendarRoomCreate') ->addPullEvent('create_room') ; $arFields['ID'] = $room->getId(); } else { $arFields['ID'] = self::Edit([ 'arFields' => $arFields, 'userId' => $userId, ]); } if ($arFields['ID'] > 0) { return $arFields; } } return false; } public static function SavePermissions($sectId, $taskPerm) { global $DB; $DB->Query("DELETE FROM b_calendar_access WHERE SECT_ID='".(int)$sectId."'", false, "FILE: ".__FILE__."
LINE: ".__LINE__); if (is_array($taskPerm)) { foreach($taskPerm as $accessCode => $taskId) { if (preg_match('/^SG/', $accessCode)) { $accessCode = self::prepareGroupCode($accessCode); } $insert = $DB->PrepareInsert( "b_calendar_access", [ "ACCESS_CODE" => $accessCode, "TASK_ID" => (int)$taskId, "SECT_ID" => (int)$sectId, ] ); $strSql = "INSERT INTO b_calendar_access(".$insert[0].") VALUES(".$insert[1].")"; $DB->Query($strSql , false, "File: ".__FILE__."
Line: ".__LINE__); } } } private static function prepareGroupCode($code) { $parsedCode = explode('_', $code); if (count($parsedCode) === 1) { $code .= '_K'; } return $code; } public static function GetArrayPermissions($arSections = []) { global $DB; $s = "'0'"; foreach($arSections as $id) { if ($id > 0) { $s .= ",'". (int)$id ."'"; } } $strSql = 'SELECT SC.ID, CAP.ACCESS_CODE, CAP.TASK_ID, SC.CAL_TYPE, SC.OWNER_ID, SC.CREATED_BY FROM b_calendar_section SC LEFT JOIN b_calendar_access CAP ON (SC.ID=CAP.SECT_ID) WHERE SC.ID in ('.$s.')'; $res = $DB->Query($strSql , false, "File: ".__FILE__."
Line: ".__LINE__); while($arRes = $res->Fetch()) { if ($arRes['ID'] > 0) { self::HandlePermission($arRes); } } return self::$Permissions; } public static function SetClearOperationCache($val = true) { self::$bClearOperationCache = $val; } public static function CanDo($operation, $sectId = 0, $userId = null) { $res = null; global $USER; if ((!$USER || !is_object($USER)) || $USER->CanDoOperation('edit_php')) { return true; } if (!is_numeric($userId)) { $userId = CCalendar::GetCurUserId(); } if ( CCalendar::IsBitrix24() && Loader::includeModule('bitrix24') && CBitrix24::isPortalAdmin($userId) ) { return true; } if ( CCalendar::IsSocNet() && CCalendar::IsSocnetAdmin() &&( CCalendar::GetType() === 'group' || CCalendar::GetType() === 'user' || CCalendar::IsBitrix24() ) ) { return true; } if ((int)$sectId && (int)$userId && !self::$bClearOperationCache) { $sectionPermKey = $userId . '|' . $sectId; if (isset(self::$userSectionPermissions[$sectionPermKey])) { $res = in_array($operation, self::$userSectionPermissions[$sectionPermKey], true); } } if ($res === null) { $res = in_array($operation, self::GetOperations($sectId, $userId), true); } self::$bClearOperationCache = false; return $res; } public static function GetOperations($sectId, $userId = null) { if (!$userId) { $userId = CCalendar::GetCurUserId(); } if ((int)$sectId && (int)$userId && !self::$bClearOperationCache) { $sectionPermKey = $userId . '|' . $sectId; if (isset(self::$userSectionPermissions[$sectionPermKey])) { return self::$userSectionPermissions[$sectionPermKey]; } } $codes = Util::getUserAccessCodes($userId); $key = $sectId.'|'.implode(',', $codes); if (self::$bClearOperationCache || !is_array(self::$arOp[$key] ?? null)) { if (!isset(self::$Permissions[$sectId])) { self::GetArrayPermissions([$sectId]); } $perms = self::$Permissions[$sectId]; self::$arOp[$key] = []; if (is_array($perms)) { foreach ($perms as $code => $taskId) { if (in_array($code, $codes, true)) { self::$arOp[$key] = array_merge(self::$arOp[$key], CTask::GetOperations($taskId, true)); } } } } if ((int)$sectId && (int)$userId) { $sectionPermKey = $userId . '|' . $sectId; self::$userSectionPermissions[$sectionPermKey] = self::$arOp[$key]; } self::$bClearOperationCache = false; return self::$arOp[$key]; } public static function GetCalDAVConnectionId($section = 0) { global $DB; $arIds = is_array($section) ? $section : array($section); $arIds = array_unique($arIds); $strIds = []; $result = []; foreach($arIds as $id) { if ((int)$id > 0) { $strIds[] = (int)$id; $result[(int)$id] = 0; } } $strIds = implode(',', $strIds); $strSql = "SELECT ID, CAL_DAV_CON FROM b_calendar_section WHERE ID in (".$strIds.")"; $res = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); while ($arRes = $res->Fetch()) { $result[$arRes['ID']] = ($arRes['CAL_DAV_CON'] > 0) ? (int)$arRes['CAL_DAV_CON'] : 0; } if (!is_array($section)) { return $result[$section]; } return $result; } public static function GetExportLink($sectionId, $type = '', $ownerId = null) { $userId = CCalendar::getCurUserId(); $ownerId = (int)$ownerId; $path = Util::getPathToCalendar($ownerId, $type); return '&type='.mb_strtolower($type) .'&owner='.$ownerId .'&ncc=1&user='.$userId .'&'.'sec_id='.(int)$sectionId .'&sign='.self::getSign($userId, $sectionId) .'&bx_hit_hash='.self::getAuthHash($userId, $path); } /** * @param int $sectionId * @param array $fields */ public static function CleanFieldsValueById(int $sectionId, array $fields): void { if (!$fields) { return; } global $DB; $dbFields = []; foreach ($fields as $field) { $dbFields[$field] = false; } $DB->Query("UPDATE b_calendar_section SET " . $DB->PrepareUpdate('b_calendar_section', $dbFields) . " WHERE ID = " . $sectionId); } /** * @param int $id * @param array $params * * @return Result|null * * @throws ArgumentException * @throws ObjectPropertyException * @throws SystemException */ private static function onCreateSync(int $id, array $params): ?Result { if (!Loader::includeModule('dav')) { return null; } $originalFrom = $params['params']['originalFrom'] ?? null; if ($originalFrom === ($params['sectionFields']['EXTERNAL_TYPE'] ?? null)) { return null; } if ($params['params']['arFields']['CAL_TYPE'] !== 'user') { return null; } /** @var \Bitrix\Calendar\Core\Section\Section $section */ $section = (new Bitrix\Calendar\Core\Mappers\Section())->getById($id); if (!$section) { return null; } $factories = FactoriesCollection::createByUserId($params['userId']); if ($factories->count() === 0) { return null; } $syncManager = new Synchronization($factories); $context = new Context([]); if (!empty($originalFrom)) { $context->add('sync', 'originalFrom', $originalFrom); } $result = $syncManager->createSection($section, $context); // TODO: temporary. Need to move into separated method if ($result->isSuccess()) { /** @var FactoryInterface $factory */ foreach ($factories as $factory) { if ($factory->canSubscribeSection()) { $outgoingManager = new \Bitrix\Calendar\Sync\Managers\OutgoingManager($factory->getConnection()); /** @var Result $vendorResult */ if ( ($vendorResult = $result->getData()[$factory->getCode()]) && $sectionConnection = $vendorResult->getData()['sectionConnection'] ) { $outgoingManager->subscribeSection($sectionConnection); } } } } return $result; } private static function onUpdateSync(int $id, array $params) { if (!Loader::includeModule('dav')) { return null; } if (($params['params']['arFields']['CAL_TYPE'] ?? null) !== 'user') { return null; } if (empty($params['params']['arFields']['NAME'])) { return new Result(); } /** @var \Bitrix\Calendar\Core\Section\Section $section */ $section = (new Bitrix\Calendar\Core\Mappers\Section())->getById($id); if (!$section) { return null; } $factories = FactoriesCollection::createBySection($section); if ($factories->count() === 0) { return null; } $syncManager = new Synchronization($factories); $context = new Context([]); if (!empty($params['params']['originalFrom'])) { $context->add('sync', 'originalFrom', $params['params']['originalFrom']); } return $syncManager->updateSection($section, $context); } private static function onDeleteSync(int $id, array $params) { if (!Loader::includeModule('dav')) { return null; } $section = new Bitrix\Calendar\Core\Section\Section(); $section->setId($id); $factories = FactoriesCollection::createBySection($section); if ($factories->count() === 0) { self::cleanLinkTables($id); return null; } $syncManager = new Synchronization($factories); $context = new Context([]); if (!empty($params['originalFrom'])) { $context->add('sync', 'originalFrom', $params['originalFrom']); } return $syncManager->deleteSection($section, $context); } public static function cleanLinkTables($sectId) { global $DB; $DB->Query("DELETE FROM b_calendar_event_connection WHERE EVENT_ID IN (SELECT EV.ID FROM b_calendar_event EV WHERE EV.SECTION_ID = " . (int)$sectId . ");" ); $DB->Query("DELETE FROM b_calendar_section_connection WHERE SECTION_ID = " . (int)$sectId . ";" ); } function GetSPExportLink() { $userId = CCalendar::GetCurUserId(); return '&user_id='.$userId.'&sign='.self::GetSign($userId, 'superposed_calendars'); } public static function GetOutlookLink($Params) { if (Bitrix\Main\Loader::includeModule('intranet')) { return CIntranetUtils::GetStsSyncURL($Params); } return null; } private static function GetUniqCalendarId() { $uniq = COption::GetOptionString("calendar", "~export_uniq_id", ""); if($uniq == '') { $uniq = md5(uniqid(rand(), true)); COption::SetOptionString("calendar", "~export_uniq_id", $uniq); } return $uniq; } public static function GetSign($userId, $sectId) { return md5($userId."||".$sectId."||".self::GetUniqCalendarId()); } public static function CheckSign($sign, $userId, $sectId) { return (md5($userId."||".$sectId."||".self::GetUniqCalendarId()) == $sign); } // * * * * EXPORT TO ICAL * * * * public static function ReturnICal($Params) { $sectId = $Params['sectId']; $userId = (int)$Params['userId']; $sign = $Params['sign']; $type = mb_strtolower($Params['type']); $ownerId = (int)$Params['ownerId']; $bCache = false; $GLOBALS['APPLICATION']->RestartBuffer(); if (!self::CheckSign($sign, $userId, $sectId)) { return CCalendar::ThrowError(Loc::getMessage('EC_ACCESS_DENIED')); } $arSections = self::GetList( array( 'arFilter' => array('ID' => $sectId), 'checkPermissions' => false, )); if ($arSections && $arSections[0] && $arSections[0]['EXPORT'] && $arSections[0]['EXPORT']['ALLOW']) { $arSection = $arSections[0]; $arEvents = CCalendarEvent::GetList( array( 'arFilter' => array( 'SECTION' => $arSection['ID'], ), 'getUserfields' => false, 'parseRecursion' => false, 'fetchAttendees' => false, 'fetchMeetings' => true, 'userId' => $userId, ) ); $iCalEvents = self::FormatICal($arSection, $arEvents); } else { return CCalendar::ThrowError(Loc::getMessage('EC_ACCESS_DENIED')); } self::ShowICalHeaders(); echo $iCalEvents; exit(); } private static function ShowICalHeaders() { header("Content-Type: text/calendar; charset=UTF-8"); header("Accept-Ranges: bytes"); header("Connection: Keep-Alive"); header("Keep-Alive: timeout=15, max=100"); } private static function FormatICal($section, $events) { global $APPLICATION; $res = 'BEGIN:VCALENDAR'."\n". 'PRODID:-//Bitrix//Bitrix Calendar//EN'."\n". 'VERSION:2.0'."\n". 'CALSCALE:GREGORIAN'."\n". 'METHOD:PUBLISH'."\n". 'X-WR-CALNAME:'.self::_ICalPaste($section['NAME'])."\n". 'X-WR-CALDESC:'.self::_ICalPaste($section['DESCRIPTION'])."\n"; $localTime = new DateTime(); $localOffset = $localTime->getOffset(); foreach ($events as $event) { $fromTs = CCalendar::Timestamp($event['DATE_FROM']); $toTs = CCalendar::Timestamp($event['DATE_TO']); if ($event['DT_SKIP_TIME'] === "Y") { $dtStart = date("Ymd", $fromTs); $dtEnd = date("Ymd", $toTs + CCalendar::GetDayLen()); } else { $fromTsUTC = $fromTs - $event['TZ_OFFSET_FROM']; $toTsUTC = $toTs - $event['TZ_OFFSET_TO']; $dtStart = date("Ymd\THis\Z", $fromTsUTC); $dtEnd = date("Ymd\THis\Z", $toTsUTC); } $dtStamp = str_replace('T000000Z', '', date("Ymd\THisZ", CCalendar::Timestamp($event['TIMESTAMP_X']) - $localOffset)); $uid = md5(uniqid(rand(), true).$event['ID']).'@bitrix'; $period = ''; $rrule = CCalendarEvent::ParseRRULE($event['RRULE']); if($rrule && isset($rrule['FREQ']) && $rrule['FREQ'] != 'NONE') { $period = 'RRULE:FREQ='.$rrule['FREQ'].';'; $period .= 'INTERVAL='.$rrule['INTERVAL'].';'; if ($rrule['FREQ'] == 'WEEKLY') { $period .= 'BYDAY='.implode(',', $rrule['BYDAY']).';'; } if (isset($rrule['COUNT']) && intval($rrule['COUNT']) > 0) { $period .= 'COUNT='.intval($rrule['COUNT']).';'; } else { $until = date("Ymd", $event['DATE_TO_TS_UTC']); if($until != '20380101') $period .= 'UNTIL='.$until.';'; } $period .= 'WKST=MO'; $period .= "\n"; } $res .= 'BEGIN:VEVENT'."\n"; if ($event['DT_SKIP_TIME'] === "Y") { $res .= 'DTSTART;VALUE=DATE:'.$dtStart."\n". 'DTEND;VALUE=DATE:'.$dtEnd."\n"; } else { $res .= 'DTSTART;VALUE=DATE-TIME:'.$dtStart."\n". 'DTEND;VALUE=DATE-TIME:'.$dtEnd."\n"; } $res .= 'DTSTAMP:'.$dtStamp."\n". 'UID:'.$uid."\n". 'SUMMARY:'.self::_ICalPaste($event['NAME'])."\n". 'DESCRIPTION:'.self::_ICalPaste($event['DESCRIPTION'])."\n".$period."\n". 'LOCATION:'.self::_ICalPaste(CCalendar::GetTextLocation($event['LOCATION']))."\n". 'SEQUENCE:0'."\n". 'STATUS:CONFIRMED'."\n". 'TRANSP:TRANSPARENT'."\n". 'END:VEVENT'."\n"; } $res .= 'END:VCALENDAR'; if (!defined('BX_UTF') || BX_UTF !== true) $res = $APPLICATION->ConvertCharset($res, LANG_CHARSET, 'UTF-8'); return $res; } private static function _ICalPaste($str) { $str = preg_replace ("/\r/i", '', $str); $str = preg_replace ("/\n/i", '\\n', $str); return $str; } public static function GetModificationLabel($calendarId) // GetCalendarModificationLabel { global $DB; // We didn't have cashing for task list, // so just change modification label every 3 minutes if ($calendarId[0] === CCalendar::TASK_SECTION_ID) { return CCalendar::Date(round(time() / 180) * 180); } $sectionId = intval($calendarId[0]); if ($sectionId > 0) { $strSql = " SELECT ".$DB->DateToCharFunction("CS.TIMESTAMP_X")." as TIMESTAMP_X FROM b_calendar_section CS WHERE ID=".$sectionId; $res = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); if($sect = $res->Fetch()) return $sect['TIMESTAMP_X']; } return ""; } public static function UpdateModificationLabel($arId = []) { global $DB; if (!is_array($arId) && $arId) $arId = array($arId); $arId = array_unique($arId); $strIds = []; foreach($arId as $id) { if (intval($id) > 0) { $strIds[] = intval($id); } } $strIds = implode(',', $strIds); if ($strIds) { $strSql = "UPDATE b_calendar_section SET ". $DB->PrepareUpdate("b_calendar_section", array('TIMESTAMP_X' => FormatDate(CCalendar::DFormat(true), time()))). " WHERE ID in (".$strIds.")"; $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); } } public static function GetDefaultAccess($type, $ownerId) { if (CCalendar::IsIntranetEnabled()) { $access = array('G2' => CCalendar::GetAccessTasksByName('calendar_section', 'calendar_view_time')); } else { $access = array('G2' => CCalendar::GetAccessTasksByName('calendar_section', 'calendar_view')); } if ($type === 'group' && $ownerId > 0) { $access['SG'.$ownerId.'_A'] = CCalendar::GetAccessTasksByName('calendar_section', 'calendar_access'); $access['SG'.$ownerId.'_E'] = CCalendar::GetAccessTasksByName('calendar_section', 'calendar_edit'); $access['SG'.$ownerId.'_K'] = CCalendar::GetAccessTasksByName('calendar_section', 'calendar_edit'); } else if ($type !== 'user') { $access['G2'] = CCalendar::GetAccessTasksByName('calendar_section', 'calendar_edit'); } // Creator of the section if ($type !== 'user') { $access['U'.CCalendar::GetUserId()] = CCalendar::GetAccessTasksByName('calendar_section', 'calendar_access'); } $arAccessCodes = []; foreach($access as $code => $o) { $arAccessCodes[] = $code; } CCalendar::PushAccessNames($arAccessCodes); return $access; } public static function getAuthHash(int $userId, string $path) { global $USER; if ((!isset(self::$authHashiCal) || empty(self::$authHashiCal)) && $USER && is_object($USER)) { self::$authHashiCal = $USER->GetHitAuthHash($path, $userId); if (empty(self::$authHashiCal)) { self::$authHashiCal = $USER->AddHitAuthHash($path, $userId); } } return self::$authHashiCal; } public static function CheckAuthHash() { global $USER; if ($_REQUEST['bx_hit_hash'] <> '') { return $USER->LoginHitByHash($_REQUEST['bx_hit_hash']); } return false; } public static function GetLastUsedSection($type, $ownerId, $userId) { $userSettings = UserSettings::get($userId); return $userSettings['lastUsedSection']; } public static function GetSectionForOwner($type, $ownerId, $autoCreate = true) { $sectionId = false; $autoCreated = false; $section = false; $res = self::GetList([ 'arFilter' => [ 'CAL_TYPE' => $type, 'OWNER_ID' => $ownerId, 'DELETED' => 'N', 'ACTIVE' => 'Y', ], 'checkPermissions' => false, ]); foreach($res as $sect) { $ownerId = $sect['OWNER_ID']; if (self::CheckGoogleVirtualSection($sect['GAPI_CALENDAR_ID'])) { continue; } $section = $sect; $sectionId = $sect['ID']; break; } if (!$section && $autoCreate) { $section = self::CreateDefault([ 'type' => $type, 'ownerId' => $ownerId, ]); $autoCreated = true; $sectionId = $section['ID']; } return array('sectionId' => $sectionId, 'autoCreated' => $autoCreated, 'section' => $section); } public static function HandlePermission($section = []) { if ($section && $section['ID']) { $sectionId = $section['ID']; if (!isset(self::$Permissions[$sectionId]) || !is_array(self::$Permissions[$sectionId])) { self::$Permissions[$sectionId] = []; } if (isset($section['ACCESS_CODE']) && $section['ACCESS_CODE'] != '' && $section['ACCESS_CODE'] != '0' && $section['TASK_ID'] > 0) { self::$Permissions[$sectionId][$section['ACCESS_CODE']] = $section['TASK_ID']; } if ($section['CAL_TYPE'] === 'location' && ($section['ACCESS'] ?? null) != '' && ($section['ACCESS_CODE'] ?? null) != '0') { self::$Permissions[$sectionId] = $section['ACCESS']; } if ($section['CAL_TYPE'] !== 'group' && $section['OWNER_ID'] > 0) // Owner for user or other calendar types { self::$Permissions[$sectionId]['U'.$section['OWNER_ID']] = CCalendar::GetAccessTasksByName('calendar_section', 'calendar_access'); } if ($section['CAL_TYPE'] === 'group' && $section['OWNER_ID'] > 0) // Owner for group { self::$Permissions[$sectionId]['SG'.$section['OWNER_ID'].'_A'] = CCalendar::GetAccessTasksByName('calendar_section', 'calendar_access'); } } } public static function CleanAccessTable() { global $DB; $res = $DB->Query( "SELECT DISTINCT CA.SECT_ID from b_calendar_access CA LEFT JOIN b_calendar_section CS ON (CA.SECT_ID=CS.ID) WHERE concat('',CA.SECT_ID * 1)=CA.SECT_ID AND CS.ID is null", false, "File: ".__FILE__."
Line: ".__LINE__); $items = []; while($r = $res->Fetch()) { $items[] = "'". (int)$r['SECT_ID'] ."'"; } // Clean from 'b_calendar_event' if(count($items)) { $DB->Query("DELETE FROM b_calendar_access WHERE SECT_ID in (".implode(',', $items).")", false, "FILE: ".__FILE__."
LINE: ".__LINE__); } } /** * @param string|null $davXmlId * @param string|null $externalType * @return bool */ public static function CheckGoogleVirtualSection($davXmlId = '', $externalType = ''): bool { return $davXmlId !== '' && (preg_match('/@virtual\/events\//i', (string)$davXmlId) || preg_match('/@group\.v\.calendar\.google/i', (string)$davXmlId) || $externalType === Dictionary::ACCESS_ROLE_TO_EXTERNAL_TYPE['reader'] || $externalType === Dictionary::ACCESS_ROLE_TO_EXTERNAL_TYPE['freeBusyOrder'] ); } public static function GetCount() { global $DB; $count = 0; $res = $DB->Query('select count(*) as c from b_calendar_section', false, "File: ".__FILE__."
Line: ".__LINE__); if($res = $res->Fetch()) { $count = $res['c']; } return $count; } public static function GetSectionByEventId($id) { $resDb = EventTable::getList([ 'select' => ['SECTION_ID', 'OWNER_ID', 'CAL_TYPE'], 'filter' => ['ID' => $id], ]); return $resDb->fetch(); } public static function containsLocalSection($sections, $type): bool { if ($type !== 'user') { return true; } if ($sections && is_array($sections)) { foreach ($sections as $section) { if ( $section['EXTERNAL_TYPE'] === self::EXTERNAL_TYPE_LOCAL && $section['CAL_TYPE'] === 'user' && (int)$section['OWNER_ID'] === CCalendar::GetOwnerId() ) { return true; } } } return false; } /** * @param int $connectionId * @param array $type * * @return array * @throws ArgumentException * @throws CDavArgumentNullException * @throws ObjectPropertyException * @throws SystemException * @throws \Bitrix\Main\LoaderException */ public static function getAllSectionsForVendor(int $connectionId, array $type) { if (!Loader::includeModule('dav')) { return [ 'status' => 'error', 'message' => Loc::getMessage('EC_SYNCAJAX_DAV_REQUIRED'), ]; } /** @var Bitrix\Calendar\Core\Mappers\Factory $eventMapper */ $mapperFactory = \Bitrix\Main\DI\ServiceLocator::getInstance()->get('calendar.service.mappers.factory'); if ($connection = $mapperFactory->getConnection()->getById($connectionId)) { $userId = \CCalendar::GetUserId(); if ($connection->getOwner()->getId() !== $userId) { return []; } return SectionTable::query() ->setSelect(['*', 'CONNECTION_ID' => 'LINK.CONNECTION_ID']) ->where('CAL_TYPE', 'user') ->where('OWNER_ID', $userId) ->whereIn('EXTERNAL_TYPE', $type) ->where('CONNECTION_ID', $connectionId) ->registerRuntimeField( new \Bitrix\Main\Entity\ReferenceField( 'LINK', \Bitrix\Calendar\Internals\SectionConnectionTable::class, ['=this.ID' => 'ref.SECTION_ID'], ['join_type' => 'INNER'] ), )->exec()->fetchAll() ; } return []; } public static function prepareSectionListResponse(string $type, string $ownerId): array { $userId = CCalendar::GetCurUserId(); $followedSectionList = UserSettings::getFollowedSectionIdList($userId); $isNotInternalUser = Loader::includeModule('extranet') && !\CExtranet::IsIntranetUser(SITE_ID, $userId) ; if ($isNotInternalUser) { // Check permissions for group if ($type === 'group') { $perm = CCalendar::GetPermissions([ 'type' => $type, 'ownerId' => $ownerId, 'userId' => $userId, 'setProperties' => false ]); // For all members of the group it will be true so we want to skip everybody else if (!$perm['edit']) { return []; } } else // user's and company calendars are not available for external users { return []; } } $sectionList = CCalendar::getSectionList([ 'CAL_TYPE' => $type, 'OWNER_ID' => $ownerId, 'ACTIVE' => 'Y', 'ADDITIONAL_IDS' => $followedSectionList, 'checkPermissions' => true, 'getPermissions' => true, 'getImages' => true ]); $sectionList = array_merge($sectionList, CCalendar::getSectionListAvailableForUser($userId)); $sections = []; $sectionIdList = []; foreach ($sectionList as $section) { if (!in_array((int)$section['ID'], $sectionIdList)) { // if ($isNotInternalUser) if (in_array($section['ID'], $followedSectionList)) { $section['SUPERPOSED'] = true; } if (!empty($section['NAME'])) { $section['NAME'] = Emoji::decode($section['NAME']); } $sections[] = $section; $sectionIdList[] = (int) $section['ID']; } } return $sections; } } ?>