Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
synceventfactory.php
1<?php
2
4
8use Bitrix\Calendar\Internals\EO_SectionConnection;
15use Bitrix\Main\Entity\ReferenceField;
23
25{
26 const TIME_SLICE = 2600000;
27
28 private Mappers\Event $eventMapper;
29 private Mappers\EventConnection $eventConnectionMapper;
30
31 public function __construct()
32 {
33 $helper = ServiceLocator::getInstance()->get('calendar.service.mappers.factory');
34 $this->eventMapper = $helper->getEvent();
35 $this->eventConnectionMapper = $helper->getEventConnection();
36 }
37
42 public function delete(Sync\Entities\SyncEvent $syncEvent): void
43 {
44 $this->eventMapper->delete($syncEvent->getEvent());
45 $this->eventConnectionMapper->delete($syncEvent->getEventConnection());
46 }
47
55 public function getSyncEventCollectionByVendorIdList(
56 array $vendorEventIdList,
57 int $connectionId
58 ): Sync\Entities\SyncEventMap
59 {
60 $syncEventMap = new Sync\Entities\SyncEventMap();
61
62 if (empty($vendorEventIdList))
63 {
64 return $syncEventMap;
65 }
66
67 $query1 = EventConnectionTable::query()
68 ->setSelect(['ID'])
69 ->where('CONNECTION_ID', $connectionId)
70 ->whereIn('VENDOR_EVENT_ID', $vendorEventIdList)
71 ;
72 $query2 = EventConnectionTable::query()
73 ->setSelect(['ID'])
74 ->where('CONNECTION_ID', $connectionId)
75 ->whereIn('RECURRENCE_ID', $vendorEventIdList)
76 ;
77
78 $query1->unionAll($query2);
79 $result = $query1->exec()->fetchAll();
80
81 $idList = array_map(static function($item) {return (int)$item['ID'];}, $result);
82
83 if (empty($idList))
84 {
85 return $syncEventMap;
86 }
87
88 $filter = [
89 ['ID', 'in', $idList],
90 ];
91 $query = ConditionTree::createFromArray($filter);
92 $eventConnectionMap = $this->eventConnectionMapper->getMap($query);
93
94 $impatientExportSyncEventList = [];
95
97 foreach ($eventConnectionMap as $eventConnection)
98 {
99 $syncEvent = new SyncEvent();
100 $syncEvent
101 ->setEventConnection($eventConnection)
102 ->setEvent($eventConnection->getEvent())
103 ->setAction($eventConnection->getLastSyncStatus())
104 ;
105
106 if ($syncEvent->isInstance())
107 {
109 if ($masterSyncEvent = $syncEventMap->getItem($syncEvent->getVendorRecurrenceId()))
110 {
111 $masterSyncEvent->addInstance($syncEvent);
112 continue;
113 }
114
115 $impatientExportSyncEventList[$syncEvent->getVendorRecurrenceId()][$eventConnection->getVendorEventId()] = $syncEvent;
116 continue;
117 }
118
119 if (
120 $syncEvent->isRecurrence()
121 && $instanceList = ($impatientExportSyncEventList[$syncEvent->getVendorEventId()] ?? null)
122 )
123 {
124 $syncEvent->addInstanceList($instanceList);
125 }
126
127 $syncEventMap->add(
128 $syncEvent,
129 $eventConnection->getVendorEventId()
130 );
131 }
132
133 if ($impatientExportSyncEventList)
134 {
135 foreach ($impatientExportSyncEventList as $syncEventList)
136 {
137 $syncEventMap->addItems($syncEventList);
138 }
139 }
140
141 return $syncEventMap;
142 }
143
156 public function getSyncEventMapBySyncSectionIdCollectionForExport(
157 array $sectionIdList,
158 int $userId,
159 int $connectionId
160 ): ?Sync\Entities\SyncEventMap
161 {
162 Loader::includeModule('dav');
163
164 if (!$sectionIdList)
165 {
166 return null;
167 }
168
169 $timestamp = time() - self::TIME_SLICE;
170 $eventDb = EventTable::query()
171 ->setSelect([
172 '*',
173 'EVENT_CONNECTION.*',
174 'EVENT_CONNECTION.CONNECTION',
175 'EVENT_CONNECTION.EVENT',
176 ])
177 ->where('OWNER_ID', $userId)
178 ->where('CAL_TYPE', Dictionary::EVENT_TYPE['user'])
179 ->where('DELETED', 'N')
180 ->where('DATE_TO_TS_UTC', '>', $timestamp)
181 // ->whereNot('MEETING_STATUS', 'N')
182 ->where(Query::filter() // TODO: it's better to optimize it and don't use 'OR' logic here
183 ->logic('or')
184 ->whereNot('MEETING_STATUS', 'N')
185 ->whereNull('MEETING_STATUS')
186 )
187 ->whereIn('SECTION_ID', $sectionIdList)
188 ->registerRuntimeField('EVENT_CONNECTION',
189 new ReferenceField(
190 'SYNC_DATA',
191 EventConnectionTable::getEntity(),
192 Join::on('ref.EVENT_ID', 'this.ID')
193 ->where('ref.CONNECTION_ID', $connectionId)
194 ,
195 ['join_type' => Join::TYPE_LEFT]
196 )
197 )
198 ->addOrder('ID')
199 ->exec()
200 ;
201
202 $map = new Sync\Entities\SyncEventMap();
203 $impatientSyncEventInstanceList = [];
204
205 while ($eventDM = $eventDb->fetchObject())
206 {
207 $action = Sync\Dictionary::SYNC_EVENT_ACTION['create'];
208 $syncEvent = new Sync\Entities\SyncEvent();
209
210 $event = (new EventBuilderFromEntityObject($eventDM))->build();
211 $syncEvent->setEvent($event);
212
214 if ($eventConnectionDM = $eventDM->get('EVENT_CONNECTION'))
215 {
216 $eventConnection = (new Sync\Builders\BuilderEventConnectionFromDM($eventConnectionDM))->build();
217 $eventConnection->setEvent($event);
218 $syncEvent->setEventConnection($eventConnection);
219
220 if (
221 in_array($eventConnection->getLastSyncStatus(), Sync\Dictionary::SYNC_EVENT_ACTION, true)
222 && ($eventConnection->getLastSyncStatus() !== Sync\Dictionary::SYNC_EVENT_ACTION['success'])
223 )
224 {
225 $action = $eventConnection->getLastSyncStatus();
226 }
227 elseif ($event->getVersion() > $eventConnection->getVersion())
228 {
229 $action = Sync\Dictionary::SYNC_EVENT_ACTION['update'];
230 }
231 else
232 {
233 $action = Sync\Dictionary::SYNC_EVENT_ACTION['success'];
234 }
235 }
236
237 if ($syncEvent->isInstance())
238 {
239 $syncEvent->setAction($action);
241 $masterEvent = $map->getItem($event->getUid());
242 if ($masterEvent)
243 {
244 if (
245 $masterEvent->getAction() === Sync\Dictionary::SYNC_EVENT_ACTION['success']
246 && $syncEvent->getAction() !== Sync\Dictionary::SYNC_EVENT_ACTION['success']
247 )
248 {
249 $masterEvent->setAction(Sync\Dictionary::SYNC_EVENT_ACTION['update']);
250 }
251
252 $masterEvent->addInstance($syncEvent);
253
254 continue;
255 }
256
257 $impatientSyncEventInstanceList[$event->getUid()][] = $syncEvent;
258 }
259 else
260 {
261 if ($instanceList = ($impatientSyncEventInstanceList[$event->getUid()] ?? null))
262 {
263 $syncEvent->addInstanceList($instanceList);
264 unset($impatientSyncEventInstanceList[$event->getUid()]);
265 if (
266 $syncEvent->getAction() !== Sync\Dictionary::SYNC_EVENT_ACTION['success']
267 && $this->hasCandidatesForUpdate($instanceList)
268 )
269 {
270 $action = Sync\Dictionary::SYNC_EVENT_ACTION['update'];
271 }
272 }
273 $syncEvent->setAction($action);
274 $map->add($syncEvent, $event->getUid());
275 }
276 }
277
278 return $map;
279 }
280
286 private function hasCandidatesForUpdate(array $list): bool
287 {
288 return (bool)array_filter($list, function (SyncEvent $syncEvent) {
289 return $syncEvent->getAction() !== Sync\Dictionary::SYNC_EVENT_ACTION['success'];
290 });
291 }
292}