92 $isNew = (!isset($id) || !$id);
94 $ownerId = (int)
$request->getPost(
'ownerId');
97 $customization =
$request->getPost(
'customization') ===
'Y';
98 $userId = \CCalendar::GetUserId();
110 'OWNER_ID' => $ownerId,
111 'ACCESS' =>
$request->getPost(
'access'),
112 'EXTERNAL_TYPE' =>
$request->getPost(
'external_type') ??
'local',
115 if ($customization && !$isNew)
121 if (Loader::includeModule(
'intranet') && !\
Bitrix\Intranet\Util::isIntranetUser())
125 && Loader::includeModule(
'socialnetwork')
128 $rights = \Bitrix\Socialnetwork\UserToGroupTable::getList([
131 '=GROUP_ID' => $ownerId,
140 new Error(Loc::getMessage(
'EC_ACCESS_DENIED'),
'access_denied_extranet_group')
144 else if (
$type ===
'user')
149 new Error(Loc::getMessage(
'EC_ACCESS_DENIED'),
'access_denied_extranet_user')
156 new Error(Loc::getMessage(
'EC_ACCESS_DENIED'),
'access_denied_extranet')
171 SectionModel::createNew()
172 ->setType(
$type ??
'')
174 if (!
$accessController->check(ActionDictionary::ACTION_SECTION_ADD, $sectionModel))
177 new Error(Loc::getMessage(
'EC_ACCESS_DENIED'),
'access_denied')
181 if (
$type ===
'group' && Loader::includeModule(
'socialnetwork'))
183 $result = \Bitrix\Socialnetwork\UserToGroupTable::getList([
186 '=GROUP_ID' => $ownerId,
195 new Error(Loc::getMessage(
'EC_ACCESS_DENIED'),
'access_denied_user')
204 $section = \CCalendarSect::GetById($id);
205 $sectionModel = SectionModel::createFromArray($section);
209 || !
$accessController->check(ActionDictionary::ACTION_SECTION_EDIT, $sectionModel, [])
214 new Error(Loc::getMessage(
'EC_ACCESS_DENIED'),
'access_denied_04')
218 $fields[
'CAL_TYPE'] = $section[
'CAL_TYPE'];
219 $fields[
'OWNER_ID'] = $section[
'OWNER_ID'];
224 $id = \CCalendar::SaveSection([
'arFields' =>
$fields]);
227 \CCalendarSect::SetClearOperationCache(
true);
228 $response[
'section'] = \CCalendarSect::GetById($id,
true,
true);
232 new Error(Loc::getMessage(
'EC_CALENDAR_SAVE_ERROR'),
'saving_error_05')
235 $response[
'accessNames'] = \CCalendar::GetAccessNames();
237 $response[
'sectionList'] = \CCalendarSect::prepareSectionListResponse(
$type, $ownerId);
242 new Error(Loc::getMessage(
'EC_CALENDAR_SAVE_ERROR'),
'saving_error_06')
296 if (Loader::includeModule(
'intranet') && !\
Bitrix\Intranet\Util::isIntranetUser())
305 if ($mode ===
'users')
307 $userIds =
$request->get(
'userIdList');
309 'filter' => [
'=ID' => $userIds],
310 'select' => [
'ID',
'LOGIN',
'NAME',
'LAST_NAME',
'SECOND_NAME']
312 while (
$user = $ormRes->fetch())
314 $user[
'FORMATTED_NAME'] = \CCalendar::GetUserName(
$user);
318 $sections = \CCalendarSect::getSuperposedList([
'USERS' => $userIds]);
320 elseif ($mode ===
'groups' || $mode ===
'collabs')
323 $groupIds =
$request->get(
'groupIdList') ?? [];
325 if (Loader::includeModule(
'socialnetwork'))
327 if (!empty($groupIds))
329 $sections = \CCalendarSect::getSuperposedList([
'GROUPS' => $groupIds]);
332 foreach ($groupIds as $groupId)
334 $groupId = (int)$groupId;
335 $createDefaultGroupSection = \CSocNetFeatures::isActiveFeature(
341 if ($createDefaultGroupSection)
343 foreach ($sections as $section)
345 if ((
int)$section[
'OWNER_ID'] === $groupId)
347 $createDefaultGroupSection =
false;
353 if ($createDefaultGroupSection)
355 $sections[] = \CCalendarSect::createDefault([
357 'ownerId' => $groupId
366 $typesRes = \CCalendarType::GetList();
367 foreach ($typesRes as
$type)
370 $type[
'XML_ID'] !==
'user'
371 &&
$type[
'XML_ID'] !==
'group'
372 &&
$type[
'XML_ID'] !==
'location'
375 $types[] =
$type[
'XML_ID'];
379 $sections = \CCalendarSect::getSuperposedList([
'TYPES' => $types]);
384 'sections' => $sections
413 Loader::includeModule(
'intranet')
414 && !ToolsManager::getInstance()->checkAvailabilityByToolId(
'calendar')
420 'isAvailable' =>
false,
424 $responseParams = [];
425 $uniqueId =
'calendar_edit_slider_' . mt_rand();
426 $formType = preg_replace(
'/\W/',
'',
$request->get(
'form_type'));
427 $entryId = (int)
$request->get(
'event_id');
428 $userCodes =
$request->get(
'userCodes');
429 $userId = \CCalendar::GetCurUserId();
430 $ownerId = (int)
$request->get(
'ownerId');
436 $fromTs = !empty(
$_REQUEST[
'date_from_offset']) ? \CCalendar::Timestamp(
$_REQUEST[
'date_from'])
438 $entry = \CCalendarEvent::getEventForEditInterface($entryId, [
'eventDate' => \CCalendar::Date($fromTs)]);
439 $entryId = is_array($entry) && isset($entry[
'ID']) ? (int)$entry[
'ID'] : $entryId;
448 $responseParams[
'uniqueId'] = $uniqueId;
449 $responseParams[
'userId'] =
$userId;
450 $responseParams[
'editorId'] = $uniqueId .
'_entry_slider_editor';
451 $responseParams[
'entry'] = $entry;
453 $responseParams[
'timezoneList'] = \CCalendar::GetTimezoneList();
454 $responseParams[
'absenceAvailable'] = (!\CCalendar::IsBitrix24()
455 || \COption::GetOptionString(
"bitrix24",
"absence_limits_enabled",
"") !==
"Y"
456 || Feature::isFeatureEnabled(
"absence"))
459 $isOpenEvent =
$type === Dictionary::CALENDAR_TYPE[
'open_event'];
467 $sectionList = \CCalendar::getSectionList([
468 'CAL_TYPE' => Dictionary::CALENDAR_TYPE[
'open_event'],
471 else if ($isCollabUser)
473 $userCollabIds = UserCollabs::getInstance()->getIds(
$userId);
475 $type === Dictionary::CALENDAR_TYPE[
'group']
476 && !in_array($ownerId, $userCollabIds,
true)
484 $sectionList = \CCalendar::getSectionList([
485 'CAL_TYPE' => Dictionary::CALENDAR_TYPE[
'group'],
486 'OWNER_ID' => $userCollabIds,
488 'checkPermissions' =>
true,
489 'getPermissions' =>
true
494 $sectionList = \CCalendar::getSectionList([
496 'OWNER_ID' => $ownerId,
498 'checkPermissions' =>
true,
499 'getPermissions' =>
true
503 $hasCurrentCalendarInSections =
false;
504 foreach ($sectionList as $section)
506 if ($section[
'CAL_TYPE'] === Dictionary::CALENDAR_TYPE[
'open_event'])
508 $section[
'PERM'][
'edit'] =
true;
511 if ($section[
'PERM'][
'edit'] || $section[
'PERM'][
'add'])
513 $sections[] = $section;
516 $section[
'CAL_TYPE'] === Dictionary::CALENDAR_TYPE[
'group']
517 && (
int)$section[
'OWNER_ID'] === $ownerId
520 $hasCurrentCalendarInSections =
true;
526 $type === Dictionary::CALENDAR_TYPE[
'group']
527 && (empty($sections) || !$hasCurrentCalendarInSections)
530 $sections[] = \CCalendarSect::createDefault([
532 'ownerId' => $ownerId
535 \CCalendarSect::setClearOperationCache();
539 if (!$isOpenEvent && !$isCollabUser)
541 $sections = array_merge(
543 \CCalendar::getSectionListAvailableForUser(
$userId, (
array)($entry[
'SECTION_ID'] ??
null))
547 $responseParams[
'sections'] = [];
548 foreach ($sections as $section)
551 ($section[
'PERM'][
'edit'] ??
false)
552 && !\CCalendarSect::CheckGoogleVirtualSection(
553 $section[
'GAPI_CALENDAR_ID'] ??
null,
554 $section[
'EXTERNAL_TYPE'] ??
null,
558 $responseParams[
'sections'][] = $section;
562 $responseParams[
'dayOfWeekMonthFormat'] = (
563 \Bitrix\Main\Context::getCurrent()
565 ->getDayOfWeekMonthFormat()
570 $responseParams[
'userIndex'] = \CCalendarEvent::getUserIndex();
571 $locationFeatureEnabled = Bitrix24Manager::isFeatureEnabled(FeatureDictionary::CALENDAR_LOCATION);
574 $responseParams[
'locationFeatureEnabled'] = !$isCollabUser && $locationFeatureEnabled;
575 if ($locationFeatureEnabled || $isCollabUser)
578 $responseParams[
'locationAccess'] = Rooms\Util::getLocationAccess(
$userId);
580 $responseParams[
'plannerFeatureEnabled'] = Bitrix24Manager::isPlannerFeatureEnabled();
581 $responseParams[
'attendeesEntityList'] = ($entryId > 0 && !empty($entry[
'attendeesEntityList']))
582 ? $entry[
'attendeesEntityList']
584 $responseParams[
'meetSection'] =
null;
585 if (
$type === Dictionary::CALENDAR_TYPE[
'user'])
587 $responseParams[
'meetSection'] =
UserSettings::get($ownerId)[
'meetSection'] ??
null;
589 $responseParams[
'eventWithEmailGuestEnabled'] = Bitrix24Manager::isFeatureEnabled(FeatureDictionary::CALENDAR_EVENTS_WITH_EMAIL_GUESTS);
596 if (Loader::includeModule(
'socialnetwork'))
605 $responseParams[
'isCollabUser'] = $isCollabUser;
607 return new \Bitrix\Main\Engine\Response\Component(
608 'bitrix:calendar.edit.slider',
613 'formType' => $formType,
614 'type' => $isOpenEvent ? Dictionary::CALENDAR_TYPE[
'open_event'] : \CCalendar::GetType(),
615 'bIntranet' => \CCalendar::IsIntranetEnabled(),
616 'bSocNet' => \CCalendar::IsSocNet(),
618 'ATTENDEES_CODES' => $userCodes,
619 'hiddenFields' => $this->getEventEditFormHiddenFields($entry),
620 'sections' => $responseParams[
'sections'],
659 $responseParams = [];
660 $uniqueId =
'calendar_view_slider_' . mt_rand();
661 $entryId = (int)
$request->get(
'entryId');
662 $userId = \CCalendar::GetCurUserId();
667 $entry = \CCalendarEvent::getEventForViewInterface($entryId,
669 'eventDate' =>
$request->get(
'dateFrom'),
670 'timezoneOffset' => (
int)
$request->get(
'timezoneOffset'),
677 $this->
addError(
new Error(Loc::getMessage(
'EC_EVENT_NOT_FOUND'),
'EVENT_NOT_FOUND_01'));
682 $responseParams[
'uniqueId'] = $uniqueId;
683 $responseParams[
'userId'] =
$userId;
684 $responseParams[
'userTimezone'] = \CCalendar::GetUserTimezoneName(
$userId);
685 $responseParams[
'entry'] = $entry;
686 $responseParams[
'userIndex'] = \CCalendarEvent::getUserIndex();
688 $responseParams[
'plannerFeatureEnabled'] = Bitrix24Manager::isPlannerFeatureEnabled();
689 $responseParams[
'entryUrl'] = \CCalendar::getEntryUrl(
695 $responseParams[
'dayOfWeekMonthFormat'] = (
696 \Bitrix\Main\Context::getCurrent()
698 ->getDayOfWeekMonthFormat()
701 $sections = \CCalendarSect::GetList([
703 'ID' => $entry[
'SECTION_ID'],
706 'checkPermissions' =>
false,
707 'getPermissions' =>
true
710 $responseParams[
'section'] = isset($sections[0]) ? $sections[0] :
null;
712 return new \Bitrix\Main\Engine\Response\Component(
713 'bitrix:calendar.view.slider',
718 'type' => \CCalendar::GetType(),
719 'sectionName' =>
$_REQUEST[
'section_name'],
720 'bIntranet' => \CCalendar::IsIntranetEnabled(),
721 'bSocNet' => \CCalendar::IsSocNet(),
728 $this->
addError(
new Error(Loc::getMessage(
'EC_EVENT_NOT_FOUND'),
'EVENT_NOT_FOUND_02'));
759 $entryId = (int)
$request[
'entryId'];
760 $parentId = (int)(
$request[
'entry'][
'parentId'] ??
$request[
'parentId'] ?? 0);
761 $userId = \CCalendar::getCurUserId();
762 $ownerId = (int)
$request[
'ownerId'];
765 $isExtranetUser = Loader::includeModule(
'intranet') && !\Bitrix\Intranet\Util::isIntranetUser(
$userId);
768 if (!$hostId &&
$type ===
'user' && !$entryId)
775 $entries = \CExtranet::getMyGroupsUsersSimple(\CExtranet::GetExtranetSiteID());
778 if (!$entryId &&
$request[
'cur_event_id'])
780 $entryId = (int)
$request[
'cur_event_id'];
785 if (
$type !== Dictionary::CALENDAR_TYPE[
'open_event'])
796 if ($entryId > 0 && empty($codes))
798 $codes[] =
'U' . $hostId;
800 if (
$request[
'add_cur_user_to_list'] ===
'Y' || empty($codes))
806 $entryType =
$request[
'entry'][
'data'][
'CAL_TYPE'] ??
null;
807 if ($entryType === Dictionary::CALENDAR_TYPE[
'open_event'])
812 $prevUserList = is_array(
$request[
'prevUserList']) ?
$request[
'prevUserList'] : [];
813 $skipFeatureCheck = (
$request[
'skipFeatureCheck'] ??
null) ===
'Y';
818 return \CCalendarPlanner::prepareData([
819 'parent_id' => $parentId,
820 'entry_id' => $entryId,
822 'host_id' => $hostId,
824 'entryLocation' => trim(
$request[
'entryLocation'] ??
""),
825 'entries' => $entries,
826 'date_from' => $dateFrom,
827 'date_to' => $dateTo,
829 'location' => trim(
$request[
'location'] ??
""),
830 'roomEventId' => (
int)
$request[
'roomEventId'],
831 'initPullWatches' =>
true,
832 'prevUserList' => $prevUserList,
833 'skipFeatureCheck' => $skipFeatureCheck,
869 $event = \CCalendarEvent::GetById((
int)$entryId);
870 $untilTimestamp = \CCalendar::Timestamp($untilDate);
875 if (\CCalendarEvent::CheckRecurcion(
$event))
877 $event[
'RRULE'] = \CCalendarEvent::ParseRRULE(
$event[
'RRULE']);
878 $event[
'RRULE'][
'UNTIL'] = \CCalendar::Date($untilTimestamp,
false);
879 if (isset(
$event[
'RRULE'][
'COUNT']))
881 unset(
$event[
'RRULE'][
'COUNT']);
884 $id = \CCalendar::SaveEvent([
887 "RRULE" =>
$event[
'RRULE']
889 'silentErrorMode' =>
false,
890 'recursionEditMode' =>
'skip',
891 'editParentEvents' =>
true,
892 'editEntryUntil' =>
true,
898 if (
$event[
"RECURRENCE_ID"] > 0)
900 $recParentEvent = \CCalendarEvent::GetById(
$event[
"RECURRENCE_ID"]);
901 if ($recParentEvent && \CCalendarEvent::CheckRecurcion($recParentEvent))
903 $recParentEvent[
'RRULE'] = \CCalendarEvent::ParseRRULE($recParentEvent[
'RRULE']);
906 $recParentEvent[
'RRULE'][
'UNTIL']
907 && \CCalendar::Timestamp($recParentEvent[
'RRULE'][
'UNTIL']) > $untilTimestamp
910 $recParentEvent[
'RRULE'][
'UNTIL'] = \CCalendar::Date($untilTimestamp,
false);
912 if (isset($recParentEvent[
'RRULE'][
'COUNT']))
914 unset($recParentEvent[
'RRULE'][
'COUNT']);
917 $id = \CCalendar::SaveEvent([
919 "ID" => $recParentEvent[
"ID"],
920 "RRULE" => $recParentEvent[
'RRULE']
922 'silentErrorMode' =>
false,
923 'recursionEditMode' =>
'skip',
924 'editParentEvents' =>
true,
925 'editEntryUntil' =>
true,
931 $recId =
$event[
"RECURRENCE_ID"];
936 $recRelatedEvents = \CCalendarEvent::GetEventsByRecId($recId,
false);
937 foreach ($recRelatedEvents as $ev)
939 if (\CCalendar::Timestamp($ev[
'DATE_FROM']) > $untilTimestamp)
941 \CCalendar::DeleteEvent((
int)$ev[
'ID'],
true, [
'recursionMode' =>
'this']);
951 $this->
addError(
new Error(
'[ed01]' . Loc::getMessage(
'EC_EVENT_DEL_ERROR'),
952 'change_recurcive_entry_until'));
1092 $attestedSectionsStatus = [];
1094 $sectionsStatus =
$request[
'sectionStatus'];
1095 $userId = \CCalendar::getCurUserId();
1097 foreach ($sectionsStatus as $sectionId => $sectionStatus)
1099 $sectionStatus = json_decode($sectionStatus);
1100 if (is_int($sectionId) && is_bool($sectionStatus))
1102 $attestedSectionsStatus[$sectionId] = $sectionStatus;
1106 if ($attestedSectionsStatus &&
$userId > 0)
1153 $uid = preg_replace(
'/\W/',
'',
$uid);
1155 $userId = \CCalendar::getCurUserId();
1156 $additionalResponseParams = [
1161 $listLockedFeatures = [];
1163 if (\
Bitrix\
Main\Loader::includeModule(
'tasks'))
1165 $featureName = \Bitrix\Tasks\Integration\Bitrix24\FeatureDictionary::TASK_CALENDAR_INTEGRATION;
1166 $tasksCalendarIntegration = \Bitrix\Tasks\Integration\Bitrix24::checkFeatureEnabled($featureName);
1168 if ($tasksCalendarIntegration ===
false)
1170 $listLockedFeatures[
'sync_tasks'] = [
1172 'code' => $featureName,
1177 return new \Bitrix\Main\Engine\Response\Component(
1178 'bitrix:calendar.settings.slider',
1182 'is_personal' => $showPersonalSettings ===
'Y',
1183 'show_general_settings' => $showGeneralSettings ===
'Y',
1184 'show_access_control' => $showAccessControl ===
'Y',
1185 'list_locked_features' => $listLockedFeatures,
1187 $additionalResponseParams
1306 if ((Loader::includeModule(
'intranet') && !\
Bitrix\Intranet\Util::isIntranetUser()) && !$isCollaber)
1313 if ($isCollaber && !in_array(
$type, [
'user',
'group'],
true))
1315 $this->
addError(
new Error(
'Collaber only can access user or group'));
1320 if (
$type ===
'user')
1323 'ownerId' => \CCalendar::GetCurUserId(),
1324 'userId' => \CCalendar::GetCurUserId(),
1328 else if (in_array(
$type, [
'company_calendar',
'calendar_company',
'company',
'group'],
true))
1331 $typeModel = TypeModel::createFromXmlId(
$type);
1341 'ownerId' =>
$request->getPost(
'ownerId'),
1342 'userId' => \CCalendar::GetCurUserId(),
1353 return CalendarFilter::getFilterData(
$params);