• Модуль: dav
  • Путь к файлу: ~/bitrix/modules/dav/classes/general/groupdavclientcalendar.php
  • Класс: CDavGroupdavClientCalendar
  • Вызов: CDavGroupdavClientCalendar::DataSync
static function DataSync($paramEntityType = null, $paramEntityId = 0)
{
	if (DAV_CALDAV_DEBUG)
	{
		CDav::WriteToLog("Starting CalDAV sync", "SYNCC");
	}

	self::InitUserEntity();

	$maxNumber = 5;
	$index = 0;
	$bShouldClearCache = false;

	$paramEntityId = (int)$paramEntityId;
	$arConnectionsFilter = ['ACCOUNT_TYPE' => [
		'caldav',
		BitrixCalendarSyncGoogleHelper::GOOGLE_ACCOUNT_TYPE_CALDAV
	]];
	if (!is_null($paramEntityType) && ($paramEntityId > 0))
	{
		$arConnectionsFilter["ENTITY_TYPE"] = $paramEntityType;
		$arConnectionsFilter["ENTITY_ID"] = $paramEntityId;
	}

	$syncInfo = [];
	$dbConnections = CDavConnection::GetList(
		["SYNCHRONIZED" => "ASC"],
		$arConnectionsFilter,
		false,
		false,
		[
			'ID',
			'ENTITY_TYPE',
			'ENTITY_ID',
			'ACCOUNT_TYPE',
			'SERVER_SCHEME',
			'SERVER_HOST',
			'SERVER_PORT',
			'SERVER_USERNAME',
			'SERVER_PASSWORD',
			'SERVER_PATH',
			'SYNCHRONIZED',
		]
	);
	while ($arConnection = $dbConnections->Fetch())
	{
		$index++;
		if ($index > $maxNumber)
		{
			break;
		}

		if (DAV_CALDAV_DEBUG)
		{
			CDav::WriteToLog("Connection [".$arConnection["ID"]."] ".$arConnection["ENTITY_TYPE"]."/".$arConnection["ENTITY_ID"], "SYNCC");
		}

		CDavConnection::SetLastResult($arConnection["ID"], "[0]");

		$client = new CDavGroupdavClientCalendar($arConnection["SERVER_SCHEME"], $arConnection["SERVER_HOST"], $arConnection["SERVER_PORT"], $arConnection["SERVER_USERNAME"], $arConnection["SERVER_PASSWORD"]);
		if (CDav::UseProxy())
		{
			$arProxy = CDav::GetProxySettings();
			$client->SetProxy($arProxy["PROXY_SCHEME"], $arProxy["PROXY_HOST"], $arProxy["PROXY_PORT"], $arProxy["PROXY_USERNAME"], $arProxy["PROXY_PASSWORD"]);
		}
		if ($arConnection['ACCOUNT_TYPE'] === BitrixCalendarSyncGoogleHelper::GOOGLE_ACCOUNT_TYPE_CALDAV)
		{
			$client->setGoogleCalendarOAuth($arConnection['ENTITY_ID']);
		}

		if (!$client->CheckWebdavServer($arConnection["SERVER_PATH"]))
		{
			$t = '';
			$arErrors = $client->GetErrors();
			foreach ($arErrors as $arError)
			{
				if ($t !== '')
				{
					$t .= ', ';
				}
				$t .= '['.$arError[0].'] '.$arError[1];
			}

			CDavConnection::SetLastResult($arConnection["ID"], (($t !== '') ? $t : "[404] Not Found"));
			$caldavHelper = ServiceLocator::getInstance()->get('calendar.service.caldav.helper');
			$connectionType = ($caldavHelper->isYandex($arConnection['SERVER_HOST'])
				? 'yandex' : 'caldav'
			);
			$connectionName = $connectionType.$arConnection['ID'];
			$connectionStatus = CCalendarSync::isConnectionSuccess($t);
			Util::addPullEvent('refresh_sync_status', $arConnection['ENTITY_ID'], [
				'syncInfo' => [
					$connectionName => [
						'syncTimestamp' => time() - CTimeZone::GetOffset((int)$arConnection['ENTITY_ID']),
						'status' => $connectionStatus,
						'type' => $connectionType,
						'connected' => true,
					],
				],
				'requestUid' => Util::getRequestUid(),
			]);

			if (DAV_CALDAV_DEBUG)
			{
				CDav::WriteToLog("ERROR: " . $t, "SYNCC");
			}

			continue;
		}

		$arCalendarsList = $client->GetCalendarList($arConnection["SERVER_PATH"]);

		if (!is_array($arCalendarsList) || empty($arCalendarsList))
		{
			CDavConnection::SetLastResult($arConnection["ID"], "[204] No Content");

			continue;
		}

		$arUserCalendars = [];
		foreach ($arCalendarsList as $value)
		{
			$arUserCalendars[] = [
				"XML_ID" => $value["href"] ?? null,
				"NAME" => $value["displayname"] ?? null,
				"DESCRIPTION" => $value["calendar-description"] ?? null,
				"COLOR" => $value["calendar-color"] ?? null,
				"MODIFICATION_LABEL" => $value["getctag"] ?? null,
			];
		}
		$tmpNumCals = count($arUserCalendars);
		$tmpNumItems = 0;

		$arUserCalendars = CCalendarSync::SyncCalendarSections(
			"caldav",
			$arUserCalendars,
			$arConnection["ENTITY_TYPE"],
			$arConnection["ENTITY_ID"],
			$arConnection["ID"]
		);

		foreach ($arUserCalendars as $userCalendar)
		{
			$arCalendarItemsList = $client->GetCalendarItemsList($userCalendar["XML_ID"]);

			if(!empty($arCalendarItemsList) && is_array($arCalendarItemsList))
			{
				$arUserCalendarItems = [];
				foreach ($arCalendarItemsList as $value)
				{
					if (
						isset($value["getetag"])
						&& mb_strpos(($value["getcontenttype"] ?? null), "text/calendar") !== false
					)
					{
						$xmlId = self::getBasenameWithoutExtension($value["href"]);
						$arUserCalendarItems[$xmlId] = $value["getetag"];
					}
				}

				$arModifiedUserCalendarItems = CCalendar::SyncCalendarItems(
					"caldav",
					$userCalendar["CALENDAR_ID"],
					$arUserCalendarItems
				);

				$arHrefs = [];
				$arIdMap = [];
				foreach ($arModifiedUserCalendarItems as $value)
				{
					$h = $client->GetRequestEventPath($userCalendar["XML_ID"], $value["XML_ID"]);
					$arHrefs[] = $h;
					$arIdMap[$h] = $value["ID"];
				}

				$arCalendarItemsList = $client->GetCalendarItemsList($userCalendar["XML_ID"], $arHrefs, true);
				if (is_array($arCalendarItemsList))
				{
					$tmpNumItems += count($arCalendarItemsList);

					foreach ($arCalendarItemsList as $value)
					{
						if (!array_key_exists($value["href"], $arIdMap))
						{
							continue;
						}

						$arModifyEventArray = [
							"ID" => $arIdMap[$value["href"]],
							"NAME" => $value["calendar-data"]["NAME"],
							"DETAIL_TEXT" => $value["calendar-data"]["DETAIL_TEXT"],
							"DETAIL_TEXT_TYPE" => $value["calendar-data"]["DETAIL_TEXT_TYPE"],
							"XML_ID" => self::getBasenameWithoutExtension($value["href"]),
							"PROPERTY_LOCATION" => $value["calendar-data"]["PROPERTY_LOCATION"],
							"DATE_FROM" => $value["calendar-data"]["DATE_FROM"],
							"DATE_TO" => $value["calendar-data"]["DATE_TO"],
							"TZ_FROM" => $value["calendar-data"]["TZ_FROM"],
							"TZ_TO" => $value["calendar-data"]["TZ_TO"],
							"DT_LENGTH" => $value["calendar-data"]["DT_LENGTH"] ?? null,
							"SKIP_TIME" => $value["calendar-data"]["SKIP_TIME"] ?? null,
							"PROPERTY_IMPORTANCE" => $value["calendar-data"]["PROPERTY_IMPORTANCE"] ?? null,
							"PROPERTY_ACCESSIBILITY" => $value["calendar-data"]["PROPERTY_ACCESSIBILITY"] ?? null,
							"PROPERTY_REMIND_SETTINGS" => $value["calendar-data"]["PROPERTY_REMIND_SETTINGS"] ?? null,
							"PROPERTY_PERIOD_TYPE" => "NONE",
							"PROPERTY_BXDAVCD_LABEL" => $value["getetag"] ?? null,
							"VERSION" => $value["calendar-data"]["VERSION"] ?? null,
							"ORGANIZER" => $value["calendar-data"]["ORGANIZER"] ?? null,
						];

						if (isset($value["calendar-data"]["PROPERTY_PERIOD_TYPE"]) && $value["calendar-data"]["PROPERTY_PERIOD_TYPE"] !== "NONE")
						{
							$arModifyEventArray["PROPERTY_PERIOD_TYPE"] = $value["calendar-data"]["PROPERTY_PERIOD_TYPE"] ?? null;
							$arModifyEventArray["PROPERTY_PERIOD_COUNT"] = $value["calendar-data"]["PROPERTY_PERIOD_COUNT"] ?? null;
							$arModifyEventArray["PROPERTY_PERIOD_ADDITIONAL"] = $value["calendar-data"]["PROPERTY_PERIOD_ADDITIONAL"] ?? null;
							$arModifyEventArray["PROPERTY_EVENT_LENGTH"] = $value["calendar-data"]["PROPERTY_EVENT_LENGTH"] ?? null;
							$arModifyEventArray["PROPERTY_PERIOD_UNTIL"] = $value["calendar-data"]["PROPERTY_PERIOD_UNTIL"] ?? null;
							$arModifyEventArray["EXDATE"] = $value["calendar-data"]["EXDATE"] ?? null;
							$arModifyEventArray["PROPERTY_RRULE_COUNT"] = $value["calendar-data"]["PROPERTY_RRULE_COUNT"] ?? null;
						}
						$k = CCalendarSync::ModifyEvent(
							$userCalendar["CALENDAR_ID"],
							$arModifyEventArray,
						);

						if (
							isset($value['calendar-data-ex'])
							&& is_array($value['calendar-data-ex'])
							&& !empty($value['calendar-data-ex'])
						)
						{
							CCalendarSync::ModifyReccurentInstances([
								'events' => $value['calendar-data-ex'],
								'parentId' => $k,
								'calendarId' => $userCalendar['CALENDAR_ID'],
							]);
						}
					}
				}
			}
		}

		if (DAV_CALDAV_DEBUG)
		{
			CDav::WriteToLog("Sync ".(int)$tmpNumCals." calendars, ".(int)$tmpNumItems." items", "SYNCC");
		}

		CDavConnection::SetLastResult($arConnection["ID"], "[200] OK");
		$caldavHelper = ServiceLocator::getInstance()->get('calendar.service.caldav.helper');
		$connectionType = ($caldavHelper->isYandex($arConnection['SERVER_HOST'])
			? 'yandex' : 'caldav'
		);
		$connectionName = $connectionType.$arConnection['ID'];
		Util::addPullEvent('refresh_sync_status', $arConnection['ENTITY_ID'], [
			'syncInfo' => [
				$connectionName => [
					'syncTimestamp' => time() - CTimeZone::GetOffset((int)$arConnection['ENTITY_ID']),
					'status' => true,
					'type' => $connectionType,
					'connected' => true,
				],
			],
			'requestUid' => Util::getRequestUid(),
		]);
	}

	if (DAV_CALDAV_DEBUG)
		CDav::WriteToLog("CalDAV sync finished", "SYNCC");

	return "CDavGroupdavClientCalendar::DataSync();";
}