Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
queuemanager.php
1<?php
2
4
10use CCalendar;
11use CTimeZone;
12
17{
18 public const PERMANENT_UPDATE_TIME = 5;
19 public const REGULAR_CHECK_TIME = 3600;
20 private const LIMIT_SECTIONS_FOR_CHECK = 5;
21
31 public static function checkNotSendEvents(int $lastHandledId = 0): ?string
32 {
33 return true;
34
35 if (!CCalendar::isGoogleApiEnabled())
36 {
37 return null;
38 }
39
40 $eventsDb = self::getEventsDb($lastHandledId);
41
42 if ($eventsDb === false)
43 {
44 return "\\Bitrix\\Calendar\\Sync\\Google\\QueueManager::checkNotSendEvents();";
45 }
46
47 $lastHandledId = 0;
48 while ($event = $eventsDb->Fetch())
49 {
50 $lastHandledId = $event['ID'];
51
52 if (GoogleApiPush::isAuthError($event['LAST_RESULT']))
53 {
54 continue;
55 }
56
57 $event = self::prepareEvent($event);
58
59 switch ($event['SYNC_STATUS'])
60 {
61 case Dictionary::SYNC_STATUS['create']:
62 self::createEvent($event);
63 break;
64 case Dictionary::SYNC_STATUS['update']:
65 self::updateEvent($event);
66 break;
67 case Dictionary::SYNC_STATUS['delete']:
68 self::deleteEvent($event);
69 break;
70 case Dictionary::SYNC_STATUS['instance']:
71 self::createInstance($event);
72 break;
73 case Dictionary::SYNC_STATUS['parent']:
74 self::updateParents($event);
75 break;
76 case Dictionary::SYNC_STATUS['next']:
77 self::updateNextEvents($event);
78 break;
79 case Dictionary::SYNC_STATUS['undefined']:
80 self::detectEventType($event);
81 break;
82 default:
83 self::detectEventType($event);
84 }
85 }
86
87 return "\\Bitrix\\Calendar\\Sync\\Google\\QueueManager::checkNotSendEvents(" . $lastHandledId . ");";
88 }
89
90 public static function checkIncompleteSync()
91 {
92 return true;
93 }
94
99 private static function createEvent(array $event): void
100 {
101 $google = new GoogleApiSync($event['OWNER_ID']);
102 $fields = $google->saveEvent($event, $event['GAPI_CALENDAR_ID']);
103
104 if ($fields !== null)
105 {
106 \CCalendarEvent::updateEventFields($event, [
107 'DAV_XML_ID' => $fields['DAV_XML_ID'],
108 'CAL_DAV_LABEL' => $fields['CAL_DAV_LABEL'],
109 'G_EVENT_ID' => $fields['G_EVENT_ID'],
110 'SYNC_STATUS' => Dictionary::SYNC_STATUS['success'],
111 ]);
112 }
113 }
114
119 private static function updateEvent(array $event): void
120 {
121 $google = new GoogleApiSync($event['OWNER_ID']);
122 $fields = $google->saveEvent($event, $event['GAPI_CALENDAR_ID'], []);
123
124 if ($errors = $google->getTransportErrors())
125 {
126 $googleHelper = ServiceLocator::getInstance()->get('calendar.service.google.helper');
127 if (is_array($errors))
128 {
129 foreach ($errors as $error)
130 {
131 if (
132 $googleHelper->isDeletedResource($error['message'])
133 || $googleHelper->isNotFoundError($error['message'])
134 )
135 {
136 \CCalendarEvent::updateEventFields($event, [
137 'G_EVENT_ID' => '',
138 'DAV_XML_ID' => '',
139 'CAL_DAV_LABEL' => '',
140 'SYNC_STATUS' => Dictionary::SYNC_STATUS['create'],
141 ]);
142 self::createEvent($event);
143 return;
144 }
145 }
146 }
147 }
148 else if ($fields !== null)
149 {
150 \CCalendarEvent::updateEventFields($event, [
151 'CAL_DAV_LABEL' => $fields['CAL_DAV_LABEL'],
152 'SYNC_STATUS' => Dictionary::SYNC_STATUS['success'],
153 ]);
154 }
155 }
156
161 private static function deleteEvent(array $event): void
162 {
163 $google = new GoogleApiSync($event['OWNER_ID']);
164 $google->deleteEvent($event['G_EVENT_ID'], $event['GAPI_CALENDAR_ID']);
165
166 if ($errors = $google->getTransportErrors())
167 {
168 $isUpdatedResult = false;
170 $googleHelper = ServiceLocator::getInstance()->get('calendar.service.google.helper');
171 if (is_array($errors))
172 {
173 foreach ($errors as $error)
174 {
175 if (
176 $googleHelper->isDeletedResource($error['message'])
177 || $googleHelper->isNotFoundError($error['message'])
178 )
179 {
180 $isUpdatedResult = true;
181 \CCalendarEvent::updateSyncStatus((int)$event['ID'], Dictionary::SYNC_STATUS['success']);
182 break;
183 }
184 }
185 }
186
187 if (!$isUpdatedResult)
188 {
189 \CCalendarEvent::updateSyncStatus((int)$event['ID'], Dictionary::SYNC_STATUS['delete']);
190 }
191 }
192 else
193 {
194 \CCalendarEvent::updateSyncStatus((int)$event['ID'], Dictionary::SYNC_STATUS['success']);
195 }
196 }
197
204 private static function createInstance(array $event): void
205 {
206 $parentEvent = Util::getEventById($event['PARENT_ID']);
207 $fields = (new GoogleApiSync($event['OWNER_ID']))->saveEvent($event, $event['GAPI_CALENDAR_ID'], [
208 'editInstance' => true,
209 'originalDavXmlId' => $parentEvent['DAV_XML_ID'],
210 'instanceTz' => $event['TZ_FROM'],
211 ]);
212
213 if ($fields !== null)
214 {
215 \CCalendarEvent::updateEventFields($event, [
216 'DAV_XML_ID' => $fields['DAV_XML_ID'],
217 'G_EVENT_ID' => $fields['G_EVENT_ID'],
218 'CAL_DAV_LABEL' => $fields['CAL_DAV_LABEL'],
219 'SYNC_STATUS' => Dictionary::SYNC_STATUS['success'],
220 ]);
221 }
222 }
223
228 private static function updateParents(array $event): void
229 {
230 $fields = (new GoogleApiSync($event['OWNER_ID']))->saveEvent($event, $event['GAPI_CALENDAR_ID'], [
231 'editParents' => true,
232 'editNextEvents' => false
233 ]);
234
235 if ($fields !== null)
236 {
237 \CCalendarEvent::updateEventFields($event, [
238 'DAV_XML_ID' => $fields['DAV_XML_ID'],
239 'CAL_DAV_LABEL' => $fields['CAL_DAV_LABEL'],
240 'G_EVENT_ID' => $fields['G_EVENT_ID'],
241 'SYNC_STATUS' => Dictionary::SYNC_STATUS['success'],
242 ]);
243 }
244 }
245
250 private static function updateNextEvents(array $event): void
251 {
252 $fields = (new GoogleApiSync($event['OWNER_ID']))->saveEvent($event, $event['GAPI_CALENDAR_ID'], [
253 'editNextEvents' => true,
254 ]);
255
256 if ($fields !== null)
257 {
258 \CCalendarEvent::updateEventFields($event, [
259 'DAV_XML_ID' => $fields['DAV_XML_ID'],
260 'CAL_DAV_LABEL' => $fields['CAL_DAV_LABEL'],
261 'G_EVENT_ID' => $fields['G_EVENT_ID'],
262 'SYNC_STATUS' => Dictionary::SYNC_STATUS['success'],
263 ]);
264 }
265 }
266
271 private static function prepareEvent(array $event): array
272 {
273 if (!empty($event['RRULE']))
274 {
275 $event['RRULE'] = \CCalendarEvent::ParseRRULE($event['RRULE']);
276 }
277
278 if (!empty($event['REMIND']) && is_string($event['REMIND']))
279 {
280 $event['REMIND'] = unserialize($event['REMIND'], ['allowed_classes' => false]);
281 }
282
283 return $event;
284 }
285
290 private static function getEventsDb(int $lastHandledId = 0)
291 {
292 global $DB;
293
294 return $DB->Query(
295 "SELECT e.*, c.LAST_RESULT, s.GAPI_CALENDAR_ID, "
296 . $DB->DateToCharFunction('e.DATE_FROM') . " as DATE_FROM, "
297 . $DB->DateToCharFunction('e.DATE_TO') . " as DATE_TO, "
298 . $DB->DateToCharFunction('e.ORIGINAL_DATE_FROM'). " as ORIGINAL_DATE_FROM, "
299 . $DB->DateToCharFunction('e.DATE_CREATE'). " as DATE_CREATE, "
300 . $DB->DateToCharFunction('e.TIMESTAMP_X'). " as TIMESTAMP_X"
301 . " FROM b_calendar_event e"
302 . " INNER JOIN b_calendar_section s ON e.SECTION_ID = s.ID"
303 . " INNER JOIN b_dav_connections c ON c.ID = s.CAL_DAV_CON"
304 . " WHERE e.SYNC_STATUS <> 'success'"
305 . " AND e.ID > ".$lastHandledId
306 . " AND s.EXTERNAL_TYPE IN ('local', 'google')"
307 . " ORDER BY e.ID ASC"
308 . " LIMIT 10"
309 . ";"
310 );
311 }
312
320 private static function detectEventType(array $event): void
321 {
322 if (
323 $event['SYNC_STATUS'] === Dictionary::SYNC_STATUS['exdated']
324 || $event['SYNC_STATUS'] === Dictionary::SYNC_STATUS['deleted']
325 )
326 {
327 return;
328 }
329
330 if (!empty($event['RECURRENCE_ID']))
331 {
332 self::createInstance($event);
333 return;
334 }
335
336 if ($event['DELETED'] === 'Y' && !empty($event['G_EVENT_ID']))
337 {
338 self::deleteEvent($event);
339 }
340 elseif (!empty($event['RRULE']) && empty($event['G_EVENT_ID']))
341 {
342 self::updateNextEvents($event);
343 }
344 elseif (!empty($event['RRULE']) && !empty($event['G_EVENT_ID']))
345 {
346 self::updateParents($event);
347 }
348 elseif (!empty($event['G_EVENT_ID']))
349 {
350 self::updateEvent($event);
351 }
352 else
353 {
354 self::createEvent($event);
355 }
356 }
357
364 public static function getNotIncompleteSections(): array
365 {
366 return SectionTable::query()
367 ->whereNotNull('PAGE_TOKEN')
368 ->setSelect(['*'])
369 ->setLimit(self::LIMIT_SECTIONS_FOR_CHECK)
370 ->exec()
371 ->fetchAll()
372 ;
373 }
374
381 public static function setIntervalForAgent(int $agentInterval = self::REGULAR_CHECK_TIME, int $delay = self::REGULAR_CHECK_TIME): void
382 {
383 $agent = \CAgent::getList(
384 [],
385 [
386 'MODULE_ID' => 'calendar',
387 '=NAME' => '\\Bitrix\\Calendar\\Sync\\Google\\QueueManager::checkIncompleteSync();'
388 ]
389 )->fetch();
390
391 if (is_array($agent) && $agent['ID'])
392 {
393 if ((int)$agent['AGENT_INTERVAL'] !== $agentInterval)
394 {
395 \CAgent::Update(
396 $agent['ID'],
397 [
398 'AGENT_INTERVAL' => $agentInterval,
399 'NEXT_EXEC' => ConvertTimeStamp(time() + CTimeZone::GetOffset() + $delay, "FULL"),
400 ]
401 );
402 }
403 }
404 else
405 {
406 \CAgent::AddAgent(
407 "\\Bitrix\\Calendar\\Sync\\Google\\QueueManager::checkIncompleteSync();",
408 "calendar",
409 "N",
410 $agentInterval
411 );
412 }
413 }
414}
static setIntervalForAgent(int $agentInterval=self::REGULAR_CHECK_TIME, int $delay=self::REGULAR_CHECK_TIME)
static checkNotSendEvents(int $lastHandledId=0)
static isAuthError(string $lastResult=null)
static getEventById(int $eventId)
Definition util.php:339