1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
googleapipush.php
См. документацию.
1<?php
2
3namespace Bitrix\Calendar\Sync;
4
5use Bitrix\Calendar\Sync\Google\Dictionary;
6use Bitrix\Calendar\Sync\Google\QueueManager;
7use Bitrix\Main\Type;
8use Bitrix\Calendar\PushTable;
9use Bitrix\Main\Loader;
10use Bitrix\Calendar\Internals;
11
15final class GoogleApiPush
16{
17 private const RENEW_LIMIT = 5;
18 private const CREATE_LIMIT = 2;
19 private const CLEAR_LIMIT = 6;
20 private const CHECK_LIMIT = 10;
21 public const TYPE_SECTION = 'SECTION';
22 public const TYPE_CONNECTION = 'CONNECTION';
23
24
29 public static function renewWatchChannels()
30 {
31 $pushRows = [];
32 $connectionIds = [];
33 $sectionIds = [];
34
35 $pushesDb = PushTable::getList([
36 'filter' => [
37 '<=EXPIRES' => (new Type\DateTime())->add('+1 day'),
38 ],
39 'order' => [
40 'EXPIRES' => 'ASC',
41 ],
42 'limit' => self::RENEW_LIMIT,
43 ]);
44
45 while ($row = $pushesDb->fetch())
46 {
47 $pushRows[] = $row;
48 if ($row['ENTITY_TYPE'] === self::TYPE_CONNECTION)
49 {
50 $connectionIds[] = (int)$row['ENTITY_ID'];
51 }
52
53 if ($row['ENTITY_TYPE'] === self::TYPE_SECTION)
54 {
55 $sectionIds[] = (int)$row['ENTITY_ID'];
56 }
57 }
58
59 if (!empty($pushRows))
60 {
61 global $DB;
62 $sections = [];
63 $connections = [];
64
65 if (!empty($sectionIds))
66 {
67 $sectionResult = $DB->query("SELECT * FROM b_calendar_section WHERE ID IN (" . implode(',', $sectionIds) . ")");
68 while($row = $sectionResult->fetch())
69 {
70 $sections[$row['ID']] = $row;
71 if (!empty($row['CAL_DAV_CON']) && !in_array((int)$row['CAL_DAV_CON'], $connectionIds, true))
72 {
73 $connectionIds[] = (int)$row['CAL_DAV_CON'];
74 }
75 }
76 }
77
78 if (!empty($connectionIds))
79 {
80 $connectionResult = $DB->query("SELECT * FROM b_dav_connections WHERE ID IN (" . implode(',', $connectionIds) . ")");
81 while($row = $connectionResult->fetch())
82 {
83 $connections[$row['ID']] = $row;
84 }
85 }
86
87 foreach ($pushRows as $row)
88 {
89 $channelInfo = false;
90 if ($row['ENTITY_TYPE'] === self::TYPE_CONNECTION && !empty($connections[$row['ENTITY_ID']]))
91 {
92 $connectionData = $connections[$row['ENTITY_ID']];
93 if (is_string($connectionData['LAST_RESULT']) && self::isAuthError($connectionData['LAST_RESULT']))
94 {
95 continue;
96 }
97 $googleApiConnection = new GoogleApiSync($connectionData['ENTITY_ID'], $connectionData['ID']);
98 $googleApiConnection->stopChannel($row['CHANNEL_ID'], $row['RESOURCE_ID']);
100 $channelInfo = $googleApiConnection->startWatchCalendarList($connectionData['NAME']);
101 }
102 elseif ($row['ENTITY_TYPE'] === self::TYPE_SECTION && !empty($sections[$row['ENTITY_ID']]))
103 {
104 $section = $sections[$row['ENTITY_ID']];
105
106 if (
107 (!empty($connectionData)
108 && is_string($connectionData['LAST_RESULT'])
109 && self::isAuthError($connectionData['LAST_RESULT'])
110 )
111 || self::isVirtualCalendar($section['GAPI_CALENDAR_ID'], $section['EXTERNAL_TYPE'])
112 )
113 {
114 continue;
115 }
116
117 $connectionData = $connections[$section['CAL_DAV_CON']];
118 $googleApiConnection = new GoogleApiSync($section['OWNER_ID'], $section['CAL_DAV_CON']);
119 $googleApiConnection->stopChannel($row['CHANNEL_ID'], $row['RESOURCE_ID']);
121 $channelInfo = $googleApiConnection->startWatchEventsChannel($section['GAPI_CALENDAR_ID']);
122 }
123 else
124 {
126 }
127
128 if (
129 $channelInfo
130 && isset($channelInfo['id'], $channelInfo['resourceId'])
131 && isset($googleApiConnection)
132 )
133 {
134 $googleApiConnection->updateSuccessLastResultConnection();
135 PushTable::add([
136 'ENTITY_TYPE' => $row['ENTITY_TYPE'],
137 'ENTITY_ID' => $row['ENTITY_ID'],
138 'CHANNEL_ID' => $channelInfo['id'],
139 'RESOURCE_ID' => $channelInfo['resourceId'],
140 'EXPIRES' => $channelInfo['expiration'],
141 'NOT_PROCESSED' => 'N'
142 ]);
143 }
144 }
145 }
146
147 if (count($pushRows) < 4)
148 {
149 \CAgent::removeAgent("\\Bitrix\\Calendar\\Sync\\GoogleApiPush::renewWatchChannels();", "calendar");
150
151 return false;
152 }
153
154 return false;
155 }
156
157 public static function checkSectionsPush($localSections, $userId, $connectionId)
158 {
159 $googleApiConnection = new GoogleApiSync($userId, $connectionId);
160 //Create new channels and refresh old push channels for sections of current connection
161 $sectionIds = self::getNotVirtualSectionIds($localSections);
162
163 $pushChannels = PushTable::getList([
164 'filter' => [
165 '=ENTITY_TYPE' => self::TYPE_SECTION,
166 '=ENTITY_ID' => $sectionIds,
167 ]
168 ]);
169 $inactiveSections = array_flip($sectionIds);
170
171 while($row = $pushChannels->fetch())
172 {
173 $now = time();
174 $tsExpires = strtotime($row['EXPIRES']);
175
176 if ($now > $tsExpires)
177 {
179 continue;
180 }
181
182 if (($tsExpires - $now) > GoogleApiSync::ONE_DAY
183 || self::isAuthError(self::getLastResultBySectionId((int)$row['ENTITY_ID']))
184 )
185 {
186 unset($inactiveSections[$row['ENTITY_ID']]);
187 continue;
188 }
189
190 $googleApiConnection->stopChannel($row['CHANNEL_ID'], $row['RESOURCE_ID']);
192 unset($inactiveSections[$row['ENTITY_ID']]);
193
194 $localCalendarIndex = array_search($row['ENTITY_ID'], array_column($localSections, 'ID'));
195 if ($localCalendarIndex !== false)
196 {
197 $channelInfo = $googleApiConnection->startWatchCalendarList($localSections[$localCalendarIndex]['GAPI_CALENDAR_ID']);
198
199 if ($channelInfo)
200 {
201 PushTable::update(
202 [
203 'ENTITY_TYPE' => $row['ENTITY_TYPE'],
204 'ENTITY_ID' => $row['ENTITY_ID']
205 ],
206 [
207 'CHANNEL_ID' => $channelInfo['id'],
208 'RESOURCE_ID' => $channelInfo['resourceId'],
209 'EXPIRES' => $channelInfo['expiration'],
210 'NOT_PROCESSED' => 'N'
211 ]
212 );
213 }
214 }
215 }
216
217 if (is_array($localSections) && is_array($inactiveSections) && $googleApiConnection instanceof GoogleApiSync)
218 {
219 self::startChannelForInActiveSections($localSections, $inactiveSections, $googleApiConnection);
220 }
221
222 return false;
223 }
224
232 public static function createWatchChannels($start = 0)
233 {
234 $pushOptionEnabled = \COption::getOptionString('calendar', 'sync_by_push', false);
235 if (!$pushOptionEnabled && !\CCalendar::isBitrix24())
236 {
237 return null;
238 }
239
240 $lastId = $start;
241 if(!Loader::includeModule('dav'))
242 {
243 return false;
244 }
245
246 $davConnections = \CDavConnection::getList(
247 ["ID" => "ASC"],
248 [
249 'ACCOUNT_TYPE' => Google\Helper::GOOGLE_ACCOUNT_TYPE_API,
250 '>ID' => $start
251 ],
252 false,
253 ['nTopCount' => self::CREATE_LIMIT]
254 );
255
256 $connections = [];
257 $pushConnectionIds = [];
258 while($row = $davConnections->fetch())
259 {
260 //connectivity check
261 if (!self::isConnectionError($row['LAST_RESULT']))
262 {
263 $lastId = $row['ID'];
264 $connections[] = $row;
265 $pushConnectionIds[] = $row['ID'];
266 }
267 }
268
269 if(!empty($connections))
270 {
271 $result = PushTable::getList(
272 [
273 'filter' => [
274 '=ENTITY_TYPE' => self::TYPE_CONNECTION,
275 '=ENTITY_ID' => $pushConnectionIds,
276 ],
277 ]
278 );
279
280 $pushChannels = [];
281 while($row = $result->fetch())
282 {
283 $pushChannels[$row['ENTITY_ID']] = $row;
284 }
285
286 foreach($connections as $davConnection)
287 {
288 if(isset($pushChannels[$davConnection['ID']]))
289 {
290 continue;
291 }
292
293 $googleApiConnection = new GoogleApiSync($davConnection['ENTITY_ID'], $davConnection['ID']);
294 $channelInfo = $googleApiConnection->startWatchCalendarList($connections['NAME']);
295 if($channelInfo && isset($channelInfo['id'], $channelInfo['resourceId']))
296 {
297 self::deletePushChannel(["ENTITY_TYPE" => self::TYPE_CONNECTION, 'ENTITY_ID' => $davConnection['ID']]);
298 $googleApiConnection->updateSuccessLastResultConnection();
299 PushTable::add([
300 'ENTITY_TYPE' => self::TYPE_CONNECTION,
301 'ENTITY_ID' => $davConnection['ID'],
302 'CHANNEL_ID' => $channelInfo['id'],
303 'RESOURCE_ID' => $channelInfo['resourceId'],
304 'EXPIRES' => $channelInfo['expiration'],
305 'NOT_PROCESSED' => 'N'
306 ]);
307 }
308 }
309 }
310
311 if($lastId == $start)
312 {
313 \CAgent::removeAgent("\\Bitrix\\Calendar\\Sync\\GoogleApiPush::createWatchChannels(".$start.");", "calendar");
314 \CAgent::removeAgent("\\Bitrix\\Calendar\\Sync\\GoogleApiPush::createWatchChannels(0);", "calendar");
315 return null;
316 }
317
318 return false;
319 }
320
327 public static function stopChannel(array $row = null, $ownerId = 0): void
328 {
329 if ($row)
330 {
331 if ($row['ENTITY_TYPE'] === self::TYPE_SECTION)
332 {
333 if (Loader::includeModule('dav'))
334 {
335 $connectionData = \CDavConnection::getById($row['ENTITY_ID']);
336 if ($ownerId === 0)
337 {
338 $ownerId = $connectionData['ENTITY_ID'];
339 }
340 }
341
342 if ($ownerId > 0 && isset($connectionData) && !self::isConnectionError($connectionData['LAST_RESULT']))
343 {
344 $googleApiConnection = new GoogleApiSync($ownerId, $row['ENTITY_ID']);
345 $googleApiConnection->stopChannel($row['CHANNEL_ID'], $row['RESOURCE_ID']);
346 }
347 }
348
349 if ($row['ENTITY_TYPE'] === self::TYPE_SECTION)
350 {
351 $section = \CCalendarSect::getById($row['ENTITY_ID']);
352 if ($ownerId === 0)
353 {
354 $ownerId = $section['OWNER_ID'];
355 }
356
357 //TODO: modify the saving of the result
358 if (Loader::includeModule('dav') && !empty($section['CAL_DAV_CON']))
359 {
360 $connectionData = \CDavConnection::getById($section['CAL_DAV_CON']);
361 }
362
363 if ($ownerId > 0 && isset($connectionData) && !self::isConnectionError($connectionData['LAST_RESULT']))
364 {
365 $googleApiConnection = new GoogleApiSync($ownerId, $section['CAL_DAV_CON']);
366 $googleApiConnection->stopChannel($row['CHANNEL_ID'], $row['RESOURCE_ID']);
367 }
368 }
369
371 }
372 }
373
378 public static function isConnectionError(string $lastResult = null): bool
379 {
380 return !empty($lastResult) && preg_match("/^\[(4\d\d)\][a-z0-9 _]*/i", $lastResult);
381 }
382
383 public static function isAuthError(string $lastResult = null): bool
384 {
385 return !empty($lastResult) && preg_match("/^\[(401)\][a-z0-9 _]*/i", $lastResult);
386 }
387
388 public static function isSyncTokenExpiresError(string $lastResult = null): bool
389 {
390 return !empty($lastResult) && preg_match("/^\[(410)\][a-z0-9 _]*/i", $lastResult);
391 }
392
397 public static function isWrongChannel(string $error = null): bool
398 {
399 return !empty($error)
400 && preg_match(
401 "/^\[404\] Channel \'[a-z0-9 _]*\' not found for project \'[a-z0-9 _]*\'/i",
402 $error
403 );
404 }
405
412 public static function clearPushChannels()
413 {
414 return null;
415 }
416
422 public static function receivePushSignal($channelId, $resourceId)
423 {
424 return;
425 }
426
427
434 public static function processIncomingPush(string $entityType, int $entityId)
435 {
436 global $DB;
437 if ($entityType === self::TYPE_SECTION)
438 {
439 $r = $DB->query(
440 "SELECT s.*, c.LAST_RESULT as LAST_RESULT
441 FROM b_calendar_section s
442 LEFT JOIN b_dav_connections c
443 ON s.CAL_DAV_CON = c.ID
444 WHERE s.ID=" . $entityId
445 );
446 if ($section = $r->fetch())
447 {
448 if (self::isAuthError($section['LAST_RESULT']))
449 {
450 return;
451 }
452
453 $tokens = [];
454 if (!empty($tokens))
455 {
456 if (empty($tokens['nextSyncToken']))
457 {
459 }
460
461 \CCalendarSect::edit(
462 [
463 'arFields' =>
464 [
465 'ID' => $section['ID'],
466 'SYNC_TOKEN' => $tokens['nextSyncToken'],
467 'PAGE_TOKEN' => $tokens['nextPageToken'],
468 ]
469 ]
470 );
471 }
472
473 \CCalendar::clearCache();
474 }
475 }
476 elseif ($entityType === self::TYPE_CONNECTION)
477 {
478 $r = $DB->query("SELECT * FROM b_dav_connections WHERE ID=" . $entityId);
479 if ($connection = $r->fetch())
480 {
481 if (
482 self::isAuthError($connection['LAST_RESULT'])
483 || !Loader::includeModule('dav')
484 )
485 {
486 return;
487 }
488
489// \CCalendarSync::syncConnection($connection);
490 \CCalendar::clearCache();
491 }
492 }
493 }
494
498 public static function processPush()
499 {
500 return false;
501 }
502
504 public static function checkPushChannel(int $lastIdConnection = 0)
505 {
506 return;
507 }
508
514 private static function checkPushConnectionChannel(array $connectionIds, array $connections): void
515 {
516 $existedConnectionChannels = [];
517 $pushConnectionChannelsDb = PushTable::getList(
518 [
519 'filter' => [
520 '=ENTITY_TYPE' => self::TYPE_CONNECTION,
521 '=ENTITY_ID' => $connectionIds
522 ]
523 ]
524 );
525
526 while ($row = $pushConnectionChannelsDb->fetch())
527 {
528 $channelInfo = null;
529 if (!empty($connections[$row['ENTITY_ID']]))
530 {
531 $connectionData = $connections[$row['ENTITY_ID']];
532 if (!self::isConnectionError($connectionData['LAST_RESULT']))
533 {
534 $existedConnectionChannels[] = $row['ENTITY_ID'];
535 continue;
536 }
537
538 $googleApiConnection = new GoogleApiSync($connectionData['ENTITY_ID'], $connectionData['ID']);
539 if ($googleApiConnection->stopChannel($row['CHANNEL_ID'], $row['RESOURCE_ID']))
540 {
542 $channelInfo = $googleApiConnection->startWatchCalendarList($connectionData['NAME']);
543 }
544
545 if (is_string($googleApiConnection->getTransportConnectionError()))
546 {
548 }
549
550 if ($channelInfo && isset($channelInfo['id'], $channelInfo['resourceId']))
551 {
552 $existedConnectionChannels[] = $row['ENTITY_ID'];
553 $googleApiConnection->updateSuccessLastResultConnection();
554 PushTable::add([
555 'ENTITY_TYPE' => $row['ENTITY_TYPE'],
556 'ENTITY_ID' => $row['ENTITY_ID'],
557 'CHANNEL_ID' => $channelInfo['id'],
558 'RESOURCE_ID' => $channelInfo['resourceId'],
559 'EXPIRES' => $channelInfo['expiration'],
560 'NOT_PROCESSED' => 'N'
561 ]);
562 }
563 }
564 }
565
566 //create new channel for connections
567 $missedChannelConnections = array_diff($connectionIds, $existedConnectionChannels);
568 if (!empty($missedChannelConnections))
569 {
570 foreach ($missedChannelConnections as $missedConnection)
571 {
572 if (self::isAuthError($missedConnection['LAST_RESULT']))
573 {
574 continue;
575 }
576
577 $channelInfo = null;
578 $connectionData = $connections[$missedConnection];
579 $googleApiConnection = new GoogleApiSync($connectionData['ENTITY_ID'], $connectionData['ID']);
580 $channelInfo = $googleApiConnection->startWatchCalendarList($connectionData['NAME']);
581 if ($channelInfo && isset($channelInfo['id'], $channelInfo['resourceId']))
582 {
583 $googleApiConnection->updateSuccessLastResultConnection();
584 PushTable::add([
585 'ENTITY_TYPE' => self::TYPE_CONNECTION,
586 'ENTITY_ID' => $connectionData['ID'],
587 'CHANNEL_ID' => $channelInfo['id'],
588 'RESOURCE_ID' => $channelInfo['resourceId'],
589 'EXPIRES' => $channelInfo['expiration'],
590 'NOT_PROCESSED' => 'N'
591 ]);
592 }
593 else
594 {
595 $error = $googleApiConnection->getTransportConnectionError();
596 if (is_string($error))
597 {
598 $googleApiConnection->updateLastResultConnection($error);
599 }
600 }
601 }
602 }
603 }
604
611 private static function checkPushSectionChannel(array $connectionIds, array $connections): void
612 {
613 $existedSectionChannels = [];
614 $sections = [];
615 $sectionIds = [];
616
617 $sectionsDb = Internals\SectionTable::getList(
618 [
619 'filter' => [
620 'CAL_DAV_CON' => $connectionIds,
621 ],
622 'order' => [
623 'ID' => 'ASC',
624 ],
625 ]
626 );
627
628 while ($section = $sectionsDb->fetch())
629 {
630 $sections[$section['ID']] = $section;
631 $sectionIds[] = $section['ID'];
632 }
633
634 if (!empty($sectionIds))
635 {
636 $pushSectionChannelsDb = PushTable::getList(
637 [
638 'filter' => [
639 '=ENTITY_TYPE' => self::TYPE_SECTION,
640 '=ENTITY_ID' => $sectionIds
641 ]
642 ]
643 );
644
645 while ($row = $pushSectionChannelsDb->fetch())
646 {
647 $channelInfo = null;
648 if (!empty($sections[$row['ENTITY_ID']]))
649 {
650 $section = $sections[$row['ENTITY_ID']];
651
652 if (self::isVirtualCalendar($section['GAPI_CALENDAR_ID'], $section['EXTERNAL_TYPE']))
653 {
654 continue;
655 }
656
657 if (!self::isConnectionError($connections[$section['CAL_DAV_CON']]['LAST_RESULT']))
658 {
659 $existedSectionChannels[] = $row['ENTITY_ID'];
660 continue;
661 }
662
663 $googleApiConnection = new GoogleApiSync($section['OWNER_ID'], $section['CAL_DAV_CON']);
664 if ($googleApiConnection->stopChannel($row['CHANNEL_ID'], $row['RESOURCE_ID']))
665 {
667 $channelInfo = $googleApiConnection->startWatchEventsChannel($section['GAPI_CALENDAR_ID']);
668 }
669 if (is_string($googleApiConnection->getTransportConnectionError()))
670 {
672 }
673
674 if ($channelInfo && isset($channelInfo['id'], $channelInfo['resourceId']))
675 {
676 $existedSectionChannels[] = $row['ENTITY_ID'];
677 $googleApiConnection->updateSuccessLastResultConnection();
678 PushTable::add([
679 'ENTITY_TYPE' => $row['ENTITY_TYPE'],
680 'ENTITY_ID' => $row['ENTITY_ID'],
681 'CHANNEL_ID' => $channelInfo['id'],
682 'RESOURCE_ID' => $channelInfo['resourceId'],
683 'EXPIRES' => $channelInfo['expiration'],
684 'NOT_PROCESSED' => 'N'
685 ]);
686 }
687 }
688 }
689
690 //create new channel for sections
691 $missedChannelSections = array_diff($sectionIds, $existedSectionChannels);
692 if (!empty($missedChannelSections))
693 {
694 foreach ($missedChannelSections as $missedSection)
695 {
696 $channelInfo = null;
697 $connectionData = $connections[$sections[$missedSection]['CAL_DAV_CON']];
698 $section = $sections[$missedSection];
699 if (
700 self::isAuthError($connectionData['LAST_RESULT'])
701 || self::isVirtualCalendar($section['GAPI_CALENDAR_ID'], $section['EXTERNAL_TYPE'])
702 )
703 {
704 continue;
705 }
706
707 $googleApiConnection = new GoogleApiSync($connectionData['ENTITY_ID'], $connectionData['ID']);
708 $channelInfo = $googleApiConnection->startWatchEventsChannel($section['GAPI_CALENDAR_ID']);
709 if ($channelInfo && isset($channelInfo['id'], $channelInfo['resourceId']))
710 {
711 $googleApiConnection->updateSuccessLastResultConnection();
712 $row = [
713 'ENTITY_TYPE' => self::TYPE_SECTION,
714 'ENTITY_ID' => $missedSection,
715 'CHANNEL_ID' => $channelInfo['id'],
716 'RESOURCE_ID' => $channelInfo['resourceId'],
717 'EXPIRES' => $channelInfo['expiration'],
718 'NOT_PROCESSED' => 'N'
719 ];
721 PushTable::add($row);
722 }
723 else
724 {
725 $error = $googleApiConnection->getTransportConnectionError();
726 if (is_string($error))
727 {
728 $googleApiConnection->updateLastResultConnection($error);
729 }
730 }
731 }
732 }
733 }
734 }
735
741 public static function deletePushChannel(array $row): void
742 {
743 PushTable::delete(['ENTITY_TYPE' => $row['ENTITY_TYPE'], 'ENTITY_ID' => $row['ENTITY_ID']]);
744 }
745
752 private static function isVirtualCalendar(?string $gApiCalendarId, ?string $externalType): bool
753 {
754 return preg_match('/(holiday.calendar.google.com)/', $gApiCalendarId)
755 || preg_match('/(group.v.calendar.google.com)/', $gApiCalendarId)
756 || preg_match('/(@virtual)/', $gApiCalendarId)
757 || preg_match('/(_readonly)/', $externalType)
758 || preg_match('/(_freebusy)/', $externalType);
759 }
760
768 private static function startChannelForInActiveSections(
769 array $localSections,
770 array $inactiveSections,
771 GoogleApiSync $googleApiConnection
772 ): void
773 {
774 foreach ($localSections as $section)
775 {
776 if (self::isVirtualCalendar($section['GAPI_CALENDAR_ID'], $section['EXTERNAL_TYPE']))
777 {
778 continue;
779 }
780
781 if (isset($inactiveSections[$section['ID']]))
782 {
783 if (($push = self::getPush(self::TYPE_SECTION, $section['ID'])) && self::isValid($push))
784 {
785 continue;
786 }
787
788 $channelInfo = $googleApiConnection->startWatchEventsChannel($section['GAPI_CALENDAR_ID']);
789 if ($channelInfo && isset($channelInfo['id'], $channelInfo['resourceId']))
790 {
792 [
793 "ENTITY_TYPE" => self::TYPE_SECTION,
794 'ENTITY_ID' => $section['ID']
795 ]
796 );
797 $googleApiConnection->updateSuccessLastResultConnection();
798 PushTable::add([
799 'ENTITY_TYPE' => self::TYPE_SECTION,
800 'ENTITY_ID' => $section['ID'],
801 'CHANNEL_ID' => $channelInfo['id'],
802 'RESOURCE_ID' => $channelInfo['resourceId'],
803 'EXPIRES' => $channelInfo['expiration'],
804 'NOT_PROCESSED' => 'N'
805 ]);
806 }
807 else
808 {
809 $error = $googleApiConnection->getTransportConnectionError();
810 if (is_string($error))
811 {
812 $googleApiConnection->updateLastResultConnection($error);
813 }
814 }
815 }
816 }
817 }
818
824 private static function getLastResultBySectionId(int $sectionId): ?string
825 {
826 global $DB;
827
828 $strSql = "SELECT c.ID as CONNECTON_ID, c.LAST_RESULT, s.ID as SECTION_ID
829 FROM b_dav_connections c
830 INNER JOIN b_calendar_section s
831 ON s.ID = " . $sectionId
832 . " WHERE s.CAL_DAV_CON = c.ID";
833
834 $connectionDb = $DB->Query($strSql);
835 if ($connection = $connectionDb->Fetch())
836 {
837 return $connection['LAST_RESULT'];
838 }
839
840 return null;
841 }
842
848 private static function getNotVirtualSectionIds(array $localSections): array
849 {
850 $sectionIds = [];
851 foreach ($localSections as $section)
852 {
853 //Skip virtual calendars, because they are not pushable.
854 if (self::isVirtualCalendar($section['GAPI_CALENDAR_ID'], $section['EXTERNAL_TYPE']))
855 {
856 continue;
857 }
858
859 $sectionIds[] = (int)$section['ID'];
860 }
861
862 return $sectionIds;
863 }
864
873 public static function getConnectionPushByConnectionId(int $id)
874 {
875 $pushResultDb = PushTable::getByPrimary([
876 'ENTITY_TYPE' => self::TYPE_CONNECTION,
877 'ENTITY_ID' => $id,
878 ]);
879
880 return $pushResultDb->fetch();
881 }
882
888 public static function setBlockPush(string $type, int $entityId): void
889 {
890 global $DB;
892 if (
893 $push
894 && isset($push['NOT_PROCESSED'])
895 && !in_array($push['NOT_PROCESSED'], Google\Dictionary::PUSH_STATUS_PROCESS, true)
896 )
897 {
898 $strSql = "UPDATE b_calendar_push"
899 . " SET NOT_PROCESSED = '" . Google\Dictionary::PUSH_STATUS_PROCESS['block'] . "'"
900 . " WHERE ENTITY_TYPE = '" . $type . "' AND ENTITY_ID = " . $entityId . ";";
901 $DB->Query($strSql);
902 }
903 }
904
910 public static function setUnblockPush(string $type, int $entityId): void
911 {
912 global $DB;
913
914 $push = self::getPush($type, $entityId);
915 if ($push !== null)
916 {
917 $strSql = "UPDATE b_calendar_push"
918 . " SET NOT_PROCESSED = 'N'"
919 . " WHERE ENTITY_TYPE = '" . $type . "' AND ENTITY_ID = " . $entityId . ";";
920 $DB->Query($strSql);
921
922 if ($push['NOT_PROCESSED'] === Dictionary::PUSH_STATUS_PROCESS['unprocessed'])
923 {
925 }
926 }
927 }
928
934 public static function setUnprocessedPush(string $type, int $entityId): void
935 {
936 global $DB;
937
938 $push = self::getPush($type, $entityId);
939 if (
940 $push
941 && isset($push['NOT_PROCESSED'])
942 && $push['NOT_PROCESSED'] !== Google\Dictionary::PUSH_STATUS_PROCESS['unprocessed']
943 )
944 {
945 $strSql = "UPDATE b_calendar_push"
946 . " SET NOT_PROCESSED = '" . Google\Dictionary::PUSH_STATUS_PROCESS['unprocessed'] ."'"
947 . " WHERE ENTITY_TYPE = '" . $type . "' AND ENTITY_ID = " . $entityId . ";";
948 $DB->Query($strSql);
949 }
950 }
951
958 public static function getPush(string $type, int $entityId): ?array
959 {
960 global $DB;
961
962 $strSql = "SELECT * FROM b_calendar_push"
963 . " WHERE ENTITY_TYPE = '" . $type . "' AND ENTITY_ID = " . $entityId . ";";
964 $pushDb = $DB->Query($strSql);
965
966 if ($push = $pushDb->Fetch())
967 {
968 return $push;
969 }
970
971 return null;
972 }
973
974 private static function isValid(?array $push): bool
975 {
976 if ($push === null)
977 {
978 return false;
979 }
980
981 $now = time();
982 $tsExpires = strtotime($push['EXPIRES']);
983
984 return !($now > $tsExpires);
985 }
986}
$connection
Определения actionsdefinitions.php:38
$type
Определения options.php:106
$resourceId
Определения push.php:24
if(empty( $fields)) foreach($fields as $field) $channelId
Определения push.php:23
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
const PUSH_STATUS_PROCESS
Определения dictionary.php:33
static setIntervalForAgent(int $agentInterval=self::REGULAR_CHECK_TIME, int $delay=self::REGULAR_CHECK_TIME)
Определения queuemanager.php:381
static isWrongChannel(string $error=null)
Определения googleapipush.php:397
static processIncomingPush(string $entityType, int $entityId)
Определения googleapipush.php:434
static isConnectionError(string $lastResult=null)
Определения googleapipush.php:378
static receivePushSignal($channelId, $resourceId)
Определения googleapipush.php:422
static setBlockPush(string $type, int $entityId)
Определения googleapipush.php:888
static stopChannel(array $row=null, $ownerId=0)
Определения googleapipush.php:327
static deletePushChannel(array $row)
Определения googleapipush.php:741
static getConnectionPushByConnectionId(int $id)
Определения googleapipush.php:873
static renewWatchChannels()
Определения googleapipush.php:29
static checkPushChannel(int $lastIdConnection=0)
Определения googleapipush.php:504
static createWatchChannels($start=0)
Определения googleapipush.php:232
static checkSectionsPush($localSections, $userId, $connectionId)
Определения googleapipush.php:157
static getPush(string $type, int $entityId)
Определения googleapipush.php:958
static isSyncTokenExpiresError(string $lastResult=null)
Определения googleapipush.php:388
static setUnprocessedPush(string $type, int $entityId)
Определения googleapipush.php:934
static setUnblockPush(string $type, int $entityId)
Определения googleapipush.php:910
static isAuthError(string $lastResult=null)
Определения googleapipush.php:383
static clearPushChannels()
Определения googleapipush.php:412
if(!\Bitrix\Main\Loader::includeModule('clouds')) $lastId
Определения sync.php:68
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$start
Определения get_search.php:9
global $DB
Определения cron_frame.php:29
string $sectionId
Определения columnfields.php:71
Определения collection.php:2
$entityId
Определения payment.php:4
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$error
Определения subscription_card_product.php:20