1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
calendar_restservice.php
См. документацию.
1<?php
2
3if(!\Bitrix\Main\Loader::includeModule('rest') || !\Bitrix\Main\Loader::includeModule('calendar'))
4{
5 return;
6}
7
18
19IncludeModuleLangFile(__FILE__);
27{
28 const SCOPE_NAME = 'calendar';
29 const PLACEMENT_GRID_VIEW = 'CALENDAR_GRIDVIEW';
30
31 public static function OnRestServiceBuildDescription()
32 {
33 $methods = [
34 //Methods list
35 "calendar.event.get" => [__CLASS__, "EventGet"],
36 "calendar.event.add" => [__CLASS__, "EventAdd"],
37 "calendar.event.update" => [__CLASS__, "EventUpdate"],
38 "calendar.event.delete" => [__CLASS__, "EventDelete"],
39 "calendar.event.get.nearest" => [__CLASS__, "EventGetNearest"],
40 "calendar.event.getbyid" => [__CLASS__, "EventGetById"],
41
42 "calendar.section.get" => [__CLASS__, "SectionGet"],
43 "calendar.section.add" => [__CLASS__, "SectionAdd"],
44 "calendar.section.update" => [__CLASS__, "SectionUpdate"],
45 "calendar.section.delete" => [__CLASS__, "SectionDelete"],
46
47 "calendar.resource.list" => [__CLASS__, "ResourceList"],
48 "calendar.resource.add" => [__CLASS__, "ResourceAdd"],
49 "calendar.resource.update" => [__CLASS__, "ResourceUpdate"],
50 "calendar.resource.delete" => [__CLASS__, "ResourceDelete"],
51
52 "calendar.resource.booking.list" => [__CLASS__, "ResourceBookingList"],
53// "calendar.resource.booking.add" => [__CLASS__, "ResourceBookingAdd"],
54// "calendar.resource.booking.update" => [__CLASS__, "ResourceBookingUpdate"],
55// "calendar.resource.booking.delete" => [__CLASS__, "ResourceBookingDelete"],
56
57 "calendar.meeting.status.set" => [__CLASS__, "MeetingStatusSet"],
58 "calendar.meeting.params.set" => [__CLASS__, "MeetingParamsSet"],
59 "calendar.meeting.status.get" => [__CLASS__, "MeetingStatusGet"],
60 "calendar.accessibility.get" => [__CLASS__, "MeetingAccessibilityGet"],
61 "calendar.settings.get" => [__CLASS__, "SettingsGet"],
62 "calendar.user.settings.get" => [__CLASS__, "UserSettingsGet"],
63 "calendar.user.settings.set" => [__CLASS__, "UserSettingsSet"],
64 // End methods list
65
66 //Placements list
67 \CRestUtil::PLACEMENTS => [
68 self::PLACEMENT_GRID_VIEW => []
69 ],
70 //End placements list
71
72 // Events
73 \CRestUtil::EVENTS => [
74 'OnCalendarEntryAdd' => [
75 'calendar',
76 'OnAfterCalendarEntryAdd',
77 [__CLASS__, 'PrepareOnCalendarEntryEvent'],
78 [
79 'sendRefreshToken' => true,
80 ]
81 ],
82 'OnCalendarEntryUpdate' => [
83 'calendar',
84 'OnAfterCalendarEntryUpdate',
85 [__CLASS__, 'PrepareOnCalendarEntryEvent'],
86 [
87 'sendRefreshToken' => true,
88 ]
89 ],
90 'OnCalendarEntryDelete' => [
91 'calendar',
92 'OnAfterCalendarEventDelete',
93 [__CLASS__, 'PrepareOnCalendarEntryEvent'],
94 [
95 'sendRefreshToken' => true,
96 ]
97 ],
98 'OnCalendarSectionAdd' => [
99 'calendar',
100 'OnAfterCalendarSectionAdd',
101 [__CLASS__, 'PrepareOnCalendarSectionEvent'],
102 [
103 'sendRefreshToken' => true,
104 ]
105 ],
106 'OnCalendarSectionUpdate' => [
107 'calendar',
108 'OnAfterCalendarSectionUpdate',
109 [__CLASS__, 'PrepareOnCalendarSectionEvent'],
110 [
111 'sendRefreshToken' => true,
112 ]
113 ],
114 'OnCalendarSectionDelete' => [
115 'calendar',
116 'OnAfterCalendarSectionDelete',
117 [__CLASS__, 'PrepareOnCalendarSectionEvent'],
118 [
119 'sendRefreshToken' => true,
120 ]
121 ],
122 'OnCalendarRoomCreate' => [
123 'calendar',
124 'OnAfterCalendarRoomCreate',
125 [__CLASS__, 'PrepareOnCalendarRoomEvent'],
126 [
127 'sendRefreshToken' => true,
128 ]
129 ],
130 'OnCalendarRoomUpdate' => [
131 'calendar',
132 'OnAfterCalendarRoomUpdate',
133 [__CLASS__, 'PrepareOnCalendarRoomEvent'],
134 [
135 'sendRefreshToken' => true,
136 ]
137 ],
138 'OnCalendarRoomDelete' => [
139 'calendar',
140 'OnAfterCalendarRoomDelete',
141 [__CLASS__, 'PrepareOnCalendarRoomEvent'],
142 [
143 'sendRefreshToken' => true,
144 ]
145 ],
146 ]
147 ];
148
149 return [self::SCOPE_NAME => $methods];
150 }
151
152 /*
153 * Returns array of events
154 *
155 * @param array $params - incomoning params:
156 * $params['type'] - (required) calendar type ('user'|'group')
157 * $params['ownerId'] - owner id
158 * $params['from'] - datetime, "from" limit, default value - 1 month before current date
159 * $params['to'] - datetime, "to" limit, default value - 3 month after current date
160 * $params['section'] - inline or array of sections
161 * @return array of events
162 * @throws \Bitrix\Rest\RestException
163 *
164 * @example (Javascript)
165 * BX24.callMethod("calendar.event.get",
166 * {
167 * type: 'user',
168 * ownerId: '1',
169 * from: '2013-06-20',
170 * to: '2013-08-20',
171 * section: [21, 44]
172 * });
173 *
174 */
175 public static function EventGet($params = [], $nav = null, $server = null)
176 {
177 $userId = CCalendar::GetCurUserId();
178 $methodName = "calendar.event.get";
179
180 $necessaryParams = ['type'];
181 foreach ($necessaryParams as $param)
182 {
183 if (empty($params[$param]))
184 {
185 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
186 '#PARAM_NAME#' => $param,
187 '#REST_METHOD#' => $methodName
188 ]));
189 }
190 }
191
192 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
193 {
194 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
195 }
196
197 $type = $params['type'];
198 $ownerId = (int)$params['ownerId'];
199 $from = false;
200 $to = false;
201
202 if (isset($params['from']))
203 {
204 $from = CRestUtil::unConvertDateTime($params['from']);
205 }
206 if (isset($params['to']))
207 {
208 $to = CRestUtil::unConvertDateTime($params['to']);
209 }
210
211 // Default values for from-to period
212 if ($from === false && $to === false)
213 {
214 // Limits
215 $ts = time();
216 $pastDays = 30;
217 $futureDays = 90;
218 $from = CCalendar::Date($ts - CCalendar::DAY_LENGTH * $pastDays, false);
219 $to = CCalendar::Date($ts + CCalendar::DAY_LENGTH * $futureDays, false);
220 }
221 elseif ($from !== false && $to === false)
222 {
223 $to = CCalendar::Date(CCalendar::GetMaxTimestamp(), false);
224 }
225
226 $arSectionIds = [];
227
228 $sections = CCalendarSect::GetList([
229 'arFilter' => [
230 'CAL_TYPE' => $type,
231 'OWNER_ID' => $ownerId
232 ]
233 ]);
234 foreach ($sections as $section)
235 {
236 if ($section['PERM']['view_full'] || $section['PERM']['view_title'] || $section['PERM']['view_time'])
237 {
238 $arSectionIds[] = (int)$section['ID'];
239 }
240 }
241
242 if (isset($params['section']))
243 {
244 if (!is_array($params['section']) && (int)$params['section'] > 0)
245 {
246 $params['section'] = [(int)$params['section']];
247 }
248
249 if (is_array($params['section']))
250 {
251 $preparedSections = array_unique(array_map(fn($section) => (int)$section, $params['section']));
252
253 $arSectionIds = array_intersect($arSectionIds, $preparedSections);
254 }
255 }
256
257 $params = [
258 'type' => $type,
259 'ownerId' => $ownerId,
260 'userId' => $userId,
261 'section' => $arSectionIds,
262 'fromLimit' => $from,
263 'toLimit' => $to,
264 ];
265
266 $arAttendees = [];
267
268 return CCalendar::GetEventList($params, $arAttendees);
269 }
270
274 private static function isDateStringContainsTimezone(string $dateString): bool
275 {
276 // Checking of timeshift in ISO 8601 format
277 if (preg_match('/([+-]\d{2}:\d{2}|[+-]\d{4}|Z)$/', $dateString))
278 {
279 return true;
280 }
281
282 // Checking timezone name (example: Europe/Moscow)
283 if (preg_match('/[A-Za-z_]+\/[A-Za-z_]+/', $dateString))
284 {
285 return true;
286 }
287
288 return false;
289 }
290
291 /*
292 * Returns event by it id
293 *
294 * @param array $params - incomoning params:
295 * $params['id'] - int, (required) calendar event id
296 * @return event or null
297 * @throws \Bitrix\Rest\RestException
298 *
299 * @example (Javascript)
300 * BX24.callMethod("calendar.event.getbyid",
301 * {
302 * id: 324
303 * });
304 *
305 */
306 public static function EventGetById($params = [], $nav = null, $server = null)
307 {
308 $methodName = "calendar.event.getbyid";
309
310 if (empty($params['id']))
311 {
312 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
313 '#PARAM_NAME#' => 'id',
314 '#REST_METHOD#' => $methodName
315 ]));
316 }
317
318 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
319 {
320 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
321 }
322
323 $event = CCalendarEvent::GetById($params['id']);
324 unset($event['ACTIVE'], $event['DT_FROM'], $event['DT_TO'], $event['TEXT_COLOR']);
325
326 return $event ?: null;
327 }
328
329 /*
330 * Add new event
331 *
332 * @param array $params - incoming params:
333 * $params['type'] - (required), number, calendar type
334 * $params['ownerId'] - (required), number, owner id
335 * $params['from'] - (required) datetime, "from" limit
336 * $params['to'] - (required) datetime, "to" limit
337 * $params['timezone_from'] - string, timezone, default value - timezone of current user
338 * $params['timezone_to'] - string, timezone, default value - timezone of current user
339 * $params['from_ts'] - timestamp, "from" limit, can be set instead of $params['from']
340 * $params['to_ts'] - timestamp, "to" limit, can be set instead of $params['to']
341 * $params['section'] - (required if $params['auto_detect_section'] is not "Y"), number, id of the section
342 * $params['auto_detect_section'] - "Y" | "N", if "Y" $params['section'] could be skipped
343 * $params['name'] - (required), string, name of the event
344 * $params['skip_time'] - "Y"|"N",
345 * $params['description'] - string, description of the event
346 * $params['color'] - background color of the event
347 * $params['text_color'] - text color of the event
348 * $params['accessibility'] - 'busy'|'quest'|'free'|'absent' - accessibility for user
349 * $params['importance'] - 'high' | 'normal' | 'low' - importance for the event
350 * $params['private_event'] - "Y" | "N"
351 * $params['rrule'] - array of the recurrence Rule
352 * $params['is_meeting'] - "Y" | "N"
353 * $params['location'] - location
354 * $params['remind'] - array(
355 * array(
356 * 'type' => 'min'|'hour'|'day', type of reminder
357 * 'count' => count of time
358 * )
359 * ) - reminders
360 * $params['attendees'] - array of the attendees for meeting if ($params['is_meeting'] == "Y")
361 * $params['host'] - host of the event
362 * $params['crm_fields'] - array(
363 * `CO_#ID#` — company
364 * `C_#ID#` — contact
365 * `L_#ID#` — lead
366 * `D_#ID#` — deal
367 * )
368 * $params['meeting'] = array(
369 'text' => inviting text,
370 'open' => true|false if meeting is open,
371 'notify' => true|false,
372 'reinvite' => true|false
373 )
374 * @return id of the new event.
375 * @throws \Bitrix\Rest\RestException
376 *
377 * @example (Javascript)
378 * BX24.callMethod("calendar.event.add",
379 * {
380 * type: 'user',
381 * ownerId: '2',
382 * name: 'New Event Name',
383 * description: 'Description for event',
384 * from: '2013-06-14',
385 * to: '2013-06-14',
386 * skip_time: 'Y',
387 * section: 5,
388 * color: '#9cbe1c',
389 * text_color: '#283033',
390 * accessibility: 'absent',
391 * importance: 'normal',
392 * is_meeting: 'Y',
393 * private_event: 'N',
394 * remind: [{type: 'min', count: 20}],
395 * location: 'Kaliningrad',
396 * attendees: [1, 2, 3],
397 * host: 2,
398 * meeting: {
399 * text: 'inviting text',
400 * open: true,
401 * notify: true,
402 * reinvite: false
403 * }
404 * });
405 */
406 public static function EventAdd($params = [], $nav = null, $server = null)
407 {
408 $userId = CCalendar::GetCurUserId();
409 $methodName = "calendar.event.add";
410
411 $skipTime = false;
412
413 if (isset($params['skip_time']))
414 {
415 $skipTime = $params['skip_time'] === 'Y';
416 }
417
418 if (isset($params['skipTime']))
419 {
420 $skipTime = $params['skipTime'] === 'Y';
421 }
422
423 if ($skipTime)
424 {
425 unset($params['timezone_from']);
426 unset($params['timezone_to']);
427 }
428
429 if (isset($params['from']))
430 {
431 $enableOffset = true;
432
433 if (!$skipTime)
434 {
435 if (self::isDateStringContainsTimezone($params['from']))
436 {
437 unset($params['timezone_from']);
438 }
439 // If the user directly set timezone or set date without timezone (example: 2025-08-05 10:00:00)
440 else
441 {
442 $enableOffset = false;
443 }
444 }
445
446 $params['from'] = CRestUtil::unConvertDateTime($params['from'], $enableOffset);
447 }
448
449 if (isset($params['to']))
450 {
451 $enableOffset = true;
452
453 if (!$skipTime)
454 {
455 if (self::isDateStringContainsTimezone($params['to']))
456 {
457 unset($params['timezone_to']);
458 }
459 // If the user directly set timezone or set date without timezone (example: 2025-08-05 10:00:00)
460 else
461 {
462 $enableOffset = false;
463 }
464 }
465
466 $params['to'] = CRestUtil::unConvertDateTime($params['to'], $enableOffset);
467 }
468
469 if (isset($params['from_ts']) && !isset($params['from']))
470 {
471 $params['from'] = CCalendar::Date($params['from_ts']);
472 }
473
474 if (isset($params['to_ts']) && !isset($params['to']))
475 {
476 $params['to'] = CCalendar::Date($params['to_ts']);
477 }
478
479 $necessaryParams = [
480 'from',
481 'to',
482 'name',
483 'ownerId',
484 'type'
485 ];
486
487 if (isset($params['auto_detect_section']) && $params['auto_detect_section'] !== "Y")
488 {
489 $necessaryParams[] = 'section';
490 }
491
492 foreach ($necessaryParams as $param)
493 {
494 if (empty($params[$param]))
495 {
496 if ($param === 'ownerId' && isset($params[$param]))
497 {
498 continue;
499 }
500
501 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
502 '#PARAM_NAME#' => $param,
503 '#REST_METHOD#' => $methodName
504 ]));
505 }
506 }
507
508 if (!is_string($params['name']))
509 {
510 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
511 '#PARAM_NAME#' => 'name',
512 ]));
513 }
514
515 if (isset($params['description']) && !is_string($params['description']))
516 {
517 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
518 '#PARAM_NAME#' => 'description',
519 ]));
520 }
521
522 $type = $params['type'];
523 $ownerId = (int)$params['ownerId'];
524 $sectionId = (int)($params['section'] ?? null);
525
526 if ($sectionId > 0)
527 {
528 $res = CCalendarSect::GetList([
529 'arFilter' => [
530 'ID' => $sectionId,
531 'CAL_TYPE' => $type,
532 'OWNER_ID' => $ownerId,
533 ]
534 ]);
535
536 if ($res && is_array($res) && isset($res[0]))
537 {
538 if (!$res[0]['PERM']['edit'])
539 {
540 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
541 }
542 }
543 else
544 {
545 throw new RestException(Loc::getMessage('CAL_REST_SECTION_ERROR'));
546 }
547 }
548
549 $arFields = [
550 "CAL_TYPE" => $type,
551 "OWNER_ID" => $ownerId,
552 "NAME" => trim($params['name']),
553 "DATE_FROM" => $params['from'],
554 "DATE_TO" => $params['to'],
555 "SECTIONS" => $sectionId,
556 'SKIP_TIME' => $skipTime,
557 ];
558
559 if (!$arFields['SKIP_TIME'])
560 {
561 $arFields = self::processTimezone($params, $arFields);
562 }
563
564 if (isset($params['description']))
565 {
566 $arFields["DESCRIPTION"] = trim($params['description']);
567 }
568
569 if (isset($params['color']))
570 {
571 $color = CCalendar::Color($params['color']);
572 if ($color)
573 {
574 $arFields["COLOR"] = $color;
575 }
576 }
577
578 if (isset($params['text_color']))
579 {
580 $color = CCalendar::Color($params['text_color']);
581 if ($color)
582 {
583 $arFields["TEXT_COLOR"] = $color;
584 }
585 }
586
587 if (isset($params['accessibility']))
588 {
589 $arFields["ACCESSIBILITY"] = $params['accessibility'];
590 }
591
592 if (isset($params['importance']))
593 {
594 $arFields["IMPORTANCE"] = $params['importance'];
595 }
596
597 if (isset($params['private_event']))
598 {
599 $arFields["PRIVATE_EVENT"] = $params['private_event'] === 'Y';
600 }
601
602 if (isset($params['rrule']))
603 {
604 $arFields["RRULE"] = $params['rrule'];
605 }
606
607 if (isset($arFields['RRULE']['UNTIL']))
608 {
609 $arFields['RRULE']['UNTIL'] = CRestUtil::unConvertDate($arFields['RRULE']['UNTIL']);
610 }
611
612 if (isset($params['is_meeting']))
613 {
614 $arFields["IS_MEETING"] = $params['is_meeting'] === 'Y';
615 }
616
617 if (isset($params['location']))
618 {
619 $arFields["LOCATION"] = $params['location'];
620 }
621
622 if (isset($params['remind']))
623 {
624 $arFields["REMIND"] = $params['remind'];
625 }
626
627 $saveParams = [];
628
629 $defaultAttendeeId = !empty($ownerId) ? $ownerId : $userId;
630 if (!empty($arFields['IS_MEETING']))
631 {
632 $requestAttendees = (isset($params['attendees']) && is_array($params['attendees']))
633 ? array_map('intval', $params['attendees'])
634 : []
635 ;
636 // set creator as attendee if no presented
637 $arFields['ATTENDEES'] = $requestAttendees ?: [$defaultAttendeeId];
638 $arFields['ATTENDEES_CODES'] = [];
639 if (is_array($arFields['ATTENDEES']))
640 {
641 foreach($arFields['ATTENDEES'] as $attendeeId)
642 {
643 $code = 'U'. (int)$attendeeId;
644 if (!in_array($code, $arFields['ATTENDEES_CODES'], true))
645 {
646 $arFields['ATTENDEES_CODES'][] = $code;
647 }
648 }
649 }
650
651 $meeting = $params['meeting'] ?? [];
652 $arFields['MEETING_HOST'] = isset($params['host']) ? (int)$params['host'] : $defaultAttendeeId;
653 $arFields['MEETING'] = [
654 'HOST_NAME' => CCalendar::GetUserName($arFields['MEETING_HOST']),
655 'NOTIFY' => (bool)($meeting['notify'] ?? false),
656 'REINVITE' => (bool)($meeting['reinvite'] ?? false),
657 'ALLOW_INVITE' => (bool)($meeting['allow_invite'] ?? false),
658 'HIDE_GUESTS' => (bool)($meeting['hide_guests'] ?? false),
659 'MEETING_CREATOR' => $arFields['MEETING_HOST'],
660 'LANGUAGE_ID' => CCalendar::getUserLanguageId($defaultAttendeeId),
661 ];
662
663 $saveParams['userId'] = $arFields['MEETING_HOST'];
664 }
665
666 if (empty($arFields['ATTENDEES']))
667 {
668 $arFields['ATTENDEES'] = [$defaultAttendeeId];
669 $arFields['ATTENDEES_CODES'] = ['U' . $defaultAttendeeId];
670 $arFields['MEETING_HOST'] = $defaultAttendeeId;
671 $arFields['MEETING_STATUS'] = 'H';
672 $arFields['MEETING'] = [
673 'NOTIFY' => false,
674 'MEETING_CREATOR' => $arFields['MEETING_HOST'],
675 'REINVITE' => false,
676 'ALLOW_INVITE' => false,
677 'HIDE_GUESTS' => false,
678 'HOST_NAME' => CCalendar::GetUserName($arFields['MEETING_HOST']),
679 'LANGUAGE_ID' => CCalendar::getUserLanguageId($defaultAttendeeId),
680 ];
681 }
682
683 if (isset($params['crm_fields']))
684 {
685 $crmFields = $params['crm_fields'];
686 if (!is_array($crmFields) || !Loader::includeModule('crm'))
687 {
688 throw new RestException(Loc::getMessage('CAL_REST_CRM_FIELDS_ERROR'));
689 }
690
691 foreach ($crmFields as $field)
692 {
693 if (!is_string($field))
694 {
695 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
696 '#PARAM_NAME#' => 'crm_fields',
697 ]));
698 }
699
700 $elementTitle = CCalendarEvent::getCrmElementTitle($field);
701
702 if (empty($elementTitle))
703 {
704 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
705 '#PARAM_NAME#' => 'crm_fields',
706 ]));
707 }
708 }
709
710 $saveParams['UF'] = ['UF_CRM_CAL_EVENT' => $crmFields];
711 }
712
713 $saveParams['arFields'] = $arFields;
714 if (isset($params['auto_detect_section']) && $params['auto_detect_section'] === 'Y')
715 {
716 $saveParams['autoDetectSection'] = true;
717 $saveParams['autoCreateSection'] = true;
718 }
719
720 $newId = CCalendar::SaveEvent($saveParams);
721
722 if (!$newId)
723 {
724 throw new RestException(Loc::getMessage("CAL_REST_EVENT_NEW_ERROR"));
725 }
726
727 return (int)$newId;
728 }
729
730 /*
731 * Edit existent event
732 *
733 * @param array $params - incoming params:
734 * $params['id'] - (required) event id,
735 * $params['type'] - number, (required) calendar type
736 * $params['ownerId'] - number, owner id
737 * $params['from'] - datetime, "from" limit
738 * $params['to'] - datetime, "to" limit
739 * $params['timezone_from'] - string, timezone, default value - timezone of current user
740 * $params['timezone_to'] - string, timezone, default value - timezone of current user
741 * $params['from_ts'] - timestamp, "from" limit,
742 * $params['to_ts'] - timestamp, "to" limit
743 * $params['section'] - number,(required) id of the section
744 * $params['name'] - string, (required) name of the event
745 * $params['skip_time'] - "Y"|"N",
746 * $params['description'] - string, description of the event
747 * $params['color'] - background color of the event
748 * $params['text_color'] - text color of the event
749 * $params['accessibility'] - 'busy'|'quest'|'free'|'absent' - accessibility for user
750 * $params['importance'] - 'high' | 'normal' | 'low' - importance for the event
751 * $params['private_event'] - "Y" | "N"
752 * $params['rrule'] - array of the recurrence Rule
753 * $params['is_meeting'] - "Y" | "N"
754 * $params['location'] - location
755 * $params['remind'] - array(
756 * array(
757 * 'type' => 'min'|'hour'|'day', type of reminder
758 * 'count' => count of time
759 * )
760 * ) - reminders
761 * $params['attendees'] - array of the attendees for meeting if ($params['is_meeting'] == "Y")
762 * $params['host'] - host of the event
763 * $params['meeting'] = array(
764 * 'text' => inviting text,
765 * 'open' => true|false if meeting is open,
766 * 'notify' => true|false,
767 * 'reinvite' => true|false
768 * )
769 * * $params['crm_fields'] - array(
770 * `CO_#ID#` — company
771 * `C_#ID#` — contact
772 * `L_#ID#` — lead
773 * `D_#ID#` — deal
774 * )
775 * $params['recurrence_mode'] = 'this' | 'next' | 'all' to change recurrent event
776 * $params['current_date_from'] = date, required if recurrence_mode provided
777 * @return id of edited event
778 * @throws \Bitrix\Rest\RestException
779 *
780 * @example (Javascript)
781 * BX24.callMethod("calendar.event.update",
782 * {
783 * id: 699
784 * type: 'user',
785 * ownerId: '2',
786 * name: 'Changed Event Name',
787 * description: 'New description for event',
788 * from: '2013-06-17',
789 * to: '2013-06-17',
790 * skip_time: 'Y',
791 * section: 5,
792 * color: '#9cbe1c',
793 * text_color: '#283033',
794 * accessibility: 'free',
795 * importance: 'normal',
796 * is_meeting: 'N',
797 * private_event: 'Y',
798 * remind: [{type: 'min', count: 10}]
799 * });
800 */
801 public static function EventUpdate($params = [], $nav = null, $server = null)
802 {
803 $userId = CCalendar::GetCurUserId();
804 $methodName = "calendar.event.update";
805
806 $necessaryParams = [
807 'id',
808 'ownerId',
809 'type'
810 ];
811 foreach ($necessaryParams as $param)
812 {
813 if (empty($params[$param]))
814 {
815 if ($param === 'ownerId' && isset($params[$param]))
816 {
817 continue;
818 }
819
820 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
821 '#PARAM_NAME#' => $param,
822 '#REST_METHOD#' => $methodName
823 ]));
824 }
825 }
826
827 if (isset($params['name']) && !is_string($params['name']))
828 {
829 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
830 '#PARAM_NAME#' => 'name',
831 ]));
832 }
833
834 if (isset($params['description']) && !is_string($params['description']))
835 {
836 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
837 '#PARAM_NAME#' => 'description',
838 ]));
839 }
840
841 $id = (int)$params['id'];
842 $type = $params['type'];
843 $ownerId = (int)$params['ownerId'];
844
845 $skipTime = false;
846
847 if (isset($params['skip_time']))
848 {
849 $skipTime = $params['skip_time'] === 'Y';
850 }
851
852 if (isset($params['skipTime']))
853 {
854 $skipTime = $params['skipTime'] === 'Y';
855 }
856
857 if ($skipTime)
858 {
859 unset($params['timezone_from']);
860 unset($params['timezone_to']);
861 }
862
863 if (isset($params['from']))
864 {
865 $enableOffset = true;
866
867 if (!$skipTime)
868 {
869 if (self::isDateStringContainsTimezone($params['from']))
870 {
871 unset($params['timezone_from']);
872 }
873 // If the user directly set timezone or set date without timezone (example: 2025-08-05 10:00:00)
874 else
875 {
876 $enableOffset = false;
877 }
878 }
879
880 $params['from'] = CRestUtil::unConvertDateTime($params['from'], $enableOffset);
881 }
882
883 if (isset($params['to']))
884 {
885 $enableOffset = true;
886
887 if (!$skipTime)
888 {
889 if (self::isDateStringContainsTimezone($params['to']))
890 {
891 unset($params['timezone_to']);
892 }
893 // If the user directly set timezone or set date without timezone (example: 2025-08-05 10:00:00)
894 else
895 {
896 $enableOffset = false;
897 }
898 }
899
900 $params['to'] = CRestUtil::unConvertDateTime($params['to'], $enableOffset);
901 }
902
903 if (isset($params['from_ts']) && !isset($params['from']))
904 {
905 $params['from'] = CCalendar::Date($params['from_ts']);
906 }
907
908 if (isset($params['to_ts']) && !isset($params['to']))
909 {
910 $params['to'] = CCalendar::Date($params['to_ts']);
911 }
912
913 $arFields = [
914 "ID" => $id,
915 ];
916
917 if (isset($params['from']))
918 {
919 $arFields['DATE_FROM'] = $params['from'];
920 }
921
922 if (isset($params['to']))
923 {
924 $arFields['DATE_TO'] = $params['to'];
925 }
926
927 $arFields['SKIP_TIME'] = $skipTime;
928
929 if (!$arFields['SKIP_TIME'])
930 {
931 $arFields = self::processTimezone($params, $arFields);
932 }
933
934 if (isset($params['name']))
935 {
936 $arFields["NAME"] = trim($params['name']);
937 if (empty($arFields["NAME"]))
938 {
939 $arFields["NAME"] = Loc::getMessage('EC_T_NEW_EVENT');
940 }
941 }
942
943 if (isset($params['description']))
944 {
945 $arFields["DESCRIPTION"] = trim($params['description']);
946 }
947
948 if (isset($params['section']))
949 {
950 $sectionId = $params['section'];
951 $arFields["SECTIONS"] = [$sectionId];
952
953 $res = CCalendarSect::GetList([
954 'arFilter' => [
955 'ID' => $params['section'],
956 'CAL_TYPE' => $type,
957 'OWNER_ID' => $ownerId,
958 ]
959 ]);
960
961 if ($res && is_array($res) && isset($res[0]))
962 {
963 if (!$res[0]['PERM']['edit'])
964 {
965 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
966 }
967 }
968 else
969 {
970 throw new RestException(Loc::getMessage('CAL_REST_SECTION_ERROR'));
971 }
972 }
973
974 $saveParams = [];
975 if ($recurrenceMode = $params['recurrence_mode'] ?? null)
976 {
977 if (!in_array($recurrenceMode, ['this', 'next', 'all'], true))
978 {
979 throw new RestException(Loc::getMessage('CAL_REST_REC_MODE_ERROR'));
980 }
981
982 $saveParams['recursionEditMode'] = $recurrenceMode;
983 }
984
985 if (isset($params['current_date_from']))
986 {
987 $saveParams['currentEventDateFrom'] = CRestUtil::unConvertDate($params['current_date_from']);
988 }
989
990 if (
991 empty($saveParams['currentEventDateFrom'])
992 && !empty($saveParams['recursionEditMode'])
993 && in_array($saveParams['recursionEditMode'], ['this', 'next'], true)
994 )
995 {
996 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
997 '#PARAM_NAME#' => 'current_date_from',
998 ]));
999 }
1000
1001 if (isset($params['color']))
1002 {
1003 $color = CCalendar::Color($params['color']);
1004 if ($color)
1005 {
1006 $arFields["COLOR"] = $color;
1007 }
1008 }
1009
1010 if (isset($params['text_color']))
1011 {
1012 $color = CCalendar::Color($params['text_color']);
1013 if ($color)
1014 {
1015 $arFields["TEXT_COLOR"] = $color;
1016 }
1017 }
1018
1019 if (isset($params['accessibility']))
1020 {
1021 $arFields["ACCESSIBILITY"] = $params['accessibility'];
1022 }
1023
1024 if (isset($params['importance']))
1025 {
1026 $arFields["IMPORTANCE"] = $params['importance'];
1027 }
1028
1029 if (isset($params['private_event']))
1030 {
1031 $arFields["PRIVATE_EVENT"] = $params['private_event'] === "Y";
1032 }
1033
1034 if (isset($params['rrule']))
1035 {
1036 $arFields["RRULE"] = $params['rrule'];
1037 }
1038
1039 if (isset($arFields['RRULE']['UNTIL']))
1040 {
1041 $arFields['RRULE']['UNTIL'] = CRestUtil::unConvertDate($arFields['RRULE']['UNTIL']);
1042 }
1043
1044 if (isset($params['is_meeting']))
1045 {
1046 $arFields["IS_MEETING"] = $params['is_meeting'] === "Y";
1047 }
1048
1049 if (isset($params['location']))
1050 {
1051 $arFields["LOCATION"] = $params['location'];
1052 }
1053
1054 if (isset($params['remind']))
1055 {
1056 $arFields["REMIND"] = $params['remind'];
1057 }
1058
1059 if (!empty($arFields['IS_MEETING']))
1060 {
1061 $arFields['ATTENDEES'] = (isset($params['attendees']) && is_array($params['attendees'])) ? $params['attendees'] : false;
1062 $arFields['ATTENDEES_CODES'] = [];
1063 if (is_array($arFields['ATTENDEES']))
1064 {
1065 foreach($arFields['ATTENDEES'] as $attendeeId)
1066 {
1067 $code = 'U'. (int)$attendeeId;
1068 if (!in_array($code, $arFields['ATTENDEES_CODES'], true))
1069 {
1070 $arFields['ATTENDEES_CODES'][] = $code;
1071 }
1072 }
1073 }
1074
1075 $meeting = $params['meeting'] ?? [];
1076 $arFields['MEETING_HOST'] = isset($params['host']) ? (int)$params['host'] : $userId;
1077 $arFields['MEETING'] = [
1078 'HOST_NAME' => CCalendar::GetUserName($arFields['MEETING_HOST']),
1079 'NOTIFY' => (bool)($meeting['notify'] ?? false),
1080 'REINVITE' => (bool)($meeting['reinvite'] ?? false),
1081 'ALLOW_INVITE' => (bool)($meeting['allow_invite'] ?? false),
1082 'HIDE_GUESTS' => (bool)($meeting['hide_guests'] ?? false),
1083 'MEETING_CREATOR' => $arFields['MEETING_HOST'],
1084 'LANGUAGE_ID' => CCalendar::getUserLanguageId($userId),
1085 ];
1086
1087 $saveParams['userId'] = $arFields['MEETING_HOST'];
1088 }
1089
1090 if (
1091 empty($arFields['ATTENDEES'])
1092 && !empty($saveParams['currentEventDateFrom'])
1093 )
1094 {
1095 $event = CCalendar::getCurrentEventForSaving($id, $userId, true);
1096 if ($event)
1097 {
1098 $arFields['ATTENDEES'] = [];
1099 foreach ($event['ATTENDEE_LIST'] as $attendee)
1100 {
1101 $arFields['ATTENDEES'][] = $attendee['id'];
1102 }
1103
1104 $arFields['ATTENDEES_CODES'] = $event['ATTENDEES_CODES'];
1105 }
1106 }
1107
1108 if (isset($params['crm_fields']))
1109 {
1110 $crmFields = $params['crm_fields'];
1111 if (!is_array($crmFields) || !Loader::includeModule('crm'))
1112 {
1113 throw new RestException(Loc::getMessage('CAL_REST_CRM_FIELDS_ERROR'));
1114 }
1115
1116 foreach ($crmFields as $field)
1117 {
1118 if (!is_string($field))
1119 {
1120 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
1121 '#PARAM_NAME#' => 'crm_fields',
1122 ]));
1123 }
1124
1125 $elementTitle = CCalendarEvent::getCrmElementTitle($field);
1126
1127 if (empty($elementTitle))
1128 {
1129 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
1130 '#PARAM_NAME#' => 'crm_fields',
1131 ]));
1132 }
1133 }
1134
1135 if (empty($crmFields))
1136 {
1137 $crmFields[] = '';
1138 }
1139
1140 $saveParams['UF'] = ['UF_CRM_CAL_EVENT' => $crmFields];
1141 }
1142
1143 $saveParams['arFields'] = $arFields;
1144 $newId = CCalendar::SaveEvent($saveParams);
1145
1146 if (!$newId)
1147 {
1148 throw new RestException(Loc::getMessage("CAL_REST_EVENT_UPDATE_ERROR"));
1149 }
1150
1151 return $newId;
1152 }
1153
1154 /*
1155 * Delete event
1156 *
1157 * @param array $params - incomoning params:
1158 * $params['type'] (required) calendar type
1159 * $params['ownerId'] (required) owner id
1160 * $params['id'] (required) event id
1161 * @return true if everything ok
1162 * @throws \Bitrix\Rest\RestException
1163 *
1164 * @example (Javascript)
1165 * BX24.callMethod("calendar.event.delete",
1166 * {
1167 * id: 698
1168 * type: 'user',
1169 * ownerId: '2'
1170 * });
1171 */
1172 public static function EventDelete($params = [], $nav = null, $server = null)
1173 {
1174 if (isset($params['id']) && (int)$params['id'] > 0)
1175 {
1176 $id = (int)$params['id'];
1177 }
1178 else
1179 {
1180 throw new RestException(Loc::getMessage('CAL_REST_EVENT_ID_EXCEPTION'));
1181 }
1182
1183 $res = CCalendar::DeleteEvent($id);
1184
1185 if ($res !== true)
1186 {
1187 throw new RestException(Loc::getMessage('CAL_REST_EVENT_DELETE_ERROR'));
1188 }
1189
1190 return $res;
1191 }
1192
1193 /*
1194 * Return array of bearest events for current user
1195 *
1196 * @param array $params - incomoning params:
1197 * $params['ownerId'] - owner id
1198 * $params['type'] - calendar type
1199 * $params['days'] - future days count (default - 60)
1200 * $params['forCurrentUser'] - true/false - list of nearest events for current user
1201 * $params['maxEventsCount'] - maximum events count
1202 * $params['detailUrl'] - url for calendar
1203 *
1204 * @return array of events
1205 *
1206 * @throws \Bitrix\Rest\RestException
1207 *
1208 * @example (Javascript)
1209 * BX24.callMethod("calendar.event.get.nearest",
1210 * {
1211 * type: 'user',
1212 * ownerId: '2',
1213 * days: 10,
1214 * forCurrentUser: true,
1215 * detailUrl: '/company/personal/user/#user_id#/calendar/'
1216 * });
1217 *
1218 */
1219 public static function EventGetNearest($params = [], $nav = null, $server = null)
1220 {
1221 $userId = CCalendar::GetCurUserId();
1222
1223 if (!isset($params['type'], $params['ownerId']) || !empty($params['forCurrentUser']))
1224 {
1225 $params['type'] = 'user';
1226 $params['ownerId'] = $userId;
1227 $params['forCurrentUser'] = true;
1228 }
1229
1230 if (!isset($params['days']))
1231 {
1232 $params['days'] = 60;
1233 }
1234
1235 // Limits
1236 $ts = time();
1237 $fromLimit = CCalendar::Date($ts, false);
1238 $toLimit = CCalendar::Date($ts + CCalendar::DAY_LENGTH * $params['days'], false);
1239
1240 $arEvents = CCalendar::GetNearestEventsList([
1241 'bCurUserList' => (bool)($params['forCurrentUser'] ?? true),
1242 'fromLimit' => $fromLimit,
1243 'toLimit' => $toLimit,
1244 'type' => $params['type'],
1245 'fromRest' => true,
1246 ]);
1247
1248 if ($arEvents === 'access_denied' || $arEvents === 'inactive_feature')
1249 {
1250 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
1251 }
1252
1253 if (is_array($arEvents))
1254 {
1255 if (isset($params['detailUrl']))
1256 {
1257 if (str_contains($params['detailUrl'], '?'))
1258 {
1259 $params['detailUrl'] = mb_substr($params['detailUrl'], 0, mb_strpos($params['detailUrl'], '?'));
1260 }
1261 $params['detailUrl'] = str_replace('#user_id#', $userId, mb_strtolower($params['detailUrl']));
1262
1263 foreach ($arEvents as $i => $event)
1264 {
1265 $arEvents[$i]['~detailUrl'] = CHTTP::urlAddParams($params['detailUrl'], ['EVENT_ID' => $event['ID'], 'EVENT_DATE' => $event['DATE_FROM']]);
1266 }
1267 }
1268
1269 if (isset($params['maxEventsCount']))
1270 {
1271 array_splice($arEvents, (int)$params['maxEventsCount']);
1272 }
1273 }
1274
1275 return $arEvents;
1276 }
1277
1278 /*
1279 * Return list of sections
1280 *
1281 * @param array $params - incomoning params:
1282 * $params['type'] (required) calendar type
1283 * $params['ownerId'] (required) owner id
1284 *
1285 * @return array of sections
1286 *
1287 * @throws \Bitrix\Rest\RestException
1288 *
1289 * @example (Javascript)
1290 * BX24.callMethod("calendar.section.get",
1291 * {
1292 * type: 'user',
1293 * ownerId: '1'
1294 * });
1295 */
1296 public static function SectionGet($params = [], $nav = null, $server = null)
1297 {
1298 $userId = CCalendar::GetCurUserId();
1299 $methodName = "calendar.section.get";
1300
1301 if (isset($params['type']))
1302 {
1303 $type = $params['type'];
1304 }
1305 else
1306 {
1307 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#REST_METHOD#' => $methodName, '#PARAM_NAME#' => 'type')));
1308 }
1309
1310 if (isset($params['ownerId']))
1311 {
1312 $ownerId = (int)$params['ownerId'];
1313 }
1314 elseif($type === 'user')
1315 {
1316 $ownerId = $userId;
1317 }
1318 else
1319 {
1320 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#REST_METHOD#' => $methodName, '#PARAM_NAME#' => 'ownerId')));
1321 }
1322
1323 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
1324 {
1325 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
1326 }
1327
1328 $arFilter = [
1329 'CAL_TYPE' => $type,
1330 'OWNER_ID' => $ownerId,
1331 'ACTIVE' => "Y"
1332 ];
1333
1334 $res = CCalendarSect::GetList(array('arFilter' => $arFilter));
1335
1336 foreach($res as $i => $section)
1337 {
1338 unset(
1339 $res[$i]['OUTLOOK_JS'],
1340 $res[$i]['DAV_EXCH_CAL'],
1341 $res[$i]['DAV_EXCH_MOD'],
1342 $res[$i]['SORT'],
1343 $res[$i]['PARENT_ID'],
1344 $res[$i]['IS_EXCHANGE'],
1345 $res[$i]['EXTERNAL_ID'],
1346 $res[$i]['ACTIVE'],
1347 $res[$i]['CAL_DAV_MOD'],
1348 $res[$i]['CAL_DAV_CAL'],
1349 $res[$i]['XML_ID']
1350 );
1351
1352 if (!empty($res[$i]['DATE_CREATE']) && is_string($res[$i]['DATE_CREATE']))
1353 {
1354 $res[$i]['DATE_CREATE'] = self::formatOld($res[$i]['DATE_CREATE']);
1355 }
1356
1357 if (!empty($res[$i]['TIMESTAMP_X']) && is_string($res[$i]['TIMESTAMP_X']))
1358 {
1359 $res[$i]['TIMESTAMP_X'] = self::formatOld($res[$i]['TIMESTAMP_X']);
1360 }
1361 }
1362
1363 return $res;
1364 }
1365
1370 private static function formatOld(string $value): string
1371 {
1372 try
1373 {
1374 $value = (new \Bitrix\Main\Type\DateTime($value))->format('Y-m-d H:i:s');
1375 }
1376 catch (\Bitrix\Main\ObjectException $e) {}
1377
1378 return $value;
1379 }
1380
1381 /*
1382 * Add new section
1383 *
1384 * @param array $params - incomoning params:
1385 * $params['type'] - (required), number, calendar type
1386 * $params['ownerId'] - (required), number, owner id
1387 * $params['name'] - string, (required) name of the section
1388 * $params['description'] - string, description of the section
1389 * $params['color']
1390 * $params['text_color']
1391 * $params['export'] = array(
1392 'ALLOW' => true|false,
1393 'SET' => array
1394 )
1395 * $params['access'] - array of access data
1396 *
1397 * @return id of created section
1398 *
1399 * @throws \Bitrix\Rest\RestException
1400 *
1401 * @example (Javascript)
1402 * BX24.callMethod("calendar.section.add",
1403 * {
1404 * type: 'user',
1405 * ownerId: '2',
1406 * name: 'New Section',
1407 * description: 'Description for section',
1408 * color: '#9cbeee',
1409 * text_color: '#283000',
1410 * export: [{ALLOW: false}]
1411 * access: {
1412 * 'D114': 17,
1413 * 'G2': 13,
1414 * 'U2':15
1415 * }
1416 * });
1417 */
1418 public static function SectionAdd($params = [], $nav = null, $server = null)
1419 {
1420 $userId = CCalendar::GetCurUserId();
1421 $methodName = "calendar.section.add";
1422 $DEFAULT_COLOR = '#E6A469';
1423 $DEFAULT_TEXT_COLOR = '#000000';
1424
1425 if (isset($params['type']))
1426 {
1427 $type = $params['type'];
1428 }
1429 else
1430 {
1431 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
1432 '#REST_METHOD#' => $methodName,
1433 '#PARAM_NAME#' => 'type'
1434 ]));
1435 }
1436
1437 if (isset($params['ownerId']))
1438 {
1439 $ownerId = (int)$params['ownerId'];
1440 }
1441 elseif ($type === 'user')
1442 {
1443 $ownerId = $userId;
1444 }
1445 else
1446 {
1447 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
1448 '#REST_METHOD#' => $methodName,
1449 '#PARAM_NAME#' => 'ownerId'
1450 ]));
1451 }
1452
1453 if (!is_string($params['name']))
1454 {
1455 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
1456 '#PARAM_NAME#' => 'name',
1457 ]));
1458 }
1459
1460 if (isset($params['description']) && !is_string($params['description']))
1461 {
1462 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
1463 '#PARAM_NAME#' => 'description',
1464 ]));
1465 }
1466
1468 $sectionModel = SectionModel::createNew()
1469 ->setType($type)
1470 ->setOwnerId($userId)
1471 ;
1472
1473 if (!$accessController->check(ActionDictionary::ACTION_SECTION_ADD, $sectionModel))
1474 {
1475 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
1476 }
1477
1478 $arFields = [
1479 'CAL_TYPE' => $type,
1480 'OWNER_ID' => $ownerId,
1481 'NAME' => !empty($params['name']) ? trim($params['name']) : '',
1482 'DESCRIPTION' => !empty($params['description']) ? trim($params['description']) : ''
1483 ];
1484
1485 if (isset($params['export']['ALLOW'], $params['export']['SET']))
1486 {
1487 $arFields['EXPORT'] = [
1488 'ALLOW' => (bool)$params['export']['ALLOW'],
1489 'SET' => $params['export']['SET']
1490 ];
1491 }
1492
1493 if (isset($params['color']))
1494 {
1495 $arFields['COLOR'] = CCalendar::Color($params['color'], $DEFAULT_COLOR);
1496 }
1497 else
1498 {
1499 $arFields['COLOR'] = $DEFAULT_COLOR;
1500 }
1501
1502 if (isset($params['text_color']))
1503 {
1504 $arFields['TEXT_COLOR'] = CCalendar::Color($params['text_color'], $DEFAULT_TEXT_COLOR);
1505 }
1506 else
1507 {
1508 $arFields['TEXT_COLOR'] = $DEFAULT_TEXT_COLOR;
1509 }
1510
1511 if (isset($params['access']) && is_array($params['access']))
1512 {
1513 $arFields['ACCESS'] = $params['access'];
1514 }
1515
1516 $id = CCalendar::SaveSection([
1517 'bAffectToDav' => false,
1518 'arFields' => $arFields
1519 ]);
1520
1521 if (!$id)
1522 {
1523 throw new RestException(Loc::getMessage('CAL_REST_SECTION_NEW_ERROR'));
1524 }
1525
1526 CCalendarSect::SetClearOperationCache(true);
1527 return $id;
1528 }
1529
1530 /*
1531 * Update section
1532 *
1533 * @param array $params - incomoning params:
1534 * $params['id'] - (required) number, calendar type
1535 * $params['type'] - (required) number, calendar type
1536 * $params['ownerId'] - (required) number, owner id
1537 * $params['name'] - string, name of the section
1538 * $params['description'] - string, description of the section
1539 * $params['color']
1540 * $params['text_color']
1541 * $params['export'] = array(
1542 'ALLOW' => true|false,
1543 'SET' => array
1544 )
1545 * $params['access'] - array of access data
1546 *
1547 * @return id of modified section
1548 *
1549 * @throws \Bitrix\Rest\RestException
1550 *
1551 * @example (Javascript)
1552 * BX24.callMethod("calendar.section.update",
1553 * {
1554 * id: 325,
1555 * type: 'user',
1556 * ownerId: '2',
1557 * name: 'Changed Section Name',
1558 * description: 'New description for section',
1559 * color: '#9cbeAA',
1560 * text_color: '#283099',
1561 * export: [{ALLOW: false}]
1562 * access: {
1563 * 'D114': 17,
1564 * 'G2': 13,
1565 * 'U2':15
1566 * }
1567 * });
1568 */
1569 public static function SectionUpdate($params = [], $nav = null, $server = null)
1570 {
1571 $userId = CCalendar::GetCurUserId();
1572 $methodName = "calendar.section.update";
1573
1574 if (isset($params['type']))
1575 {
1576 $type = $params['type'];
1577 }
1578 else
1579 {
1580 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
1581 '#REST_METHOD#' => $methodName,
1582 '#PARAM_NAME#' => 'type'
1583 ]));
1584 }
1585
1586 if (isset($params['ownerId']))
1587 {
1588 $ownerId = (int)$params['ownerId'];
1589 }
1590 elseif ($type === 'user')
1591 {
1592 $ownerId = $userId;
1593 }
1594 else
1595 {
1596 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#REST_METHOD#' => $methodName, '#PARAM_NAME#' => 'ownerId')));
1597
1598 }
1599
1600 if (isset($params['id']) && (int)$params['id'] > 0)
1601 {
1602 $id = (int)$params['id'];
1603 }
1604 else
1605 {
1606 throw new RestException(Loc::getMessage('CAL_REST_SECT_ID_EXCEPTION'));
1607 }
1608
1609 if (isset($params['name']) && !is_string($params['name']))
1610 {
1611 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
1612 '#PARAM_NAME#' => 'name',
1613 ]));
1614 }
1615
1616 if (isset($params['description']) && !is_string($params['description']))
1617 {
1618 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', [
1619 '#PARAM_NAME#' => 'description',
1620 ]));
1621 }
1622
1624 $sectionModel =
1625 SectionModel::createFromId($id)
1626 ->setType($type)
1627 ->setOwnerId($ownerId)
1628 ;
1629 if (!$accessController->check(ActionDictionary::ACTION_SECTION_EDIT, $sectionModel))
1630 {
1631 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
1632 }
1633
1634 $arFields = [
1635 'ID' => $id,
1636 'CAL_TYPE' => $type,
1637 'OWNER_ID' => $ownerId
1638 ];
1639
1640 if (isset($params['name']) && trim($params['name']) !== '')
1641 {
1642 $arFields['NAME'] = trim($params['name']);
1643 }
1644
1645 if (isset($params['description']) && trim($params['description']) !== '')
1646 {
1647 $arFields['DESCRIPTION'] = trim($params['description']);
1648 }
1649
1650 if (isset($params['color']))
1651 {
1652 $arFields['COLOR'] = CCalendar::Color($params['color']);
1653 }
1654
1655 if (isset($params['text_color']))
1656 {
1657 $arFields['TEXT_COLOR'] = CCalendar::Color($params['text_color']);
1658 }
1659
1660 if (isset($params['access']) && is_array($params['access']))
1661 {
1662 $arFields['ACCESS'] = $params['access'];
1663 }
1664
1665 $id = (int)CCalendar::SaveSection([
1666 'bAffectToDav' => false,
1667 'arFields' => $arFields
1668 ]);
1669
1670 if (!$id)
1671 {
1672 throw new RestException(Loc::getMessage('CAL_REST_SECTION_SAVE_ERROR'));
1673 }
1674
1675 return $id;
1676 }
1677
1678 /*
1679 * Delete section
1680 *
1681 * @param array $params - incomoning params:
1682 * $params['type'] (required) calendar type
1683 * $params['ownerId'] (required) owner id
1684 * $params['id'] (required) section id
1685 *
1686 * @return true if everything ok
1687 *
1688 * @throws \Bitrix\Rest\RestException
1689 *
1690 * @example (Javascript)
1691 * BX24.callMethod("calendar.section.delete",
1692 * {
1693 * type: 'user',
1694 * ownerId: '2',
1695 * id: 521
1696 * });
1697 */
1698 public static function SectionDelete($params = [], $nav = null, $server = null)
1699 {
1700 $userId = CCalendar::GetCurUserId();
1701 $methodName = "calendar.section.delete";
1702
1703 if (isset($params['type']))
1704 {
1705 $type = $params['type'];
1706 }
1707 else
1708 {
1709 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
1710 '#REST_METHOD#' => $methodName,
1711 '#PARAM_NAME#' => 'type'
1712 ]));
1713 }
1714
1715 if (isset($params['ownerId']))
1716 {
1717 $ownerId = (int)$params['ownerId'];
1718 }
1719 elseif ($type === 'user')
1720 {
1721 $ownerId = $userId;
1722 }
1723 else
1724 {
1725 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#REST_METHOD#' => $methodName, '#PARAM_NAME#' => 'ownerId')));
1726 }
1727
1728 if (isset($params['id']) && (int)$params['id'] > 0)
1729 {
1730 $id = (int)$params['id'];
1731 }
1732 else
1733 {
1734 throw new RestException(Loc::getMessage('CAL_REST_SECT_ID_EXCEPTION'));
1735 }
1736
1738 $sectionModel =
1739 SectionModel::createFromId($id)
1740 ->setType($type)
1741 ->setOwnerId($ownerId)
1742 ;
1743 if (!$accessController->check(ActionDictionary::ACTION_SECTION_EDIT, $sectionModel))
1744 {
1745 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
1746 }
1747
1748 $res = CCalendar::DeleteSection($id);
1749
1750 if (!$res)
1751 {
1752 throw new RestException(Loc::getMessage('CAL_REST_SECTION_DELETE_ERROR'));
1753 }
1754
1755 return $res;
1756 }
1757
1758 /*
1759 * Set meeting status for current user
1760 *
1761 * @param array $params - incomoning params:
1762 * $params['eventId'] - event id
1763 * $params['status'] = 'Y' | 'N' | 'Q'
1764 *
1765 * @return true if everything ok
1766 *
1767 * @throws \Bitrix\Rest\RestException
1768 *
1769 * @example (Javascript)
1770 * BX24.callMethod("calendar.meeting.status.set",
1771 * {
1772 * eventId: '651',
1773 * status: 'Y'
1774 * });
1775 */
1776 public static function MeetingStatusSet($params = [], $nav = null, $server = null)
1777 {
1778 $userId = CCalendar::GetCurUserId();
1779 $methodName = "calendar.meeting.status.set";
1780
1781 $necessaryParams = array('eventId', 'status');
1782 foreach ($necessaryParams as $param)
1783 {
1784 if (empty($params[$param]))
1785 {
1786 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
1787 '#PARAM_NAME#' => $param,
1788 '#REST_METHOD#' => $methodName
1789 ]));
1790 }
1791 }
1792
1793 $params['status'] = mb_strtoupper($params['status']);
1794 if (!in_array($params['status'], array('Y', 'N', 'Q')))
1795 {
1796 throw new RestException(Loc::getMessage('CAL_REST_PARAM_ERROR', ['#PARAM_NAME#' => 'status']));
1797 }
1798
1799 CCalendarEvent::SetMeetingStatus(array(
1800 'userId' => $userId,
1801 'eventId' => $params['eventId'],
1802 'status' => $params['status']
1803 ));
1804
1805 return true;
1806 }
1807
1808 /*
1809 * Return meeting status for current user for given event
1810 *
1811 * @param array $params - incomoning params:
1812 * $params['eventId'] - (required) event id
1813 *
1814 * @return status - "Y" | "N" | "Q"
1815 *
1816 * @throws \Bitrix\Rest\RestException
1817 *
1818 * @example (Javascript)
1819 * BX24.callMethod("calendar.meeting.status.get",
1820 * {
1821 * eventId: '651'
1822 * });
1823 */
1824 public static function MeetingStatusGet($params = [], $nav = null, $server = null)
1825 {
1826 $userId = CCalendar::GetCurUserId();
1827 $methodName = "calendar.meeting.status.get";
1828
1829 $necessaryParams = array('eventId');
1830 foreach ($necessaryParams as $param)
1831 {
1832 if (empty($params[$param]))
1833 {
1834 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
1835 '#PARAM_NAME#' => $param,
1836 '#REST_METHOD#' => $methodName
1837 ]));
1838 }
1839 }
1840
1841 $status = CCalendarEvent::GetMeetingStatus(
1842 $userId,
1843 $params['eventId'],
1844 );
1845
1846 if ($status === false)
1847 {
1848 throw new RestException(Loc::getMessage('CAL_REST_GET_STATUS_ERROR'));
1849 }
1850
1851 return $status;
1852 }
1853
1854 /*
1855 * @deprecated
1856 */
1857 public static function MeetingParamsSet($params = [], $nav = null, $server = null)
1858 {
1859 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
1860 }
1861
1862 /*
1863 * Allow to get user's accessibility
1864 *
1865 * @param array $params - incomoning params:
1866 * $params['users'] - (required) array of user ids
1867 * $params['from'] - (required) date, from limit
1868 * $params['to'] - (required) date, to limit
1869 *
1870 * @return array - array('user_id' => array()) - information about accessibility for each asked user
1871 *
1872 * @throws \Bitrix\Rest\RestException
1873 *
1874 * @example (Javascript)
1875 * BX24.callMethod("calendar.accessibility.get",
1876 * {
1877 * from: '2013-06-20',
1878 * to: '2013-12-20',
1879 * users: [1, 2, 34]
1880 * });
1881 */
1882 public static function MeetingAccessibilityGet($params = [], $nav = null, $server = null)
1883 {
1884 $methodName = "calendar.accessibility.get";
1885
1886 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
1887 {
1888 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
1889 }
1890
1891 $necessaryParams = array('from', 'to', 'users');
1892 foreach ($necessaryParams as $param)
1893 {
1894 if (empty($params[$param]))
1895 {
1896 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
1897 '#PARAM_NAME#' => $param,
1898 '#REST_METHOD#' => $methodName
1899 ]));
1900 }
1901 }
1902
1903 $from = CRestUtil::unConvertDate($params['from']);
1904 $to = CRestUtil::unConvertDate($params['to']);
1905
1906 return CCalendar::GetAccessibilityForUsers(array(
1907 'users' => $params['users'],
1908 'from' => $from,
1909 'to' => $to,
1910 'getFromHR' => true
1911 ));
1912 }
1913
1914 /*
1915 * Return calendar general settings
1916 *
1917 * @return array of settings
1918 *
1919 * @example (Javascript)
1920 * BX24.callMethod("calendar.settings.get", {});
1921 */
1922 public static function SettingsGet($params = [], $nav = null, $server = null)
1923 {
1924 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
1925 {
1926 return [
1927 'work_time_start' => 9,
1928 'work_time_end' => 19,
1929 ];
1930 }
1931
1932 return CCalendar::GetSettings();
1933 }
1934
1935 /*
1936 * Set calendar settings
1937 *
1938 * @param array $params - incomoning params:
1939 * $params['settings'] - (required) array of user's settings
1940 *
1941 * @return true if everything ok
1942 *
1943 * @throws \Bitrix\Rest\RestException
1944 *
1945 * @example (Javascript)
1946 * BX24.callMethod("calendar.settings.set",
1947 * {
1948 * settings: {
1949 * work_time_start: 9,
1950 * work_time_end: 19,
1951 * year_holidays: '1.01,2.01,7.01,23.02,8.03,1.05,9.05,12.06,4.11,12.12,03.04,05.04',
1952 * week_holidays:['SA','SU'],
1953 * week_start: 'MO'
1954 * }
1955 * });
1956 */
1957 public static function SettingsSet($params = [], $nav = null, $server = null)
1958 {
1959 global $USER;
1960 $methodName = "calendar.settings.set";
1961
1962 if (!$USER->CanDoOperation('bitrix24_config') && !$USER->CanDoOperation('edit_php'))
1963 {
1964 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
1965 }
1966
1967 if (!isset($params['settings']))
1968 {
1969 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', [
1970 '#PARAM_NAME#' => 'settings',
1971 '#REST_METHOD#' => $methodName
1972 ]));
1973 }
1974
1975 CCalendar::SetSettings($params['settings']);
1976
1977 return true;
1978 }
1979
1980 /*
1981 * Clears calendar settings
1982 *
1983 * @return true if everything ok
1984 *
1985 * @throws \Bitrix\Rest\RestException
1986 *
1987 * @example (Javascript)
1988 * BX24.callMethod("calendar.settings.clear",{});
1989 */
1990 public static function SettingsClear()
1991 {
1992 global $USER;
1993
1994 if (!$USER->CanDoOperation('bitrix24_config') && !$USER->CanDoOperation('edit_php'))
1995 {
1996 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
1997 }
1998
1999 CCalendar::SetSettings([], true);
2000 return true;
2001 }
2002
2003 /*
2004 * Returns user's settings
2005 *
2006 * @return array of settings
2007 *
2008 * @example (Javascript)
2009 * BX24.callMethod("calendar.user.settings.get",{});
2010 */
2011 public static function UserSettingsGet($params = [], $nav = null, $server = null)
2012 {
2013 $userId = CCalendar::GetCurUserId();
2014
2015 return CCalendar::GetUserSettings($userId);
2016 }
2017
2018 /*
2019 * Saves user's settings
2020 *
2021 * @param array $params - incomoning params:
2022 * $params['settings'] - (required) array of user's settings
2023 *
2024 * @return true if everything ok
2025 *
2026 * @throws \Bitrix\Rest\RestException
2027 *
2028 * @example (Javascript)
2029 * BX24.callMethod("calendar.user.settings.set",
2030 * {
2031 * settings: {
2032 * tabId: 'month',
2033 * meetSection: '23',
2034 * blink: true,
2035 * showDeclined: false,
2036 * showMuted: true
2037 * }
2038 * });
2039 */
2040 public static function UserSettingsSet($params = [], $nav = null, $server = null)
2041 {
2042 $userId = CCalendar::GetCurUserId();
2043 $methodName = "calendar.user.settings.set";
2044
2045 if (!isset($params['settings']))
2046 {
2047 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#PARAM_NAME#' => 'settings','#REST_METHOD#' => $methodName)));
2048 }
2049
2051 return true;
2052 }
2053
2054 /*
2055 * Return list of all resources
2056 *
2057 * @return array of resources
2058 *
2059 * @throws \Bitrix\Rest\RestException
2060 *
2061 * @example (Javascript)
2062 * BX24.callMethod("calendar.resource.list");
2063 */
2064 public static function ResourceList()
2065 {
2066 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
2067 {
2068 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
2069 }
2070
2071 $resources = [];
2072
2073 $resourceList = Internals\SectionTable::getList(
2074 array(
2075 "filter" => [
2076 "=ACTIVE" => 'Y',
2077 "=CAL_TYPE" => 'resource'
2078 ],
2079 "select" => ["ID", "NAME", "CREATED_BY"]
2080 )
2081 );
2082
2083 while ($resource = $resourceList->fetch())
2084 {
2085 $resources[] = $resource;
2086 }
2087
2088 return $resources;
2089 }
2090
2091 /*
2092 * Add new resource
2093 *
2094 * @param array $params - incomoning params:
2095 * $params['name'] - string, (required) name of the resource
2096 *
2097 * @return id of created resource
2098 *
2099 * @throws \Bitrix\Rest\RestException
2100 *
2101 * @example (Javascript)
2102 * BX24.callMethod("calendar.resource.add",
2103 * {
2104 * name: 'My resource title'
2105 * });
2106 */
2107 public static function ResourceAdd($params = [], $nav = null, $server = null)
2108 {
2109 $methodName = "calendar.resource.add";
2110 $type = 'resource';
2111
2112 if (empty($params['name']))
2113 {
2114 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#REST_METHOD#' => $methodName, '#PARAM_NAME#' => 'name')));
2115 }
2116
2117 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
2118 {
2119 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
2120 }
2121
2122 $accessController = new TypeAccessController(CCalendar::GetUserId());
2123 $typeModel = TypeModel::createFromXmlId($type);
2124
2125 if (!$accessController->check(ActionDictionary::ACTION_TYPE_EDIT, $typeModel))
2126 {
2127 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
2128 }
2129
2130 $id = \CCalendarSect::edit([
2131 'arFields' => [
2132 'CAL_TYPE' => $type,
2133 'NAME' => $params['name'],
2134 'ACCESS' => []
2135 ]
2136 ]);
2137
2138 if (!$id)
2139 {
2140 throw new RestException(Loc::getMessage('CAL_REST_RESOURCE_NEW_ERROR'));
2141 }
2142
2143 CCalendarSect::SetClearOperationCache(true);
2144 return $id;
2145 }
2146
2147 /*
2148 * Update resource
2149 *
2150 * @param array $params - incomoning params:
2151 * $params['resourceId'] - (required) number,
2152 * $params['name'] - (required) string, name of the resource
2153 *
2154 * @return id of modified section
2155 *
2156 * @throws \Bitrix\Rest\RestException
2157 *
2158 * @example (Javascript)
2159 * BX24.callMethod("calendar.resource.update",
2160 * {
2161 * resourceId: 325,
2162 * name: 'Changed Resource Name'
2163 * });
2164 */
2165 public static function ResourceUpdate($params = [], $nav = null, $server = null)
2166 {
2167 $methodName = "calendar.resource.update";
2168 $type = 'resource';
2169
2170 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
2171 {
2172 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
2173 }
2174
2175 if (isset($params['resourceId']) && (int)$params['resourceId'] > 0)
2176 {
2177 $id = (int)$params['resourceId'];
2178 }
2179 else
2180 {
2181 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#REST_METHOD#' => $methodName, '#PARAM_NAME#' => 'id')));
2182 }
2183
2184 if (empty($params['name']))
2185 {
2186 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#REST_METHOD#' => $methodName, '#PARAM_NAME#' => 'name')));
2187 }
2188
2189 $accessController = new TypeAccessController(CCalendar::GetUserId());
2190 $typeModel = TypeModel::createFromXmlId($type);
2191
2192 if (!$accessController->check(ActionDictionary::ACTION_TYPE_EDIT, $typeModel))
2193 {
2194 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
2195 }
2196
2197 $id = \CCalendarSect::edit([
2198 'arFields' => [
2199 'ID' => $id,
2200 'CAL_TYPE' => $type,
2201 'NAME' => $params['name'],
2202 'ACCESS' => []
2203 ]
2204 ]);
2205
2206 if (!$id)
2207 {
2208 throw new RestException(Loc::getMessage('CAL_REST_RESOURCE_UPDATE_ERROR'));
2209 }
2210
2211 CCalendarSect::SetClearOperationCache(true);
2212 return $id;
2213 }
2214
2215 /*
2216 * Delete resource
2217 *
2218 * @param array $params - incomoning params:
2219 * $params['resourceId'] (required) resource id
2220 *
2221 * @return true if everything ok
2222 *
2223 * @throws \Bitrix\Rest\RestException
2224 *
2225 * @example (Javascript)
2226 * BX24.callMethod("calendar.resource.delete",
2227 * {
2228 * resourceId: 521
2229 * });
2230 */
2231 public static function ResourceDelete($params = [], $nav = null, $server = null)
2232 {
2233 $userId = CCalendar::GetCurUserId();
2234 $methodName = "calendar.resource.delete";
2235
2236 if (isset($params['resourceId']) && (int)$params['resourceId'] > 0)
2237 {
2238 $id = (int)$params['resourceId'];
2239 }
2240 else
2241 {
2242 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#REST_METHOD#' => $methodName, '#PARAM_NAME#' => 'resourceId')));
2243 }
2244
2245 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
2246 {
2247 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
2248 }
2249
2251 $typeModel = TypeModel::createFromXmlId(Dictionary::CALENDAR_TYPE['resource']);
2252
2253 if (!$accessController->check(ActionDictionary::ACTION_TYPE_EDIT, $typeModel))
2254 {
2255 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
2256 }
2257
2258 $res = CCalendar::DeleteSection($id);
2259
2260 if (!$res)
2261 {
2262 throw new RestException(Loc::getMessage('CAL_REST_SECTION_DELETE_ERROR'));
2263 }
2264
2265 return $res;
2266 }
2267
2268
2269 /*
2270 * Return list of booking for resources by id or by resource types
2271 *
2272 * @param array $params - incomoning params:
2273 * $params['filter'] - array of ids of resource bookings
2274 * $params['filter']['resourceIdList'] - array of ids of resource bookings, if this parameter is specified other filter params (resourceTypeIdList, from, to) in filter are not used.
2275 * $params['filter']['resourceTypeIdList'] - array, list of resource type ids. Required if resourceIdList is not specified.
2276 * $params['filter']['from'] - datetime, "from" limit, default value - 1 month before current date
2277 * $params['filter']['to'] - datetime, "to" limit, default value - 3 month after current date
2278 * @return array of booking for resources
2279 *
2280 * @throws \Bitrix\Rest\RestException
2281 *
2282 * @example (Javascript)
2283 * BX24.callMethod("calendar.resource.booking.list", {
2284 * filter: {
2285 * resourceTypeIdList: [10852, 10888, 10873, 10871, 10853]
2286 * from: '2013-06-20',
2287 * to: '2013-08-20',
2288 * }
2289 * };
2290 *
2291 * @example (Javascript)
2292 * BX24.callMethod("calendar.resource.booking.list", {
2293 * filter: {
2294 * resourceIdList: [10, 18, 17]
2295 * }
2296 * };
2297 */
2298 public static function ResourceBookingList($params = [])
2299 {
2300 $type = 'resource';
2301 $methodName = "calendar.resource.booking.list";
2302
2303 $userId = CCalendar::GetCurUserId();
2304
2305 if (Loader::includeModule('intranet') && !\Bitrix\Intranet\Util::isIntranetUser())
2306 {
2307 throw new RestException(Loc::getMessage('CAL_REST_ACCESS_DENIED'));
2308 }
2309
2310 $idList = isset($params['filter']) && is_array($params['filter'])
2311 ? ($params['filter']['resourceIdList'] ?? [])
2312 : []
2313 ;
2314 if (!empty($idList))
2315 {
2316 if(!is_array($idList) && $idList > 0)
2317 {
2318 $idList = [$idList];
2319 }
2320 if (!empty($idList))
2321 {
2322 $userId = CCalendar::GetCurUserId();
2324 $entries = [];
2325
2326 $eventIdList = [];
2327 $bookingIndex = [];
2328 if (is_array($resourseList) && isset($resourseList['ENTRIES']) && is_array($resourseList['ENTRIES']))
2329 {
2330 foreach($resourseList['ENTRIES'] as $resEntry)
2331 {
2332 $eventIdList[] = $resEntry['EVENT_ID'];
2333 $bookingIndex[$resEntry['EVENT_ID']] = (int)$resEntry['ID'];
2334 }
2335
2336 if (!empty($eventIdList))
2337 {
2338 $entries = CCalendarEvent::GetList(
2339 array(
2340 'arFilter' => array(
2341 'ID' => $eventIdList
2342 ),
2343 'parseRecursion' => true,
2344 'fetchAttendees' => false,
2345 'userId' => $userId,
2346 'fetchMeetings' => false,
2347 'setDefaultLimit' => false
2348 )
2349 );
2350 }
2351
2352 foreach($entries as $k => $entry)
2353 {
2354 $entries[$k]['RESOURCE_BOOKING_ID'] = $bookingIndex[$entry['ID']];
2355 }
2356 }
2357
2358 return $entries;
2359 }
2360 }
2361
2362 $resourceTypeIdList = isset($params['filter']) && is_array($params['filter'])
2363 ? ($params['filter']['resourceTypeIdList'] ?? [])
2364 : []
2365 ;
2366 if (empty($resourceTypeIdList) || !is_array($resourceTypeIdList))
2367 {
2368 throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#PARAM_NAME#' => 'filter[\'resourceTypeIdList\']', '#REST_METHOD#' => $methodName)));
2369 }
2370
2371 $from = isset($params['filter']['from']) ? CRestUtil::unConvertDateTime($params['filter']['from']) : false;
2372 $to = isset($params['filter']['to']) ? CRestUtil::unConvertDateTime($params['filter']['to']) : false;
2373
2374 // Default values for from-to period
2375 if ($from === false && $to === false)
2376 {
2377 // Limits
2378 $ts = time();
2379 $pastDays = 30;
2380 $futureDays = 90;
2381 $from = CCalendar::Date($ts - CCalendar::DAY_LENGTH * $pastDays, false);
2382 $to = CCalendar::Date($ts + CCalendar::DAY_LENGTH * $futureDays, false);
2383 }
2384 elseif($from !== false && $to === false)
2385 {
2386 $to = CCalendar::Date(CCalendar::GetMaxTimestamp(), false);
2387 }
2388
2389 $attendees = [];
2390 $entries = CCalendar::GetEventList([
2391 'type' => $type,
2392 'userId' => $userId,
2393 'section' => array_map('intval', $resourceTypeIdList),
2394 'fromLimit' => $from,
2395 'toLimit' => $to
2396 ], $attendees);
2397
2398 $eventIdList = [];
2399 $eventIndex = [];
2400
2401 foreach($entries as $i => $eventEntry)
2402 {
2403 $eventIdList[] = $eventEntry['ID'];
2404 $eventIndex[$eventEntry['ID']] = $i;
2405 $entries[$i]['RESOURCE_BOOKING_ID'] = null;
2406 }
2407
2408 $resourseList = \Bitrix\Calendar\Internals\ResourceTable::getList(
2409 array(
2410 "select" => ["ID","EVENT_ID"],
2411 "filter" => array(
2412 "=EVENT_ID" => $eventIdList
2413 )
2414 )
2415 );
2416
2417 while ($resBooking = $resourseList->fetch())
2418 {
2419 if ($eventIndex[$resBooking['EVENT_ID']] >= 0)
2420 {
2421 $entries[$eventIndex[$resBooking['EVENT_ID']]]['RESOURCE_BOOKING_ID'] = $resBooking['ID'];
2422 }
2423 }
2424
2425 return $entries;
2426 }
2427
2428 /*
2429 * Books given resource
2430 *
2431 * @param array $params - incomoning params:
2432 * $params['resourceType'] - (required) string, type of the resource could be 'user' or 'resource'
2433 * $params['resourceId'] - (required) number, id of the resource or user
2434 * $params['from'] - (required) datetime, "from"
2435 * $params['to'] - (required) datetime, "to" limit
2436 * $params['timezone'] - string, timezone, dafault value - timezone of current user
2437 * $params['skipTime'] - is it booking for whole day(s) "Y"|"N" deafault value - "N",
2438 * $params['bookingName'] - string, name of the booking event
2439 * $params['serviceName'] - string, name of the booking event
2440 * $params['bindingEntityType'] - string, type of entity binded to the booking (example CRM_LEAD)
2441 * $params['bindingEntityId'] - number, id of entity binded to the booking
2442 *
2443 * @return array of booking for esources
2444 *
2445 * @throws \Bitrix\Rest\RestException
2446 *
2447 * @example (Javascript)
2448 * BX24.callMethod("calendar.resource.booking.add", {
2449 * resourceTypeIdList: [10852, 10888, 10873, 10871, 10853]
2450 * from: '2013-06-20',
2451 * to: '2013-08-20',
2452 * };
2453 */
2454// public static function ResourceBookingAdd($params = array())
2455// {
2456// $userId = CCalendar::GetCurUserId();
2457// $methodName = "calendar.resource.booking.add";
2458//
2459// $necessaryParams = array('resourceType', 'resourceId', 'from', 'to');
2460//
2461// if (isset($params['from']))
2462// {
2463// $params['from'] = CRestUtil::unConvertDateTime($params['from']);
2464// }
2465//
2466// if (isset($params['to']))
2467// {
2468// $params['to'] = CRestUtil::unConvertDateTime($params['to']);
2469// }
2470//
2471// if (isset($params['resourceId']))
2472// {
2473// $params['resourceId'] = intval($params['resourceId']);
2474// }
2475//
2476// $params['bindingEntityType'] = isset($params['bindingEntityType']) ? $params['bindingEntityType'] : 'REST';
2477// $params['bindingEntityId'] = isset($params['bindingEntityId']) ? intval($params['bindingEntityId']) : 0;
2478//
2479// foreach ($necessaryParams as $param)
2480// {
2481// if (!isset($params[$param]) || empty($params[$param]))
2482// {
2483// throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#PARAM_NAME#' => $param,'#REST_METHOD#' => $methodName)));
2484// }
2485// }
2486//
2487// if (!in_array($params['resourceType'], ['user', 'resource']))
2488// {
2489// throw new RestException(Loc::getMessage('CAL_REST_RES_TYPE_ERROR', array('#ALLOWED_TYPES#' => 'user|resource')));
2490// }
2491//
2492// $entryFields = array(
2493// "DATE_FROM" => $params['from'],
2494// "DATE_TO" => $params['to'],
2495// "SKIP_TIME" => $params['skip_time'],
2496// "NAME" => !empty($params['bookingName']) ? $params['bookingName'] : Loc::getMessage('CAL_REST_RES_BOOKING_DEFAULT_VALUE')
2497// );
2498//
2499// if ($params['serviceName'] !== '')
2500// {
2501// $entryFields["DESCRIPTION"] = Loc::getMessage("CAL_REST_RES_BOOKING_SERVICE_LABEL").': '.$params['serviceName'];
2502// }
2503//
2504// if (strtoupper($params['skipTime']) !== 'Y')
2505// {
2506// $userTimezoneName = \CCalendar::getUserTimezoneName($userId, true);
2507// if($userTimezoneName)
2508// {
2509// $entryFields['TZ_FROM'] = $userTimezoneName;
2510// $entryFields['TZ_TO'] = $userTimezoneName;
2511// }
2512// }
2513//
2514// $resourceBookingId = \Bitrix\Calendar\UserField\ResourceBooking::saveResource(
2515// false,
2516// $params['resourceType'],
2517// $params['resourceId'],
2518// $entryFields,
2519// [
2520// 'serviceName' => $params['serviceName'],
2521// 'bindingEntityType' => $params['bindingEntityType'],
2522// 'bindingEntityId' => $params['bindingEntityId'],
2523// 'bindingUserfieldId' => $params['bindingUserfieldId']
2524// ]
2525// );
2526//
2527// if (!$resourceBookingId)
2528// {
2529// throw new RestException(Loc::getMessage("CAL_REST_RESOURCE_BOOKING_ADD_ERROR"));
2530// }
2531//
2532// return $resourceBookingId;
2533// }
2534
2535 /*
2536 * Edit resource booking
2537 *
2538 * @param array $params - incomoning params:
2539 * $params['id'] - (required) numper, booking id,
2540 * $params['resourceType'] - (required) string, type of the resource could be 'user' or 'resource'
2541 * $params['resourceId'] - (required) number, id of the resource or user
2542 * $params['from'] - (required) datetime, "from"
2543 * $params['to'] - (required) datetime, "to" limit
2544 * $params['timezone'] - string, timezone, dafault value - timezone of current user
2545 * $params['skipTime'] - is it booking for whole day(s) "Y"|"N" deafault value - "N",
2546 * $params['bookingName'] - string, name of the booking event
2547 * $params['serviceName'] - string, name of the booking event
2548 * $params['bindingEntityType'] - string, type of entity binded to the booking (example CRM_LEAD)
2549 * $params['bindingEntityId'] - number, id of entity binded to the booking
2550 *
2551 * @return array of booking for esources
2552 *
2553 * @throws \Bitrix\Rest\RestException
2554 *
2555 * @example (Javascript)
2556 * BX24.callMethod("calendar.resource.booking.update", {
2557 * id:
2558 * resourceTypeIdList: [10852, 10888, 10873, 10871, 10853]
2559 * from: '2013-06-20',
2560 * to: '2013-08-20',
2561 * };
2562 */
2563// public static function ResourceBookingUpdate($params = array())
2564// {
2565// $userId = CCalendar::GetCurUserId();
2566// $methodName = "calendar.resource.booking.update";
2567//
2568// $necessaryParams = array('id', 'resourceType', 'resourceId', 'from', 'to');
2569//
2570// if (isset($params['id']))
2571// {
2572// $params['id'] = intval($params['id']);
2573// }
2574//
2575// if (isset($params['from']))
2576// {
2577// $params['from'] = CRestUtil::unConvertDateTime($params['from']);
2578// }
2579//
2580// if (isset($params['to']))
2581// {
2582// $params['to'] = CRestUtil::unConvertDateTime($params['to']);
2583// }
2584//
2585// if (isset($params['resourceId']))
2586// {
2587// $params['resourceId'] = intval($params['resourceId']);
2588// }
2589//
2590// $params['bindingEntityType'] = isset($params['bindingEntityType']) ? $params['bindingEntityType'] : 'REST';
2591// $params['bindingEntityId'] = isset($params['bindingEntityId']) ? intval($params['bindingEntityId']) : 0;
2592//
2593// foreach ($necessaryParams as $param)
2594// {
2595// if (!isset($params[$param]) || empty($params[$param]))
2596// {
2597// throw new RestException(Loc::getMessage('CAL_REST_PARAM_EXCEPTION', array('#PARAM_NAME#' => $param,'#REST_METHOD#' => $methodName)));
2598// }
2599// }
2600//
2601// if (!in_array($params['resourceType'], ['user', 'resource']))
2602// {
2603// throw new RestException(Loc::getMessage('CAL_REST_RES_TYPE_ERROR', array('#ALLOWED_TYPES#' => 'user|resource')));
2604// }
2605//
2606// $entryFields = array(
2607// "DATE_FROM" => $params['from'],
2608// "DATE_TO" => $params['to'],
2609// "SKIP_TIME" => $params['skip_time'],
2610// "NAME" => !empty($params['bookingName']) ? $params['bookingName'] : Loc::getMessage('CAL_REST_RES_BOOKING_DEFAULT_VALUE')
2611// );
2612//
2613// if ($params['serviceName'] !== '')
2614// {
2615// $entryFields["DESCRIPTION"] = Loc::getMessage("CAL_REST_RES_BOOKING_SERVICE_LABEL").': '.$params['serviceName'];
2616// }
2617//
2618// if (strtoupper($params['skipTime']) !== 'Y')
2619// {
2620// $userTimezoneName = \CCalendar::getUserTimezoneName($userId, true);
2621// if($userTimezoneName)
2622// {
2623// $entryFields['TZ_FROM'] = $userTimezoneName;
2624// $entryFields['TZ_TO'] = $userTimezoneName;
2625// }
2626// }
2627//
2628// $resourceBookingId = \Bitrix\Calendar\UserField\ResourceBooking::saveResource(
2629// $params['id'],
2630// $params['resourceType'],
2631// $params['resourceId'],
2632// $entryFields,
2633// [
2634// 'serviceName' => $params['serviceName'],
2635// 'bindingEntityType' => $params['bindingEntityType'],
2636// 'bindingEntityId' => $params['bindingEntityId'],
2637// 'bindingUserfieldId' => $params['bindingUserfieldId']
2638// ]
2639// );
2640//
2641// if (!$resourceBookingId)
2642// {
2643// throw new RestException(Loc::getMessage("CAL_REST_RESOURCE_BOOKING_ADD_ERROR"));
2644// }
2645//
2646// return $resourceBookingId;
2647// }
2648
2649// public static function ResourceBookingDelete($params = array())
2650// {
2651// $userId = CCalendar::GetCurUserId();
2652// $methodName = "calendar.resource.booking.delete";
2653//
2654// \CCalendar::deleteEvent(intVal($entry['EVENT_ID']), false, array('checkPermissions' => false));
2655// Internals\ResourceTable::delete($entry['ID']);
2656// }
2657
2658
2659 /*
2660 * Clears user's settings
2661 *
2662 * @return true if everything ok
2663 *
2664 * @example (Javascript)
2665 * BX24.callMethod("calendar.settings.clear",{});
2666 */
2667 public static function UserSettingsClear($params = [], $nav = null, $server = null)
2668 {
2669 $userId = CCalendar::GetCurUserId();
2671 return true;
2672 }
2673
2674 /*
2675 * Filters data fields about entry for event handlers
2676 *
2677 * @return array - array('id' => number) - id of entry which triggered event
2678 */
2679 public static function PrepareOnCalendarEntryEvent($params, $handler)
2680 {
2681 return ['id' => $params[0]];
2682 }
2683
2684 /*
2685 * Filters data fields about section for event handlers
2686 *
2687 * @return array - array('id' => number) - id of section which triggered event
2688 */
2689 public static function PrepareOnCalendarSectionEvent($params, $handler)
2690 {
2691 return ['id' => $params[0]];
2692 }
2693
2694 public static function PrepareOnCalendarRoomEvent($params)
2695 {
2696 return ['id' => $params[0]];
2697 }
2698
2699 private static function processTimezone(array $params, array $arFields): array
2700 {
2701 if (isset($params['timezone_to']))
2702 {
2703 $arFields['TZ_TO'] = $params['timezone_to'];
2704 }
2705
2706 if (isset($params['timezone_from']))
2707 {
2708 $arFields['TZ_FROM'] = $params['timezone_from'];
2709
2710 if (!isset($params['timezone_to']))
2711 {
2712 $arFields['TZ_TO'] = $params['timezone_from'];
2713 }
2714 }
2715
2716 if (!isset($arFields['TZ_FROM']) || !isset($arFields['TZ_TO']))
2717 {
2718 $userTimezoneName = CCalendar::GetUserTimezoneName(CCalendar::GetCurUserId());
2719
2720 if (!isset($arFields['TZ_FROM']))
2721 {
2722 $arFields['TZ_FROM'] = $userTimezoneName;
2723 }
2724
2725 if (!isset($arFields['TZ_TO']))
2726 {
2727 $arFields['TZ_TO'] = $userTimezoneName;
2728 }
2729 }
2730
2731 return $arFields;
2732 }
2733}
$type
Определения options.php:106
$accessController
Определения options.php:23
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getResourceEntriesList($idList=[])
Определения resourcebooking.php:1164
static set($settings=[], $userId=false)
Определения usersettings.php:50
Определения loader.php:13
static includeModule($moduleName)
Определения loader.php:67
static GetUserTimezoneName($user, $getDefault=true)
Определения calendar.php:5435
static ResourceList()
Определения calendar_restservice.php:2064
static UserSettingsGet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:2011
static EventGetById($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:306
static EventAdd($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:406
static PrepareOnCalendarRoomEvent($params)
Определения calendar_restservice.php:2694
static UserSettingsSet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:2040
static PrepareOnCalendarSectionEvent($params, $handler)
Определения calendar_restservice.php:2689
static UserSettingsClear($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:2667
static EventUpdate($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:801
static EventGetNearest($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1219
static SettingsClear()
Определения calendar_restservice.php:1990
static ResourceUpdate($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:2165
static OnRestServiceBuildDescription()
Определения calendar_restservice.php:31
const PLACEMENT_GRID_VIEW
Определения calendar_restservice.php:29
static MeetingAccessibilityGet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1882
static SectionGet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1296
const SCOPE_NAME
Определения calendar_restservice.php:28
static EventGet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:175
static MeetingParamsSet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1857
static MeetingStatusSet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1776
static SectionUpdate($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1569
static MeetingStatusGet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1824
static SettingsGet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1922
static ResourceDelete($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:2231
static SectionAdd($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1418
static ResourceBookingList($params=[])
Определения calendar_restservice.php:2298
static SectionDelete($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1698
static SettingsSet($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1957
static ResourceAdd($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:2107
static EventDelete($params=[], $nav=null, $server=null)
Определения calendar_restservice.php:1172
static PrepareOnCalendarEntryEvent($params, $handler)
Определения calendar_restservice.php:2679
static urlAddParams($url, $add_params, $options=[])
Определения http.php:521
Определения rest.php:896
$arFields
Определения dblapprove.php:5
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
global $USER
Определения csv_new_run.php:40
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
$status
Определения session.php:10
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
$value
Определения Param.php:39
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$i
Определения factura.php:643
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$k
Определения template_pdf.php:567
$arFilter
Определения user_search.php:106