45 public function execute(array &$option): bool
47 if (!Loader::includeModule(self::$moduleId) || !Loader::includeModule(
'dav'))
51 if (Option::get(self::$moduleId, self::OPTION_CONVERTED,
'N') ===
'Y')
53 CCalendar::ClearCache();
58 $status = $this->loadCurrentStatus();
59 $events = $this->getGoogleEvents();
63 foreach ($events as $event)
65 $status[
'lastEventId'] = $event->getId();
67 $connection = $event->get(
'SECTION_CONNECTION');
68 if ($connection && $connectionId = $connection->getConnectionId())
70 $eventIds[] = $this->createEventConnection($event, $connectionId);
74 $eventIds[] = $event->getId();
80 $this->cleanExtraEventInfo($eventIds);
81 $status[
'steps'] += $events->count();
84 Option::set(self::$moduleId, self::OPTION_STATUS, serialize($status));
86 'count' => $status[
'count'],
87 'steps' => $status[
'steps'],
88 'lastEventId' => $status[
'lastEventId'],
96 Option::set(self::$moduleId, self::OPTION_CONVERTED,
'Y');
97 Option::delete(self::$moduleId, [
'name' => self::OPTION_STATUS]);
98 $this->unblockAllPushChannels();
99 CCalendar::ClearCache();
104 private function loadCurrentStatus(): array
106 $status = Option::get(self::$moduleId, self::OPTION_STATUS,
'default');
107 $status = $status !==
'default' ? @unserialize($status, [
'allowed_classes' =>
false]) : [];
108 $status = is_array($status) ? $status : [];
114 'count' => $this->getTotalCountEvents(),
125 private function getTotalCountEvents(): int
129 $result = $DB->Query(
"
130 SELECT COUNT(*) AS cnt
131 FROM b_calendar_event
132 WHERE G_EVENT_ID IS NOT NULL
135 if ($res = $result->Fetch())
137 $count = (int)$res[
'cnt'];
149 private function getGoogleEvents(): EO_Event_Collection
151 return EventTable::query()
154 'ORIGINAL_DATE_FROM',
161 'SECTION_CONNECTION.CONNECTION_ID',
163 ->whereNotNull(
'G_EVENT_ID')
164 ->where(
'DELETED',
'N')
165 ->setLimit(self::PORTION)
166 ->setOrder([
'ID' =>
'DESC'])
167 ->registerRuntimeField(
168 'SECTION_CONNECTION',
171 SectionConnectionTable::getEntity(),
172 Join::on(
'ref.SECTION_ID',
'this.SECTION_ID'),
173 [
'join_type' => Join::TYPE_LEFT]
176 ->exec()->fetchCollection()
185 private function cleanExtraEventInfo(array $eventIds): void
189 UPDATE b_calendar_event
190 SET G_EVENT_ID = null,
191 CAL_DAV_LABEL = null,
193 WHERE ID IN (" . implode(
',', $eventIds) .
");
204 private function createEventConnection(EO_Event $event,
int $connectionId): int
206 $recId = ($event->getOriginalDateFrom() && $event->getRecurrenceId())
207 ? $event->getDavXmlId()
210 EventConnectionTable::add([
211 'EVENT_ID' => $event->getId(),
212 'CONNECTION_ID' => $connectionId,
213 'VENDOR_EVENT_ID' => $event->getGEventId(),
214 'SYNC_STATUS' => self::STATUS_SUCCESS,
215 'ENTITY_TAG' => $event->getCalDavLabel(),
216 'VERSION' => $event->getVersion(),
217 'VENDOR_VERSION_ID' => $event->getVersion(),
218 'RECURRENCE_ID' => $recId,
221 return $event->getId();
227 private function unblockAllPushChannels(): void
231 UPDATE b_calendar_push
232 SET NOT_PROCESSED = 'N'
244 private function deDuplicate()
246 $this->deDuplicateEvents();
247 $this->deDuplicateSections();
257 private function deDuplicateEvents()
260 $sql =
"SELECT GROUP_CONCAT(link.ID) as ids
261 FROM b_calendar_event_connection link
262 GROUP BY link.CONNECTION_ID , link.EVENT_ID
265 $duplicateGroups = $DB->Query($sql);
266 while ($row = $duplicateGroups->Fetch())
268 $ids = explode(
',', $row[
'ids']);
269 $this->processEventDubles($ids);
280 private function deDuplicateSections()
283 $sql =
"SELECT GROUP_CONCAT(link.ID) as ids
284 FROM b_calendar_section_connection link
285 GROUP BY link.CONNECTION_ID , link.SECTION_ID
288 $duplicateGroups = $DB->Query($sql);
289 while ($row = $duplicateGroups->Fetch())
291 $ids = explode(
',', $row[
'ids']);
292 $this->processSectionDubles($ids);
305 private function processEventDubles(array $linkIds)
307 $this->processDubles(
309 new EventConnectionTable(),
323 private function processSectionDubles(array $linkIds)
325 $this->processDubles(
327 new SectionConnectionTable(),
344 private function processDubles(array $linkIds, DataManager $table,
string $validFieldName)
346 $validRow = $table->query()
348 ->addFilter(
"!$validFieldName",
false)
349 ->whereIn(
'ID', $linkIds)
352 if (!empty($validRow))
354 foreach ($linkIds as $index => $linkId)
356 if ($linkId == $validRow[
'ID'])
358 unset($linkIds[$index]);
364 foreach ($linkIds as $linkId)
366 $table->delete($linkId);