40 private const RENEW_LIMIT = 5;
41 private const FIX_LIMIT = 5;
42 private const RENEW_INTERVAL_CHANNEL = 14400;
43 private const PAUSE_INTERVAL_CHANNEL = 72000;
44 private const TYPE_LINK =
'SECTION_CONNECTION';
45 private const TYPE_CONNECTION =
'CONNECTION';
46 private const GOOGLE_CONNECTION =
'google_api_oauth';
47 private const OFFICE365_CONNECTION =
'office365';
48 private const RESULT_STATUS = [
53 private $mapperFactory;
57 private static array $outgoingManagersCache = [];
66 if (!Loader::includeModule(
'dav'))
71 $this->mapperFactory = ServiceLocator::getInstance()->get(
'calendar.service.mappers.factory');
87 if (!Loader::includeModule(
'dav') || !Loader::includeModule(
'calendar'))
92 $agentName = __METHOD__ .
'();';
97 $manager->doFixWatchSectionChannels();
98 $manager->doFixWatchConnectionChannels();
100 if (
$status === self::RESULT_STATUS[
'done'])
102 $nextAgentDate = DateTime::createFromTimestamp(
103 time() + self::PAUSE_INTERVAL_CHANNEL)->format(Date::convertFormatToPhp(
FORMAT_DATETIME)
106 CAgent::removeAgent($agentName,
"calendar");
107 CAgent::addAgent($agentName,
"calendar",
"N", self::RENEW_INTERVAL_CHANNEL,
"",
"Y", $nextAgentDate);
124 private function doRenewWatchChannels(): string
126 $pushChannels = PushTable::getList([
128 'ENTITY_TYPE' => [self::TYPE_LINK, self::TYPE_CONNECTION],
129 '<=EXPIRES' => (
new DateTime())->add(
'+1 day'),
134 'limit' => self::RENEW_LIMIT,
135 ])->fetchCollection();
137 foreach ($pushChannels as $pushChannelEO)
141 if ($pushChannel->getEntityType() === self::TYPE_LINK)
143 $this->renewSectionPush($pushChannel);
145 elseif ($pushChannel->getEntityType() === self::TYPE_CONNECTION)
147 $this->renewConnectionPush($pushChannel);
151 if ($pushChannels->count() < self::RENEW_LIMIT)
153 return self::RESULT_STATUS[
'done'];
156 return self::RESULT_STATUS[
'next'];
166 private function deleteChannel(Push $pushChannel): void
168 (
new PushManager())->deletePush($pushChannel);
178 private function savePushChannel(Push $pushChannel): void
180 (
new PushManager())->updatePush($pushChannel);
188 private function getFactoryByConnection(Connection
$connection): ?FactoryInterface
204 private function renewPushChannel(PushManagerInterface $vendorPushManager, Push $pushChannel): Result
208 $result = $vendorPushManager->renewPush($pushChannel);
212 $this->savePushChannel($pushChannel);
216 $result->addError(
new Error(
'Error of renew push channel.'));
219 catch(SyncException $e)
237 private function recreateSectionPushChannel(
238 PushManagerInterface $vendorPushManager,
240 SectionConnection $sectionLink
246 $vendorPushManager->deletePush($pushChannel);
247 $result = $vendorPushManager->addSectionPush($sectionLink);
252 ->setChannelId(
$data[
'CHANNEL_ID'])
253 ->setResourceId(
$data[
'RESOURCE_ID'])
254 ->setExpireDate(
new \Bitrix\Calendar\Core\Base\Date(
$data[
'EXPIRES']));
255 $this->savePushChannel($pushChannel);
259 $result->addError(
new Error(
'Error of create push channel.'));
262 catch(ApiException $e)
264 $result->addError(
new Error(
'ApiException during creation of push channel.'));
265 if ($e->getMessage() ===
'ExtensionError')
267 $this->deleteChannel($pushChannel);
282 private function isError405(Result
$result): bool
291 if ((
int)
$error->getCode() === 405)
303 private function getLinkFactory(): SectionConnectionFactory
305 if (empty($this->linkFactory))
307 $this->linkFactory =
new SectionConnectionFactory();
310 return $this->linkFactory;
324 private function renewSectionPush(Push $pushChannel): void
326 $sectionLink = $this->getLinkFactory()->getSectionConnection([
328 '=ID' => $pushChannel->getEntityId(),
332 $sectionLink !==
null
333 && $sectionLink->isActive()
334 && ($sectionLink->getConnection() !==
null)
335 && !$sectionLink->getConnection()->isDeleted()
336 && $sectionLink->getConnection()?->getOwner() !==
null
340 $vendorFactory = $this->getFactoryByConnection($sectionLink->getConnection());
342 if ($vendorPushManager = $vendorFactory->getPushManager())
344 $now =
new DateTime();
345 if ($pushChannel->getExpireDate()->getDate() > $now)
347 $result = $this->renewPushChannel($vendorPushManager, $pushChannel);
354 $result = $this->recreateSectionPushChannel($vendorPushManager, $pushChannel, $sectionLink);
367 $result = $this->recreateSectionPushChannel($vendorPushManager, $pushChannel, $sectionLink);
376 $this->deleteChannel($pushChannel);
390 private function renewConnectionPush(Push $pushChannel): void
393 $connection = $this->getConnectionMapper()->getById($pushChannel->getEntityId());
401 $vendorFactory = $this->getFactoryByConnection(
$connection);
403 if ($vendorPushManager = $vendorFactory->getPushManager())
405 $result = $this->recreateConnectionPushChannel($vendorPushManager, $pushChannel,
$connection);
413 $this->deleteChannel($pushChannel);
419 private function getConnectionMapper(): \Bitrix\
Calendar\Core\Mappers\Connection
421 return $this->mapperFactory->getConnection();
433 private function recreateConnectionPushChannel(
434 PushManagerInterface $vendorPushManager,
439 $vendorPushManager->deletePush($pushChannel);
445 ->setResourceId(
$data[
'RESOURCE_ID'])
446 ->setExpireDate(
new \Bitrix\Calendar\Core\Base\Date(
$data[
'EXPIRES']));
447 $this->savePushChannel($pushChannel);
451 $result->addError(
new Error(
'Error of create push channel.'));
464 private function doFixWatchSectionChannels(): void
466 $query = SectionConnectionTable::query()
473 'CONNECTION.IS_DELETED',
474 'CONNECTION.ACCOUNT_TYPE',
477 ->registerRuntimeField(
'PUSH',
480 PushTable::getEntity(),
482 '=this.ID' =>
'ref.ENTITY_ID',
483 'ref.ENTITY_TYPE' => [
'?', self::TYPE_LINK]
485 [
'join_type' => Join::TYPE_LEFT]
488 ->where(
'ACTIVE',
'Y')
489 ->where(
'LAST_SYNC_STATUS',
'success')
490 ->where(
'CONNECTION.IS_DELETED',
'N')
491 ->whereIn(
'CONNECTION.ACCOUNT_TYPE', [self::GOOGLE_CONNECTION, self::OFFICE365_CONNECTION])
492 ->whereNull(
'PUSH.ENTITY_TYPE')
493 ->setLimit(self::FIX_LIMIT)
497 while ($row =
$query->Fetch())
500 $connection = $this->mapperFactory->getConnection()->getById($row[
'CONNECTION_ID']);
503 SectionConnectionTable::delete($row[
'ID']);
510 $link = $this->mapperFactory->getSectionConnection()->getById($row[
'ID']);
521 $this->mapperFactory->getSectionConnection()->update($link);
532 private function doFixWatchConnectionChannels(): void
534 $query = DavConnectionTable::query()
542 ->registerRuntimeField(
'PUSH',
545 PushTable::getEntity(),
547 '=this.ID' =>
'ref.ENTITY_ID',
548 'ref.ENTITY_TYPE' => [
'?', self::TYPE_CONNECTION]
550 [
'join_type' => Join::TYPE_LEFT]
553 ->where(
'IS_DELETED',
'N')
554 ->where(
'ACCOUNT_TYPE', self::GOOGLE_CONNECTION)
555 ->whereIn(
'LAST_RESULT', [
'success',
'[200] OK'])
556 ->whereNull(
'PUSH.ENTITY_TYPE')
557 ->setLimit(self::FIX_LIMIT)
560 while ($row =
$query->fetch())
565 $connection = $this->mapperFactory->getConnection()->getById($row[
'ID']);
576 DavConnectionTable::update($row[
'ID'], [
577 'LAST_RESULT' =>
'['. $e->getCode() .
'] ERR'
589 private function getOutgoingManager(Connection
$connection): OutgoingManager
591 if (empty(static::$outgoingManagersCache[
$connection->getId()]))
596 return static::$outgoingManagersCache[
$connection->getId()];
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)