Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
incomingmanager.php
1<?php
2
4
18use Bitrix\Calendar\Sync\Internals\HasContextTrait;
24use Bitrix\Calendar\Core;
30use DateTime;
31use DateTimeZone;
32use Exception;
33
35{
36 use HasContextTrait;
37
41 private const IMPORT_SECTIONS_LIMIT = 10;
42
44 private ?SectionConnection $lastSectionConnection = null;
45
49 public function __construct(Office365Context $context)
50 {
51 $this->context = $context;
52 parent::__construct($context->getConnection());
53 }
54
68 public function getSections(): Result
69 {
70 $result = new Result();
71 $syncSectionMap = new SyncSectionMap();
72 $sections = $this->context->getVendorSyncService()->getSections();
73 foreach ($sections as $sectionDto)
74 {
75 if ($sectionDto->canShare)
76 {
77 $syncSectionMap->add(
78 $this->prepareSyncSection($sectionDto),
79 $sectionDto->id
80 );
81 }
82 }
83
84 return $result->setData([
85 'externalSyncSectionMap' => $syncSectionMap,
86 ]);
87 }
88
94 private function prepareSyncSection(SectionDto $sectionDto): SyncSection
95 {
96 $section = $this->context->getConverter()->convertSection($sectionDto);
97 $section
98 ->setExternalType(Helper::ACCOUNT_TYPE)
99 ->setOwner($this->connection->getOwner())
100 ->setCreator($this->connection->getOwner())
101 ->setIsActive(true)
102 ->setType('user')
103 ;
104 $sectionConnection = (new SectionConnection())
105 ->setSection($section)
106 ->setConnection($this->connection)
107 ->setVendorSectionId($sectionDto->id)
108 ->setActive(true)
109 ->setLastSyncDate(null)
110 ->setPrimary($sectionDto->isDefaultCalendar ?? false)
111 ->setOwner($this->connection->getOwner())
112 ->setLastSyncStatus(Dictionary::SYNC_STATUS['success'])
113 ->setVersionId($sectionDto->changeKey)
114 ;
115
116 return (new SyncSection())
117 ->setSection($section)
118 ->setSectionConnection($sectionConnection)
119 ->setVendorName($this->getServiceName())
120 ->setAction(Dictionary::SYNC_STATUS['success'])
121 ;
122 }
123
138 public function getEvents(SyncSection $syncSection): Result
139 {
140 $syncEventMap = new SyncEventMap();
141 $result = (new Result())->setData([
142 'externalSyncEventMap' => $syncEventMap,
143 ]);
144 $service = $this->context->getVendorSyncService();
145 $this->lastSectionConnection = $syncSection->getSectionConnection();
146 foreach ($service->getCalendarDelta($syncSection->getSectionConnection()) as $eventId => $eventPack)
147 {
149 if ($dto = ($eventPack[Helper::EVENT_TYPES['deleted']] ?? null))
150 {
151 $this->pushIntoSyncEventMap(
152 $syncEventMap,
153 $eventId,
154 $this->prepareDeletedSyncEvent($dto, $syncSection),
155 'delete' // change to dictionary constant
156 );
157 }
158 elseif ($dto = ($eventPack[Helper::EVENT_TYPES['single']] ?? null))
159 {
160 $this->pushIntoSyncEventMap($syncEventMap, $eventId, $this->prepareSyncEvent($dto, $syncSection));
161 }
162 elseif ($dto = ($eventPack[Helper::EVENT_TYPES['series']] ?? null))
163 {
164 $master = $this->prepareSyncEvent($dto, $syncSection);
165 $this->pushIntoSyncEventMap($syncEventMap, $eventId, $master);
166 if ($master->getEvent()->getRecurringRule())
167 {
168 $master->getEvent()
169 ->setExcludedDateCollection(new Core\Event\Properties\ExcludedDatesCollection([]));
170 if ($exceptions = ($eventPack[Helper::EVENT_TYPES['exception']] ?? null))
171 {
172 foreach ($exceptions as $exceptionDto)
173 {
174 $exception = $this->prepareSyncEvent($exceptionDto, $syncSection)
175 ->setAction(Dictionary::SYNC_EVENT_ACTION['create'])
176 ;
177 $master->addInstance($exception);
178 }
179 }
181 $instances = array_map(function (DateTimeDto $val) use ($master) {
182 $result = (new DateTime(
183 $val->dateTime,
184 new DateTimeZone($val->timeZone)
185 ))->setTimezone($master->getEvent()->getStartTimeZone()->getTimeZone());
186
187 return $result->format('d.m.Y');
188 }, ($eventPack[Helper::EVENT_TYPES['occurrence']] ?? []));
189 $deltaPeriod = $this->context->getHelper()->getDeltaInterval();
190 $computedInstances = (new Core\Event\Tools\Recurrence())->getEventOccurenceDates(
191 $master->getEvent(),
192 [
193 'limitDateFrom' => $deltaPeriod['from'],
194 'limitDateTo' => $deltaPeriod['to'],
195 ]
196 );
197 foreach ($computedInstances as $date => $dateTime)
198 {
199 if (!in_array($date, $instances))
200 {
201 $master->getEvent()->getExcludedDateCollection()->add(
202 Core\Base\Date::createDateFromFormat($date, 'd.m.Y')
203 ->resetTime()
204 ->setDateTimeFormat('d.m.Y')
205 );
206 }
207 }
208 }
209 }
210 }
211
212 return $result;
213 }
214
225 private function pushIntoSyncEventMap(
226 SyncEventMap $map,
227 string $key,
228 SyncEvent $event,
229 string $action = 'save'
230 )
231 {
232 $event->setAction($action);
233 $map->add($event, $key);
234 }
235
242 private function prepareSyncEvent(
243 EventDto $eventDto,
244 SyncSection $section
245 ): SyncEvent
246 {
247
248 $event = $this->context->getConverter()
249 ->convertEvent($eventDto, $section->getSection());
250 $eventConnection = (new EventConnection())
251 ->setEvent($event)
252 ->setConnection($section->getSectionConnection()->getConnection())
253 ->setVendorEventId($eventDto->id)
254 ->setVendorVersionId($eventDto->changeKey)
255 ->setEntityTag($eventDto->etag)
256 ->setRecurrenceId($eventDto->seriesMasterId ?: null)
257 ->setData($this->prepareCustomData($eventDto))
258 ->setLastSyncStatus(Dictionary::SYNC_STATUS['success'])
259 ;
260
261 return (new SyncEvent())
262 ->setEvent($event)
263 ->setEventConnection($eventConnection);
264 }
265
271 private function prepareCustomData(EventDto $eventDto): array
272 {
273 $data = [];
274 if (!empty($eventDto->location))
275 {
276 $data['location'] = $eventDto->location->toArray(true);
277 }
278 if (!empty($eventDto->locations))
279 {
280 foreach ($eventDto->locations as $location)
281 {
282 $data['locations'][] = $location->toArray(true);
283 }
284 }
285
286 if (!empty($eventDto->attendees))
287 {
288 $data['attendees'] = [];
289 foreach ($eventDto->attendees as $attendee)
290 {
291 $data['attendees'][] = $attendee->toArray(true);
292 }
293 }
294
295 return $data;
296 }
297
301 public function getSectionConnection(): Result
302 {
303 return (new Result())->setData(['sectionConnection' => new SectionConnection()]);
304 }
305
306 public function getPageToken(): ?string
307 {
308 if ($this->lastSectionConnection)
309 {
310 return $this->lastSectionConnection->getPageToken();
311 }
312 return null;
313 }
314
315 public function getEtag(): ?string
316 {
317 if ($this->lastSectionConnection)
318 {
319 return $this->lastSectionConnection->getVersionId();
320 }
321 return null;
322 }
323
324 public function getSyncToken(): ?string
325 {
326 if ($this->lastSectionConnection)
327 {
328 return $this->lastSectionConnection->getSyncToken();
329 }
330 return null;
331 }
332
333 public function getStatus(): ?string
334 {
335 if ($this->lastSectionConnection)
336 {
337 return $this->lastSectionConnection->getLastSyncStatus();
338 }
339 return null;
340 }
341
342 public function getConnection(): Result
343 {
344 return (new Result())->setData([
345 'connection' => $this->context->getConnection(),
346 ]);
347 }
348
355 private function prepareDeletedSyncEvent(EventDto $dto, SyncSection $syncSection): SyncEvent
356 {
357 $event = new Core\Event\Event();
358 $eventConnection = (new EventConnection())
359 ->setEvent($event)
360 ->setConnection($syncSection->getSectionConnection()->getConnection())
361 ->setVendorEventId($dto->id)
362 ;
363
364 return (new SyncEvent())
365 ->setEvent($event)
366 ->setEventConnection($eventConnection);
367 }
368}
setData(array $data)
Definition result.php:113