58 $this->connection = $connection;
60 'connection' => $connection,
62 $this->factory = FactoryBuilder::create($connection->getVendor()->getCode(), $connection, $context);
64 $this->mapperFactory = ServiceLocator::getInstance()->get(
'calendar.service.mappers.factory');
76 public function exportSections(array $params = []):
Result
78 $mainResult =
new Result();
89 $excludeIds = $params[
'excludeIds'] ?? [];
91 foreach ($this->fetchSections($excludeIds) as $section)
94 if ($sectionResult->isSuccess())
96 foreach ($sectionResult->getData() as $key => $link)
98 $resultData[
'links'][$key][] = $link;
100 $resultData[
'exported'][] = $section->getId();
104 $mainResult->addErrors($sectionResult->getErrors());
105 $resultData[
'exportErr'][] = $section->getId();
109 return $mainResult->setData($resultData);
136 $pushResult =
static function(array $result) use (&$resultData)
138 if (empty($result[
'entityType']) || empty($result[
'entity']))
142 if ($result[
'entityType'] ===
'link')
144 $resultData[
'events'][$result[
'action']] = $result[
'entity']->getEvent()->getId();
146 elseif ($result[
'entityType'] ===
'eventId')
148 $resultData[
'events'][$result[
'action']] = $result[
'entity'];
152 foreach ($this->fetchSectionEvents($sectionLink->getSection(), $excludeEventIds) as $eventPack)
154 $exportResult = $this->exportEvent($eventPack, $sectionLink);
155 if ($exportResult->isSuccess())
157 $pushResult($exportResult->getData());
163 if ($eventPack[
'event'])
165 $id = $eventPack[
'event']->getId();
167 else if ($eventPack[
'master'])
169 $id = $eventPack[
'master']->getId();
171 $resultData[
'events'][
'error'] = $id;
175 return $result->setData($resultData);
187 public function export():
Result
189 $mainResult =
new Result();
192 foreach ($this->fetchSections() as $section)
195 if (!$sectionResult->isSuccess())
201 $sectionLink = $sectionResult->getData()[
'sectionConnection'] ??
null;
205 foreach ($this->fetchSectionEvents($section) as $event)
207 $this->exportEvent($event, $sectionLink);
212 throw new ObjectPropertyException(
'Context object das not have sectionLink information');
216 return $mainResult->setData($resultData);
233 if ($link = $this->getSectionLink($section))
235 if ($link->isActive())
237 $result = $this->syncManager->updateSection($section, $sectionContext);
238 if ($result->isSuccess())
240 $result->setData(array_merge($result->getData(), [
241 'sectionConnection' => $link,
245 !$result->isSuccess()
246 && $result->getData()[
'error'] === 404
247 && $section->getExternalType() ===
'local'
250 $this->deleteSectionConnection($link);
251 $sectionContext->setSectionConnection(
null);
252 $result = $this->syncManager->createSection($section, $sectionContext);
262 $result = $this->syncManager->createSection($section, $sectionContext);
283 $mainResult =
new Result();
286 if ($link = $this->getSectionLink($section))
288 $sectionContext->setSectionConnection($link);
289 if ($link->isActive())
291 $result = $this->syncManager->updateSection($section, $sectionContext);
292 if ($result->isSuccess())
294 $resultData[
'updated'] = $link;
298 $resultData[
'error'] = $link;
303 $resultData[
'skipped'] = $link;
306 elseif ($section->getExternalType() !== Core\
Section\Section::LOCAL_EXTERNAL_TYPE)
308 $resultData[
'skipped'] = $section;
312 $result = $this->syncManager->createSection($section, $sectionContext);
313 if (!empty($result->getData()[
'sectionConnection']))
315 $resultData[
'exported'] = $result->getData()[
'sectionConnection'];
319 $result->addError(
new Error(
'Error of export section'));
320 $resultData[
'section'] = $section;
324 return $mainResult->setData($resultData);
336 private function fetchSections(array $exclude = []): Generator
338 $sectionList = SectionTable::getList([
340 '=CAL_TYPE' => $this->connection->getOwner()->getType(),
341 'OWNER_ID' => $this->connection->getOwner()->getId(),
342 'EXTERNAL_TYPE' => [
'local', $this->connection->getVendor()->getCode()],
349 while ($sectionDM = $sectionList->fetchObject())
351 $section = $mapper->getByEntityObject($sectionDM);
365 private function getSectionLink(\
Bitrix\Calendar\Core\Section\Section $section): ?SectionConnection
368 $map = $mapper->getMap([
369 '=SECTION_ID' => $section->getId(),
370 '=CONNECTION_ID' => $this->connection->getId(),
372 switch ($map->count())
377 return $map->fetch();
386 private function getFactory(): FactoryInterface
388 return $this->factory;
401 private function fetchSectionEvents(Core\Section\Section $section, array $excludeEventIds = []): Generator
404 $eventList = EventTable::getList([
411 '=SECTION_ID' => $section->getId(),
413 '!ID' => $excludeEventIds,
414 '>DATE_TO_TS_UTC' => $timestamp,
415 '!=MEETING_STATUS' =>
'N',
420 EventConnectionTable::class,
422 '=this.ID' =>
'ref.EVENT_ID',
423 'ref.CONNECTION_ID' => [
'?', $this->connection->getId()],
425 [
'join_type' =>
'LEFT']
428 ])->fetchCollection();
430 $eventList = $this->prepareEvents($eventList);
432 foreach ($eventList as $eventPack)
438 private function prepareEvents(EO_Event_Collection $events): array
442 foreach ($events as $event)
444 if ($event->getRrule())
446 $recId = $event->getParentId();
447 $result[$recId][
'type'] =
'recurrence';
448 $result[$recId][
'master'] = $event;
450 else if ($event->getRecurrenceId())
452 $result[$event->getRecurrenceId()][
'instances'][] = $event;
456 $result[$event->getId()] = [
472 private function getEventLink(EO_Event $eventEntity): ?EventConnection
475 if ($link = $eventEntity->get(
'LINK'))
477 $link->setEvent($eventEntity);
479 return $this->mapperFactory->getEventConnection()->getByEntityObject($link);
496 private function exportEvent(array $eventPack, SectionConnection $sectionLink): Result
498 if (!empty($eventPack[
'master']))
500 return $this->exportRecurrenceEvent($sectionLink, $eventPack);
503 if (!empty($eventPack[
'event']))
505 return $this->exportSimpleEvent($sectionLink, $eventPack[
'event']);
508 return (
new Result())->addError(
new Error(
'Unsupported eventpack format'));
525 $mainResult =
new Result();
526 if ($this->syncManager->canSubscribeSection())
529 $subscription = $pushManager->getPush(
533 if ($subscription && !$subscription->isExpired())
535 $result = $this->syncManager->renewPush($subscription);
536 if ($result->isSuccess())
538 $mainResult = $pushManager->renewPush($subscription, $result->getData());
542 $mainResult->addError(
new Error(
'Error of renew subscription.'));
543 $mainResult->addErrors($result->getErrors());
548 $subscribeResult = $this->syncManager->subscribeSection($link);
549 if ($subscribeResult->isSuccess())
553 $pushManager->renewPush($subscription, $subscribeResult->getData());
559 $pushManager->addPush(
560 'SECTION_CONNECTION',
562 $subscribeResult->getData()
568 $e->getCode() === 400
583 $mainResult->addError(
new Error(
'Error of add subscription.'));
584 $mainResult->addErrors($subscribeResult->getErrors());
600 $mainResult =
new Result();
601 if ($this->syncManager->canSubscribeConnection())
604 $subscription = $pushManager->getPush(
606 $this->connection->getId()
609 if ($subscription && !$subscription->isExpired())
611 $result = $this->syncManager->renewPush($subscription);
612 if ($result->isSuccess())
614 $mainResult = $pushManager->renewPush($subscription, $result->getData());
618 $mainResult->addError(
new Error(
'Error of renew subscription.'));
619 $mainResult->addErrors($result->getErrors());
624 $subscribeResult = $this->syncManager->subscribeConnection();
625 if ($subscribeResult->isSuccess())
627 if ($subscription !==
null)
629 $pushManager->renewPush($subscription, $subscribeResult->getData());
633 $pushManager->addPush(
635 $this->connection->getId(),
636 $subscribeResult->getData()
642 $mainResult->addError(
new Error(
'Error of add subscription.'));
643 $mainResult->addErrors($subscribeResult->getErrors());
661 if ($link->getConnection()->getId() && $link->getSection()->getId())
664 DELETE FROM b_calendar_event_connection
665 WHERE CONNECTION_ID = " . (
int)$link->getConnection()->getId() .
"
666 AND EVENT_ID IN (SELECT EV.ID FROM b_calendar_event EV
667 WHERE EV.SECTION_ID = " . (
int)$link->getSection()->getId() .
");"
673 SectionConnectionTable::delete($link->getId());
688 private function exportSimpleEvent(SectionConnection $sectionLink, EO_Event $eventData): Result
690 $result =
new Result();
691 $context =
new Context([]);
692 $context->add(
'sync',
'sectionLink', $sectionLink);
694 $event = $this->mapperFactory->getEvent()->getByEntityObject($eventData);
696 $eventLink = $this->getEventLink($eventData);
697 $eventContext = (
new EventContext())
699 ->setSectionConnection($sectionLink)
700 ->setEventConnection($eventLink)
703 if ($eventLink && !$eventLink->getVendorEventId())
705 $this->mapperFactory->getEventConnection()->delete($eventLink);
709 if ($event && $eventLink)
711 $resultUpdate = $this->syncManager->updateEvent($event, $eventContext);
713 'entityType' =>
'link',
714 'entity' => $eventLink,
715 'action' =>
'updated',
717 if (!$resultUpdate->isSuccess())
719 $result->addErrors($resultUpdate->getErrors());
724 $resultAdd = $this->syncManager->createEvent($event, $eventContext);
726 'entityType' =>
'link',
727 'action' =>
'exported',
729 if ($resultAdd->isSuccess())
731 if (!empty($resultAdd->getData()[
'eventConnectionId']))
733 $resultData[
'entity'] = $this->mapperFactory->getEventConnection()
734 ->getById($resultAdd->getData()[
'eventConnectionId'])
739 $resultData[
'entity'] = $this->mapperFactory->getEventConnection()->getMap([
740 '=EVENT_ID' => $event->getId(),
741 '=CONNECTION_ID' => $sectionLink->getConnection()->getId(),
748 'entityType' =>
'errorLink',
749 'action' =>
'exported',
751 $result->addErrors($resultAdd->getErrors());
755 return $result->setData($resultData);
765 private function exportRecurrenceEvent(SectionConnection $sectionLink, array $eventData): Result
767 $context =
new EventContext();
768 $context->setSectionConnection($sectionLink);
770 $recurrenceEvent = $this->buildRecurrenceEvent($eventData);
772 if ($recurrenceEvent->getEventConnection())
774 $context->setEventConnection($recurrenceEvent->getEventConnection());
775 $result = $this->syncManager->updateRecurrence($recurrenceEvent, $context);
779 $result = $this->syncManager->createRecurrence($recurrenceEvent, $context);
783 'entityType' =>
'link',
784 'action' =>
'updated',
787 return $result->setData($resultData);
796 private function buildRecurrenceEvent(array $eventData): SyncEvent
798 $masterEvent = $this->mapperFactory->getEvent()->getByEntityObject($eventData[
'master']);
799 $masterLink = $this->getEventLink($eventData[
'master']);
800 $masterSyncEvent = (
new SyncEvent())
801 ->setEvent($masterEvent)
802 ->setEventConnection($masterLink)
804 if ($masterSyncEvent->getEventConnection() && !$masterSyncEvent->getEventConnection()->getVendorEventId())
806 $this->mapperFactory->getEventConnection()->delete($masterSyncEvent->getEventConnection());
807 $masterSyncEvent->setEventConnection(
null);
810 $instancesCollection =
new InstanceMap();
811 $instances = $eventData[
'instances'] ?? [];
812 foreach ($instances as $instance)
814 $instanceEvent = $this->mapperFactory->getEvent()->getByEntityObject($instance);
815 $instanceLink = $this->getEventLink($instance);
816 $instanceSyncEvent = (
new SyncEvent())
817 ->setEvent($instanceEvent)
818 ->setEventConnection($instanceLink)
821 if ($instanceSyncEvent->getEventConnection() && !$instanceSyncEvent->getEventConnection()->getVendorEventId())
823 $this->mapperFactory->getEventConnection()->delete($instanceSyncEvent->getEventConnection());
824 $instanceSyncEvent->setEventConnection(
null);
826 $instancesCollection->add($instanceSyncEvent);
829 $masterSyncEvent->setInstanceMap($instancesCollection);
831 return $masterSyncEvent;