Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
eventconverter.php
1<?php
2
4
14
16{
17 protected const MAX_COUNT_REMINDERS_FOR_SYNC = 5;
18
26 private Event $originalEvent;
30 private ?EventConnection $eventConnection;
31
37 public function __construct(
38 Event $event,
39 EventConnection $eventConnection = null,
41 )
42 {
43 $this->originalEvent = $event;
44 $this->eventConnection = $eventConnection;
45 $this->instanceCollection = $instanceCollection;
46 }
47
52 public function convertForCreate(): array
53 {
54 $event = [];
55
56 $event['summary'] = $this->originalEvent->getName();
57 $event['description'] = $this->prepareDescription($this->originalEvent);
58 $event['transparency'] = $this->prepareAccessibility();
59 $event = array_merge($event, $this->prepareDate());
60 $event['reminders'] = $this->prepareReminders();
61 $event['location'] = $this->prepareLocation();
62 $event['visibility'] = $this->prepareVisibility();
63 // $event['sequence'] = $this->originalEvent->getVersion() - Helper::VERSION_DIFFERENCE;
64
65 if ($this->originalEvent->getUid() !== null)
66 {
67 $event['iCalUID'] = $this->originalEvent->getUid();
68 }
69
70 if ($this->originalEvent->isRecurrence())
71 {
72 $event['recurrence'] = $this->prepareRecurrenceRule();
73 }
74
75 return $event;
76 }
77
85 private function prepareDescription(Event $event): string
86 {
87 $description = \CCalendarEvent::ParseText((new EventDescription())->prepareForExport($event));
88
89 return preg_replace("/<br>/i", "\r\n", $description);
90 }
91
96 public function convertForUpdate(): array
97 {
98 if ($this->eventConnection === null)
99 {
100 throw new BaseException('you should initialize eventConnection before update event');
101 }
102
103 $event = $this->convertForCreate();
104 if ($this->eventConnection && $this->eventConnection->getVendorEventId() !== null)
105 {
106 $event['id'] = $this->eventConnection->getVendorEventId();
107
108 if ($this->originalEvent->isInstance())
109 {
110 $event['recurringEventId'] = $this->eventConnection->getRecurrenceId();
111 }
112 }
113
114 return $event;
115 }
116
122 public function convertForDeleteInstance(): array
123 {
124 $event = $this->convertForUpdate();
125 $event['status'] = 'cancelled';
126
127 return $event;
128 }
129
133 public function prepareAccessibility(): string
134 {
135 return $this->originalEvent->getAccessibility() === 'busy'
136 ? 'opaque'
137 : 'transparent'
138 ;
139 }
140
144 public function prepareDate(): array
145 {
146 $date = [];
147
148 if ($this->originalEvent->isFullDayEvent())
149 {
150 $date['start']['date'] = $this->originalEvent->getStart()->format('Y-m-d');
151 $date['end']['date'] = $this->originalEvent->getEnd()->add(('+1 day'))->format('Y-m-d');
152 }
153 else
154 {
155 $date['start']['dateTime'] = $this->originalEvent->getStart()->format(Helper::DATE_TIME_FORMAT);
156 $date['start']['timeZone'] = $this->originalEvent->getStartTimeZone()
157 ? $this->originalEvent->getStartTimeZone()->getTimeZone()->getName()
158 : (new \DateTime())->getTimezone()->getName()
159 ;
160 $date['end']['dateTime'] = $this->originalEvent->getEnd()->format(Helper::DATE_TIME_FORMAT);
161 $date['end']['timeZone'] = $this->originalEvent->getEndTimeZone()
162 ? $this->originalEvent->getEndTimeZone()->getTimeZone()->getName()
163 : (new \DateTime())->getTimezone()->getName()
164 ;
165 }
166
167 if ($this->originalEvent->getOriginalDateFrom() !== null)
168 {
169 if ($this->originalEvent->isFullDayEvent())
170 {
171 $event['originalStartTime']['date'] = $this->originalEvent->getOriginalDateFrom()->format(Helper::DATE_FORMAT);
172 }
173 else
174 {
175 $event['originalStartTime']['dateTime'] = $this->originalEvent->getOriginalDateFrom()->format(Helper::DATE_TIME_FORMAT);
176 }
177 }
178
179 return $date;
180 }
181
185 private function prepareReminders(): array
186 {
187 $reminders = [];
188 $reminders['useDefault'] = false;
189
190 $remindCollection = $this->originalEvent->getRemindCollection();
191 if ($remindCollection && $remindCollection->count() > self::MAX_COUNT_REMINDERS_FOR_SYNC)
192 {
193 $remindCollection->sortFromStartEvent();
194 }
195
197 foreach ($remindCollection as $remind)
198 {
199 if (!$remind->isBeforeEventStart())
200 {
201 continue;
202 }
203
204 $reminders['overrides'][] = [
205 Remind::UNIT_MINUTES => $remind->getTimeBeforeStartInMinutes(),
206 'method' => 'popup',
207 ];
208
209 if (count($reminders['overrides']) >= self::MAX_COUNT_REMINDERS_FOR_SYNC)
210 {
211 break;
212 }
213 }
214
215 return $reminders;
216 }
217
224 private function prepareLocation(): string
225 {
226 if ($this->originalEvent->getLocation())
227 {
228 return \Bitrix\Calendar\Rooms\Util::getTextLocation((string)$this->originalEvent->getLocation());
229 }
230
231 return '';
232 }
233
237 private function prepareVisibility(): string
238 {
239 return $this->originalEvent->isPrivate()
240 ? 'private'
241 : 'public'
242 ;
243 }
244
248 private function prepareRecurrenceRule(): array
249 {
250 $rule = [];
251
252 if (!$this->originalEvent->isRecurrence())
253 {
254 return [];
255 }
256
257 $rule[] = $this->prepareDescriptionRecurrenceRule();
258
259 if ($this->originalEvent->getExcludedDateCollection() !== null)
260 {
261 array_push($rule, ...$this->prepareExcludedDates());
262 }
263
264 return $rule;
265 }
266
270 public function prepareDescriptionRecurrenceRule(): string
271 {
273 $eventRule = $this->originalEvent->getRecurringRule();
274 $descriptionRule = 'RRULE:';
275 $descriptionRule .= 'FREQ=' . $eventRule->getFrequency();
276 $descriptionRule .= ';INTERVAL=' . $eventRule->getInterval();
277
278 if ($eventRule->hasDay())
279 {
280 $descriptionRule .= ';BYDAY=' . implode(",", $eventRule->getByday());
281 }
282
283 if ($eventRule->hasCount())
284 {
285 $descriptionRule .= ';COUNT=' . $eventRule->getCount();
286 }
287 elseif ($eventRule->hasUntil())
288 {
289 $until = clone $eventRule->getUntil();
290 if (!$this->originalEvent->isFullDayEvent() && !$eventRule->isUntilEndOfTime())
291 {
292 $until = $until->add('1 day')->sub('1 second');
293 }
294 $descriptionRule .= ';UNTIL=' . $until->format(Helper::DATE_TIME_FORMAT_WITH_UTC_TIMEZONE);
295 }
296
297 return $descriptionRule;
298 }
299
303 public function prepareExcludedDates(): array
304 {
305 $rule = [];
306
307 if (
308 $this->originalEvent->getExcludedDateCollection()
309 && ($exdateCollection = $this->originalEvent->getExcludedDateCollection()->getDateCollectionNewerThanInterval())
310 )
311 {
312 $originalDateList = [];
313 if ($this->instanceCollection !== null)
314 {
316 foreach ($this->instanceCollection as $instance)
317 {
318 if ($originalDateFrom = $instance->getEvent()->getOriginalDateFrom())
319 {
320 $originalDateList[] = $originalDateFrom->format('Ymd');
321 }
322 }
323 }
324
325 if ($this->originalEvent->isFullDayEvent())
326 {
327 foreach ($exdateCollection as $exDate)
328 {
329 $date = $exDate->format('Ymd');
330 if (!in_array($date, $originalDateList, true))
331 {
332 $rule[] = 'EXDATE;VALUE=DATE:' . $date;
333 }
334 }
335 }
336 else
337 {
338 $postfix = (clone $this->originalEvent->getStart())
339 ->setTimezone(new \DateTimeZone('UTC'))
340 ->format('\\THis\\Z')
341 ;
343 foreach ($exdateCollection as $exDate)
344 {
345 $date = $exDate->format('Ymd');
346 if (!in_array($date, $originalDateList, true))
347 {
348 $rule[] = 'EXDATE;TZID=UTC:' . $date . $postfix;
349 }
350 }
351 }
352 }
353
354 return $rule;
355 }
356
360 public function convertForDelete(): array
361 {
362 return [
363 'sendUpdates' => 'all',
364 ];
365 }
366}
__construct(Event $event, EventConnection $eventConnection=null, ?InstanceMap $instanceCollection=null)