Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
eventbuilder.php
1<?php
2
4
6use Bitrix\Calendar\Core\Base\SingletonTrait;
15
17{
19
20 const DAY_LENGTH = 86400;
21
28 public function getContent(Event $event, ?array $data = null): ?array
29 {
30 if (!Loader::includeModule('dav'))
31 {
32 return null;
33 }
34
35 $content = [
36 'TYPE' => 'VEVENT',
37 'CREATED' => date('Ymd\\THis\\Z', $event->getDateCreate()->getTimestamp()),
38 'LAST-MODIFIED' => date('Ymd\\THis\\Z', $event->getDateModified()->getTimestamp()),
39 'DTSTAMP' => date('Ymd\\THis\\Z', $event->getDateModified()->getTimestamp()),
40 'UID' => $event->getUid(),
41 'SUMMARY' => $event->getName(),
42 ];
43
44 if ($event->isFullDayEvent())
45 {
46 $content['DTSTART'] = [
47 'VALUE' => $event->getStart()->format('Ymd'),
48 'PARAMETERS' => ['VALUE' => 'DATE'],
49 ];
50 $content['DTEND'] = [
51 'VALUE' => $event->getEnd()->add('1 day')->format('Ymd'),
52 'PARAMETERS' => ['VALUE' => 'DATE'],
53 ];
54 }
55 else
56 {
57 $content['DTSTART'] = [
58 'VALUE' => $event->getStart()->format('Ymd\\THis'),
59 'PARAMETERS' => ['TZID' => $this->prepareTimeZone($event->getStartTimeZone())],
60 ];
61 $content['DTEND'] = [
62 'VALUE' => $event->getEnd()->format('Ymd\\THis'),
63 'PARAMETERS' => ['TZID' => $this->prepareTimeZone($event->getEndTimeZone())],
64 ];
65 }
66
67 if ($event->getOriginalDateFrom())
68 {
69 if ($event->isFullDayEvent())
70 {
71 $content['RECURRENCE-ID'] = [
72 'VALUE' => $event->getOriginalDateFrom()->format('Ymd'),
73 'PARAMETERS' => ['VALUE' => 'DATE'],
74 ];
75 }
76 else
77 {
78 $content['RECURRENCE-ID'] = [
79 'VALUE' => $event->getOriginalDateFrom()->format('Ymd\\THis'),
80 'PARAMETERS' => ['TZID' => $this->prepareTimeZone($event->getStartTimeZone())],
81 ];
82 }
83 }
84
85 if ($event->getAccessibility() === 'free')
86 {
87 $content['TRANSP'] = 'TRANSPARENT';
88 }
89 else
90 {
91 $content['TRANSP'] = 'OPAQUE';
92 }
93
94 if ($event->getLocation() && $event->getLocation()->getActualLocation())
95 {
96 $content['LOCATION'] = Rooms\Util::getTextLocation($event->getLocation()->getActualLocation());
97 }
98
99 $importance = $event->getImportance();
100 if ($importance === 'low')
101 {
102 $content['PRIORITY'] = 9;
103 }
104 else if ($importance === 'high')
105 {
106 $content['PRIORITY'] = 1;
107 }
108 else
109 {
110 $content['PRIORITY'] = 5;
111 }
112
113 $content['DESCRIPTION'] = $this->prepareDescription($event);
114 if (!$content['DESCRIPTION'])
115 {
116 unset($content['DESCRIPTION']);
117 }
118
119 if ($event->getRemindCollection() && $event->getRemindCollection()->getCollection())
120 {
121 $content['@VALARM'] = $this->prepareReminders($event);
122 }
123
124 if ($event->isRecurrence())
125 {
126 $content['RRULE'] = $this->prepareRecurrenceRule($event->getRecurringRule(), $event->getStartTimeZone());
127 }
128
129 $content['SEQUENCE'] = $event->getVersion();
130
131 if ($event->getExcludedDateCollection() && $event->isRecurrence())
132 {
133 $content['EXDATE'] = $this->prepareExcludedDates($event);
134 }
135
136 $this->prepareOuterParams($data, $content);
137
138 return $content;
139 }
140
146 private function prepareDescription(Event $event): string
147 {
148 return (new EventDescription())->prepareForExport($event);
149 }
150
158 private function prepareReminderValue(
159 Remind $remind,
160 bool $isFullDay
161 ): array
162 {
163 $valueType = '';
164 $value = '';
165
166 if ($remind->getUnits() === 'minutes')
167 {
168 $valueType = 'DURATION';
169 if ($remind->getTime() === 60 || $remind->getTime() === 120)
170 {
171 $value = '-PT' . $remind->getTime() / 60 . 'H';
172 }
173 else if ($remind->getTime() === 0)
174 {
175 $value = 'PT' . $remind->getTime() . 'S';
176 }
177 else
178 {
179 $value = '-PT' . $remind->getTime() . 'M';
180 }
181 }
182 else if ($remind->getSpecificTime() && $remind->getDaysBefore() !== null)
183 {
184 $valueType = 'DURATION';
185 $diff = $remind->getTimeBeforeStartInMinutes();
186 $parsedDiff = Util::minutesToDayHoursMinutes(abs($diff));
187 if ($isFullDay && $remind->getDaysBefore() === 0)
188 {
189 $value = 'PT' . $parsedDiff['hours'] . 'H';
190 }
191 else if (
192 ($remind->getDaysBefore() === 0 && !$isFullDay && $diff > 0)
193 || ($remind->getDaysBefore() === 1 && $parsedDiff['days'] === 0)
194 )
195 {
196 $hours = '';
197 $minutes = '';
198 if ($parsedDiff['hours'])
199 {
200 $hours = $parsedDiff['hours'] . 'H';
201 }
202 if ($parsedDiff['minutes'])
203 {
204 $minutes = $parsedDiff['minutes'] . 'M';
205 }
206 $value = '-PT' . $hours . $minutes;
207 }
208 else if ($parsedDiff['days'] > 0)
209 {
210 $hours = '';
211 $minutes = '';
212 $value = '-P' . $parsedDiff['days'] . 'D';
213 if ($parsedDiff['hours'])
214 {
215 $hours = $parsedDiff['hours'] . 'H';
216 }
217 if ($parsedDiff['minutes'])
218 {
219 $minutes = $parsedDiff['minutes'] . 'M';
220 }
221 if ($hours || $minutes)
222 {
223 $value .= 'T' . $hours . $minutes;
224 }
225 }
226 else
227 {
228 return [null, null];
229 }
230 }
231 else if ($remind->getSpecificTime())
232 {
233 $valueType = 'DATE-TIME';
234 $value = date('Ymd\\THis\\Z', $remind->getSpecificTime()->getTimestamp());
235 }
236
237 return [$value, $valueType];
238 }
239
245 private function prepareTimeZone(?DateTimeZone $timeZone): string
246 {
247 if ($timeZone)
248 {
249 return $timeZone->getTimeZone()->getName();
250 }
251
252 return 'UTC';
253 }
254
261 private function prepareReminders(Event $event): array
262 {
263 $result = [];
265 foreach ($event->getRemindCollection()->getCollection() as $remind)
266 {
267 [$value, $valueType] = $this->prepareReminderValue(
268 $remind,
269 $event->isFullDayEvent()
270 );
271
272 if (!$value || !$valueType)
273 {
274 continue;
275 }
276
278 $result[] = [
279 'X-WR-ALARMUID' => $uuId,
280 'UID' => $uuId,
281 'TYPE' => 'VALARM',
282 'ACTION' => 'DISPLAY',
283 'TRIGGER' => [
284 'PARAMETERS' => ['VALUE' => $valueType],
285 'VALUE' => $value,
286 ],
287 ];
288 }
289
290 return $result;
291 }
292
300 private function prepareRecurrenceRule(RecurringEventRules $rrule, ?DateTimeZone $timeZone): string
301 {
302 $result = 'FREQ=' . $rrule->getFrequency();
303 if ($rrule->getInterval())
304 {
305 $result .= ';INTERVAL=' . $rrule->getInterval();
306 }
307 if ($rrule->getByday())
308 {
309 $result .= ';BYDAY=' . implode(',', $rrule->getByday());
310 }
311 if ($rrule->getCount())
312 {
313 $result .= ';COUNT=' . $rrule->getCount();
314 }
315 else if (
316 $rrule->getUntil()
317 && $rrule->getUntil()->getDate()->getTimestamp()
318 && $rrule->getUntil()->getDate()->getTimestamp() < 2145830400
319 )
320 {
321 $offset = 0;
322 if ($timeZone)
323 {
324 $offset = $timeZone->getTimeZone()->getOffset(new \DateTime('now', $timeZone->getTimeZone()));
325 }
326
327 $untilTimestamp = $rrule->getUntil()->getDate()->getTimestamp() + (self::DAY_LENGTH - 1) - $offset;
328 $result .= ';UNTIL=' . date('Ymd\\THis\\Z', $untilTimestamp);
329 }
330
331 return $result;
332 }
333
339 private function prepareExcludedDates(Event $event): array
340 {
341 $result = [];
342 $exDate = $event->getExcludedDateCollection()->getCollection();
343 foreach ($exDate as $date)
344 {
345 $fields = $date->getFields();
346 if ($event->isFullDayEvent())
347 {
348 $result[] = [
349 'VALUE' => date('Ymd', MakeTimeStamp($fields['date'])),
350 'PARAMETERS' => ['VALUE' => 'DATE'],
351 ];
352 }
353 else
354 {
355 $result[] = [
356 'VALUE' => date('Ymd', MakeTimeStamp($fields['date']))
357 . 'T' . $event->getStart()->format('His'),
358 'PARAMETERS' => ['TZID' => $this->prepareTimeZone($event->getStartTimeZone())],
359 ];
360 }
361 }
362
363 return $result;
364 }
365
372 private function prepareOuterParams(?array $data, array &$content): void
373 {
374 if (!$data)
375 {
376 return;
377 }
378
379 if ($data['ATTENDEE'])
380 {
381 foreach ($data['ATTENDEE'] as $attendee)
382 {
383 $value = $attendee['VALUE'];
384 unset($attendee['VALUE']);
385
386 $content['ATTENDEE'][] = [
387 'PARAMETERS' => $attendee,
388 'VALUE' => $value,
389 ];
390 }
391 }
392
393 if ($data['ATTACH'])
394 {
395 foreach ($data['ATTACH'] as $attachment)
396 {
397 $value = $attachment['VALUE'];
398 unset($attachment['VALUE']);
399
400 $content['ATTACH'][] = [
401 'PARAMETERS' => $attachment,
402 'VALUE' => $value,
403 ];
404 }
405 }
406
407 if ($data['ORGANIZER'])
408 {
409 $value = $data['ORGANIZER']['VALUE'];
410 unset($data['ORGANIZER']['VALUE']);
411
412 $content['ORGANIZER'] = [
413 'PARAMETERS' => $data['ORGANIZER'],
414 'VALUE' => $value,
415 ];
416 }
417
418 if ($data['URL'])
419 {
420 $content['URL'] = $data['URL'];
421 }
422 }
423}
getContent(Event $event, ?array $data=null)
static minutesToDayHoursMinutes(int $minutes)
Definition util.php:677