• Модуль: calendar
  • Путь к файлу: ~/bitrix/modules/calendar/classes/general/calendar.php
  • Класс: CCalendar
  • Вызов: CCalendar::Show
public function Show($params = [])
{
	global $APPLICATION;
	$arType = false;

	foreach(self::$arTypes as $type)
	{
		if(self::$type === $type['XML_ID'])
		{
			$arType = $type;
		}
	}

	if (!$arType)
	{
		$APPLICATION->ThrowException('[EC_WRONG_TYPE] '.Loc::getMessage('EC_WRONG_TYPE'), 'calendar_wrong_type');
		return false;
	}

	$typeModel = TypeModel::createFromXmlId(self::$type);
	if (!(new TypeAccessController(self::$userId))->check(ActionDictionary::ACTION_TYPE_VIEW,$typeModel, []))
	{
		$APPLICATION->ThrowException(Loc::getMessage("EC_ACCESS_DENIED"));
		return false;
	}

	$init_month = false;
	$init_year = false;
	$startupEvent = false;
	//Show new event dialog
	if (isset($_GET['EVENT_ID']))
	{
		if($this->doOpenEventInEditMode($_GET['EVENT_ID']))
		{
			$eventId = $this->getEditEventId($_GET['EVENT_ID']);
			$startupEvent = self::GetStartUpEvent($eventId);
			if ($startupEvent)
			{
				$startupEvent['EDIT'] = true;

				if ($startupEvent['DT_FROM'] ?? false)
				{
					$ts = self::Timestamp($startupEvent['DT_FROM']);
					$init_month = date('m', $ts);
					$init_year = date('Y', $ts);
				}
			}
		}
		// Show popup event at start
		else
		{
			$eventId = (int)$_GET['EVENT_ID'];
			$isSharing = (bool)($_GET['IS_SHARING'] ?? null) === true;
			$startupEvent = self::GetStartUpEvent($eventId, $isSharing);
			if ($startupEvent)
			{
				$eventFromTs = self::Timestamp($startupEvent['DATE_FROM']);
				$currentDateTs = self::Timestamp($_GET['EVENT_DATE'] ?? null);

				if ($currentDateTs > $eventFromTs)
				{
					$startupEvent['~CURRENT_DATE'] = self::Date($currentDateTs, false);
					$init_month = date('m', $currentDateTs);
					$init_year = date('Y', $currentDateTs);
				}
				else
				{
					$init_month = date('m', $eventFromTs);
					$init_year = date('Y', $eventFromTs);
				}
			}
		}
	}

	if (!$init_month && !$init_year && ($params["initDate"] ?? false) <> '' && mb_strpos($params["initDate"], '.') !== false)
	{
		$ts = self::Timestamp($params["initDate"]);
		$init_month = date('m', $ts);
		$init_year = date('Y', $ts);
	}

	if (!$init_month)
	{
		$init_month = date("m");
	}
	if (!$init_year)
	{
		$init_year = date("Y");
	}

	$id = $this->GetId();

	$weekHolidays = [];
	if (isset(self::$settings['week_holidays']))
	{
		$days = array('MO' => 0, 'TU' => 1, 'WE' => 2,'TH' => 3,'FR' => 4,'SA' => 5,'SU' => 6);
		foreach(self::$settings['week_holidays'] as $day)
		{
			$weekHolidays[] = $days[$day];
		}
	}
	else
	{
		$weekHolidays = array(5, 6);
	}

	$yearHolidays = [];
	if (isset(self::$settings['year_holidays']))
	{
		foreach(explode(',', self::$settings['year_holidays']) as $date)
		{
			$date = trim($date);
			$ardate = explode('.', $date);
			if (count($ardate) == 2 && $ardate[0] && $ardate[1])
			{
				$yearHolidays[] = (int)$ardate[0] . '.' . ((int)$ardate[1] - 1);
			}
		}
	}

	$yearWorkdays = [];
	if (isset(self::$settings['year_workdays']))
	{
		foreach(explode(',', self::$settings['year_workdays']) as $date)
		{
			$date = trim($date);
			$ardate = explode('.', $date);
			if (count($ardate) === 2 && $ardate[0] && $ardate[1])
			{
				$yearWorkdays[] = (int)$ardate[0] . '.' . ((int)$ardate[1] - 1);
			}
		}
	}

	$isPersonalCalendarContext = self::IsPersonal(self::$type, self::$ownerId, self::$userId);
	$bExchange = self::IsExchangeEnabled() && self::$type === 'user';
	$bExchangeConnected = $bExchange && CDavExchangeCalendar::IsExchangeEnabledForUser(self::$ownerId);
	$bWebservice = self::IsWebserviceEnabled();
	$bExtranet = self::IsExtranetEnabled();
	$isExtranetUser = Loader::includeModule('intranet') && !BitrixIntranetUtil::isIntranetUser();

	$userTimezoneOffsetUTC = self::GetCurrentOffsetUTC(self::$userId);
	$userTimezoneName = self::GetUserTimezoneName(self::$userId, false);
	$userTimezoneDefault = '';

	// We don't have default timezone for this offset for this user
	// We will ask him but we should suggest some suitable for his offset
	if (!$userTimezoneName)
	{
		$userTimezoneDefault = self::GetGoodTimezoneForOffset($userTimezoneOffsetUTC);
	}

	$JSConfig = Array(
		'id' => $id,
		'type' => self::$type,
		'userId' => self::$userId,
		'userName' => self::GetUserName(self::$userId), // deprecated
		'ownerId' => self::$ownerId,
		'ownerName' => self::GetOwnerName(self::$type, self::$ownerId),
		'user' => [
			'id' => self::$userId,
			'name' => self::GetUserName(self::$userId),
			'url' => self::GetUserUrl(self::$userId),
			'avatar' => self::GetUserAvatarSrc(self::$userId),
			'smallAvatar' => self::GetUserAvatarSrc(self::$userId, array('AVATAR_SIZE' => 18)),
		],
		'perm' => $arType['PERM'], // Permissions from type
		'locationAccess' => RoomsUtil::getLocationAccess(self::$userId),
		'permEx' => self::$perm,
		'showTasks' => self::$showTasks,
		'sectionControlsDOMId' => self::$SectionsControlsDOMId,
		'week_holidays' => $weekHolidays,
		'year_holidays' => $yearHolidays,
		'year_workdays' => $yearWorkdays,
		'init_month' => $init_month,
		'init_year' => $init_year,
		'pathToUser' => self::$pathToUser,
		'path' => self::$path,
		'actionUrl' => self::$actionUrl,
		'settings' => self::$settings,
		'userSettings' => self::$userSettings,
		'bAnonym' => self::$bAnonym,
		'bIntranet' => self::$bIntranet,
		'bWebservice' => $bWebservice,
		'bExtranet' => $bExtranet,
		'bSocNet' => self::$bSocNet,
		'bExchange' => $bExchangeConnected,
		'startupEvent' => $startupEvent,
		'workTime' => [self::$settings['work_time_start'], self::$settings['work_time_end']], // Decrecated !!
		'userWorkTime' => [self::$settings['work_time_start'], self::$settings['work_time_end']],
		'meetingRooms' => RoomsIBlockMeetingRoom::getMeetingRoomList([
			'RMiblockId' => self::$settings['rm_iblock_id'],
			'pathToMR' => self::$pathesForSite['path_to_rm'],
		]),
		'allowResMeeting' => self::$allowReserveMeeting,
		'bAMPM' => self::$bAMPM,
		'WDControllerCID' => 'UFWD' . $id,
		'userTimezoneOffsetUTC' => $userTimezoneOffsetUTC,
		'userTimezoneName' => $userTimezoneName,
		'userTimezoneDefault' => $userTimezoneDefault,
		'sectionCustomization' => UserSettings::getSectionCustomization(self::$userId),
		'locationFeatureEnabled' => Bitrix24Manager::isFeatureEnabled('calendar_location'),
		'plannerFeatureEnabled' => Bitrix24Manager::isPlannerFeatureEnabled(),
		'isSharingFeatureEnabled' => BitrixCalendarSharingSharingFeature::isEnabled(),
		'payAttentionToNewSharingFeature' => BitrixCalendarSharingHelper::payAttentionToNewSharingFeature(),
		'eventWithEmailGuestLimit'=> Bitrix24Manager::getEventWithEmailGuestLimit(),
		'countEventWithEmailGuestAmount'=> Bitrix24Manager::getCountEventWithEmailGuestAmount(),
		'showAfterSyncAccent' => isset($_GET['googleAuthSuccess']) && $_GET['googleAuthSuccess'] === 'y',
		'isExtranetUser' => $isExtranetUser,
		'sharingFeatureLimitEnable' => Bitrix24Manager::isFeatureEnabled('calendar_sharing'),
		'isGoogleApplicationRefused' => COption::GetOptionString('calendar', 'isGoogleApplicationRefused', 'N'),
		'showGoogleApplicationRefused' => CUserOptions::getOption('calendar', 'showGoogleApplicationRefused', 'Y'),
	);

	if (self::$type === 'user' && (int)self::$userId !== (int)self::$ownerId)
	{
		$JSConfig['ownerUser'] = array(
			'id' => self::$ownerId,
			'name' => self::GetUserName(self::$ownerId),
			'url' => self::GetUserUrl(self::$ownerId),
			'avatar' => self::GetUserAvatarSrc(self::$ownerId),
			'smallAvatar' => self::GetUserAvatarSrc(self::$ownerId, array('AVATAR_SIZE' => 18)),
		);
	}

	$JSConfig['dayOfWeekMonthFormat'] = stripslashes(
		BitrixMainContext::getCurrent()
			->getCulture()
			->getDayOfWeekMonthFormat()
	);

	$JSConfig['dayMonthFormat'] = stripslashes(
		BitrixMainContext::getCurrent()
			->getCulture()
			->getDayMonthFormat()
	);

	$JSConfig['longDateFormat'] = stripslashes(
		BitrixMainContext::getCurrent()
			->getCulture()
			->getLongDateFormat()
	);

	$placementParams = false;
	if (Loader::includeModule('rest'))
	{
		$placementParams = [
			'gridPlacementCode' => CCalendarRestService::PLACEMENT_GRID_VIEW,
			'gridPlacementList' => BitrixRestPlacementTable::getHandlersList(CCalendarRestService::PLACEMENT_GRID_VIEW),
			'serviceUrl' => '/bitrix/components/bitrix/app.layout/lazyload.ajax.php?&site='.SITE_ID.'&'.bitrix_sessid_get(),
		];
	}
	$JSConfig['placementParams'] = $placementParams;

	if (self::$type === 'user' && self::$userId === self::$ownerId)
	{
		$JSConfig['counters'] = CountersManager::getValues((int)self::$userId);
		$JSConfig['filterId'] = BitrixCalendarUiCalendarFilter::getFilterId(
			self::$type,
			self::$ownerId,
			self::$userId
		);
	}

	else if (
		self::$type === 'company_calendar'
		|| self::$type === 'calendar_company'
		|| self::$type === 'company'
		|| self::$type === 'group'
	)
	{
		$JSConfig['filterId'] = BitrixCalendarUiCalendarFilter::getFilterId(
			self::$type,
			self::$ownerId,
			self::$userId
		);
	}

	// Access permissions for type
	$typeModel = TypeModel::createFromXmlId(self::$type);
	$accessController = new TypeAccessController(self::$userId);
	if ($accessController->check(ActionDictionary::ACTION_TYPE_ACCESS, $typeModel, []))
	{
		$JSConfig['TYPE_ACCESS'] = $arType['ACCESS'];
	}
	
	if ($isPersonalCalendarContext)
	{
		$syncInfoParams = [
			'userId' => self::$userId,
			'type' => self::$type,
		];
		$JSConfig['syncInfo'] = CCalendarSync::GetSyncInfo($syncInfoParams);
		$JSConfig['syncLinks'] = CCalendarSync::GetSyncLinks($syncInfoParams);
		$JSConfig['caldav_link_all'] = self::GetServerPath();
		$JSConfig['isRuZone'] = BitrixCalendarUtil::checkRuZone();
		$JSConfig['isSetSyncGoogleSettings'] = self::IsCalDAVEnabled() && self::isGoogleApiEnabled();
		$JSConfig['isSetSyncOffice365Settings'] = self::IsCalDAVEnabled() && self::isOffice365ApiEnabled();
		$JSConfig['isIphoneConnected'] = self::isIphoneConnected();
		$JSConfig['isMacConnected'] = self::isMacConnected();
		$JSConfig['isIcloudConnected'] = ($JSConfig['syncInfo']['icloud'] ?? false)
			? $JSConfig['syncInfo']['icloud']['connected']
			: false
		;
		$JSConfig['isGoogleConnected'] = ($JSConfig['syncInfo']['google'] ?? false)
			? $JSConfig['syncInfo']['google']['connected']
			: false
		;
	}
	else
	{
		$JSConfig['caldav_link_all'] = self::GetServerPath();
		$JSConfig['isRuZone'] = BitrixCalendarUtil::checkRuZone();
		$JSConfig['syncInfo'] = false;
		$JSConfig['isIphoneConnected'] = false;
		$JSConfig['isMacConnected'] = false;
		$JSConfig['isIcloudConnected'] = false;
		$JSConfig['isGoogleConnected'] = false;
	}

	self::$userMeetingSection = self::GetCurUserMeetingSection();

	$followedSectionList = UserSettings::getFollowedSectionIdList(self::$userId);
	$defaultHiddenSections = [];
	$sections = [];
	$roomsList = RoomsManager::getRoomsList();

	$categoryList = RoomsCategoriesManager::getCategoryList();

	if(self::$type === 'location')
	{
		$sectionList = $roomsList ?? [];
	}
	else
	{
		$sectionList = self::getSectionList([
			'CAL_TYPE' => self::$type,
			'OWNER_ID' => self::$ownerId,
			'ACTIVE' => 'Y',
			'ADDITIONAL_IDS' => $followedSectionList,
			'checkPermissions' => true,
			'getPermissions' => true,
			'getImages' => true,
		]);
	}

	$sectionList = array_merge($sectionList, self::getSectionListAvailableForUser(self::$userId));
	$sectionIdList = [];
	foreach ($sectionList as $i => $section)
	{
		if (!in_array((int)$section['ID'], $sectionIdList))
		{
			$sections[] = $section;
			$sectionIdList[] = (int)$section['ID'];
		}

		if ($section['CAL_TYPE'] !== self::$type || self::$ownerId !== (int)$section['OWNER_ID'])
		{
			$defaultHiddenSections[] = (int)$section['ID'];
		}
	}

	$hiddenSections = UserSettings::getHiddenSections(
		self::$userId,
	 	[
	 		'type' => self::$type,
			'ownerId' => self::$ownerId,
			'isPersonalCalendarContext' => $isPersonalCalendarContext,
			'defaultHiddenSections' => $defaultHiddenSections,
		]
	);

	$readOnly = !self::$perm['edit'] && !self::$perm['section_edit'];

	if (self::$type === 'user' && self::$ownerId !== (int)self::$userId)
	{
		$readOnly = true;
	}

	if (self::$bAnonym)
	{
		$readOnly = true;
	}

	$bCreateDefault = !self::$bAnonym;

	if (self::$type === 'user')
	{
		$bCreateDefault = self::$ownerId === self::$userId;
	}

	$additionalMeetingsId = [];
	$groupOrUser = self::$type === 'user' || self::$type === 'group';
	if ($groupOrUser)
	{
		$noEditAccessedCalendars = true;
	}

	$trackingGroups = [];
	foreach ($sections as $i => $section)
	{
		$sections[$i]['~IS_MEETING_FOR_OWNER'] = $section['CAL_TYPE'] === 'user'
			&& $section['OWNER_ID'] !== self::$userId
			&& self::GetMeetingSection($section['OWNER_ID']) === $section['ID'];

		// It's superposed calendar of the other user and it's need to show user's meetings
		if (
			($section['ACTIVE'] ?? null) !== 'N'
			&& $sections[$i]['~IS_MEETING_FOR_OWNER']
			&& !in_array($section['ID'], $hiddenSections)
		)
		{
			$additionalMeetingsId[] = [
				'ID' => $section['OWNER_ID'],
				'SECTION_ID' => $section['ID'],
			];
		}

		$canEdit = $accessController->check(ActionDictionary::ACTION_TYPE_EDIT, $typeModel, []);
		// We check access only for main sections because we can't edit superposed section
		if (
			$groupOrUser
			&& $sections[$i]['CAL_TYPE'] === self::$type
			&& (int)$sections[$i]['OWNER_ID'] === (int)self::$ownerId
		)
		{
			if ($noEditAccessedCalendars && $section['PERM']['edit'])
			{
				$noEditAccessedCalendars = false;
			}

			if (
				$readOnly
				&& $canEdit
				&& ($section['PERM']['edit'] || $section['PERM']['edit_section'])
				&& !self::$isArchivedGroup
			)
			{
				$readOnly = false;
			}
		}

		if (in_array($section['ID'], $followedSectionList))
		{
			$sections[$i]['SUPERPOSED'] = true;
		}

		if (
			$bCreateDefault
			&& $section['CAL_TYPE'] === self::$type
			&& (int)$section['OWNER_ID'] === self::$ownerId
		)
		{
			$bCreateDefault = false;
		}

		$type = $sections[$i]['CAL_TYPE'];
		if ($type === 'user')
		{
			$path = CComponentEngine::MakePathFromTemplate(
				self::$pathesForSite['path_to_user_calendar'],
				["user_id" => $sections[$i]['OWNER_ID']]
			);
		}
		elseif($type === 'group')
		{
			$path = CComponentEngine::MakePathFromTemplate(
				self::$pathesForSite['path_to_group_calendar'],
				["group_id" => $sections[$i]['OWNER_ID']]
			);
			$trackingGroups[] = $sections[$i]['OWNER_ID'];
		}
		else
		{
			$path = self::$pathesForSite['path_to_type_'.$type];
		}
		$sections[$i]['LINK'] = $path;
	}

	if ($groupOrUser && $noEditAccessedCalendars && !$bCreateDefault)
	{
		$readOnly = true;
	}

	self::$readOnly = $readOnly;
	$JSConfig = array_merge(
		$JSConfig,
		[
			'trackingUsersList' => UserSettings::getTrackingUsers(self::$userId),
			'trackingGroupList' => UserSettings::getTrackingGroups(self::$userId, ['groupList' => $trackingGroups]),
		]
	);

	//  **** GET TASKS ****
	if (self::$showTasks)
	{
		$JSConfig['viewTaskPath'] = self::$viewTaskPath;
		$JSConfig['editTaskPath'] = self::$editTaskPath;
	}

	// We don't have any section
	if ($bCreateDefault)
	{
		$fullSectionsList = $groupOrUser
			? self::GetSectionList(['checkPermissions' => false, 'getPermissions' => false])
			: []
		;
		// Section exists but it closed to this user (Ref. mantis:#64037)
		if (
			!empty($fullSectionsList)
			&& self::GetOwnerId() !== self::GetUserId()
		)
		{
			$readOnly = true;
		}
		else
		{
			$defCalendar = CCalendarSect::CreateDefault([
				'type' => self::GetType(),
				'ownerId' => self::GetOwnerId(),
			]);
			$sections[] = $defCalendar;
			self::$userMeetingSection = $defCalendar['ID'];
		}
	}
	else if (!CCalendarSect::containsLocalSection($sectionList, self::$type))
	{
		$defCalendar = CCalendarSect::CreateDefault([
			'type' => self::GetType(),
			'ownerId' => self::GetOwnerId(),
		]);
		$sections[] = $defCalendar;
		self::$userMeetingSection = $defCalendar['ID'];
	}
	//check if we need to create default calendar for user when he opens location calendar
	if (self::$type === 'location')
	{
		$userSections = array_filter($sectionList, static function ($section) {
			return $section['CAL_TYPE'] === 'user' && (int)$section['OWNER_ID'] === self::$userId;
		});
		if (empty($userSections))
		{
			$defUserCalendar = CCalendarSect::CreateDefault([
				'type' => 'user',
				'ownerId' => self::$userId,
			]);
			if ($defUserCalendar)
			{
				$sections[] = $defUserCalendar;
				self::$userMeetingSection = $defUserCalendar['ID'];
			}
		}
	}
	$typeAccessController = new TypeAccessController(self::$userId);
	if ($typeAccessController->check(ActionDictionary::ACTION_TYPE_EDIT, TypeModel::createFromXmlId(self::$type)))
	{
		$JSConfig['new_section_access'] = CCalendarSect::GetDefaultAccess(self::$type, self::$ownerId);
	}

	$colors = ['#86B100','#0092CC','#00AFC7','#E89B06','#00B38C','#DE2B24','#BD7AC9','#838FA0','#C3612C','#E97090'];

	$JSConfig['hiddenSections'] = $hiddenSections;
	$JSConfig['readOnly'] = $readOnly;
	$JSConfig['hideSettingsHintLocation']  = CUserOptions::GetOption('calendar', 'hideSettingsHintLocation');
	// access
	$JSConfig['accessNames'] = self::GetAccessNames();
	$JSConfig['sectionAccessTasks'] = self::$type === 'location'
		? self::GetAccessTasks('calendar_section', 'location')
		: self::GetAccessTasks()
	;
	$JSConfig['typeAccessTasks'] = self::$type === 'location'
		? self::GetAccessTasks('calendar_type', 'location')
		: self::GetAccessTasks('calendar_type')
	;

	$JSConfig['bSuperpose'] = self::$bSuperpose;
	$JSConfig['additonalMeetingsId'] = $additionalMeetingsId;

	$JSConfig['sharing'] = ['url' => (new SharingSharing(self::$userId))->getActiveLinkShortUrl()];

	$userSettings = UserSettings::get(self::$ownerId);
	$meetSectionId = $userSettings['meetSection'];

	$meetSection = CCalendarSect::GetById($meetSectionId);
	$hasRightsForMeetSection = false;
	if (is_array($meetSection))
	{
		$sectionAccessController = new SectionAccessController(self::$userId);
		$sectionModel = SectionModel::createFromArray($meetSection);
		$action = ActionDictionary::ACTION_SECTION_EDIT;
		$hasRightsForMeetSection = $sectionAccessController->check($action, $sectionModel);
	}
	if ($meetSectionId && $hasRightsForMeetSection)
	{
		$JSConfig['meetSectionId'] = $meetSectionId;
	}

	$selectedUserCodes = array('U'.self::$userId);
	if (self::$type === 'user')
	{
		$selectedUserCodes[] = 'U'.self::$ownerId;
	}

	$additionalParams = array(
		'socnetDestination' => self::GetSocNetDestination(false, $selectedUserCodes),
		'locationList' => $roomsList,
		'timezoneList' => self::GetTimezoneList(),
		'defaultColorsList' => $colors,
		'formSettings' => array(
			'slider_main' => UserSettings::getFormSettings('slider_main'),
		),
	);

	// Append Javascript files and CSS files, and some base configs
	if (self::$type === 'location')
	{
		CCalendarSceleton::InitJS(
			$JSConfig,
			array(
				'sections' => $sections,
				'rooms' => $roomsList,
				'categories' => $categoryList,
			),
			$additionalParams
		);
	}
	else
	{
		CCalendarSceleton::InitJS(
			$JSConfig,
			array(
				'sections' => $sections,
			),
			$additionalParams
		);
	}
}