calendar 26.0.0: потолок повторов RRULE, права на удалённые sharing-события и разбор ошибок REST

4 мин чтения
Узнавайте о ломающих изменениях Битрикса раньше, чем они доедут до прода: свежие разборы — в канале @bxmax_updates

Релиз про повторяющиеся события и права. Появился жёсткий лимит на количество повторов, у удалённых событий по общей ссылке — отдельная проверка доступа, а REST перестал терять ошибки между вызовами. Публичные сигнатуры не удалялись, но пара изменений в поведении заметна.

Потолок на повторы

CCalendarEvent::$MAX_RRULE_COUNT = 10000, метод limitRRuleCount() обрезает RRULE.COUNT.

Ограничение очевидно откуда взялось: правило «повторять 999999 раз» — законный ICS, который приезжает из внешнего календаря, и дальше портал честно материализует экземпляры. Десять тысяч — компромисс между «ежедневно 27 лет» и «не положить базу одним импортом».

Рядом переписан пересчёт UNTIL для правил, заданных через COUNT: появились getRRuleCalculationTimezone() и calculateUntilForCountRRuleInCurrentTimezone(). Считать «двадцатое повторение» без учёта таймзоны самого события нельзя — на границе перехода на летнее время расчёт уезжает на час, а на длинной серии это сдвиг даты.

Сдвиг экземпляров при переносе серии вынесен в отдельные методы: getRecurrentEventTimestampDelta(), shiftRecurrentDateByDays(), shiftRecurrentExDatesByDays(). Появился CCalendar::normalizeRRuleByDay($byDay): array — нормализация BYDAY к ключам SU...SA. Если вы разбирали BYDAY сами, теперь есть штатный способ.

Доступ к удалённым событиям по общей ссылке

Новый DeletedSharedEventAccessChecker::canView(int $userId, EventLink $eventLink, ?Link $parentLink) разбирает три случая: ссылка на сделку CRM, на группу и на пользователя. CCalendar при просмотре удалённого sharing-события идёт через него и возвращает null при отсутствии доступа.

Сценарий, который это закрывает: событие по публичной ссылке удалили, но ссылка осталась у получателя. Раньше страница удалённого события отдавала данные всем, у кого есть URL. Теперь у неё есть своя проверка прав, привязанная к сущности, ради которой ссылку выдавали.

Под ту же задачу приехали UserPermissionsHandler::canReadDeal(int $userId, int $dealId) и MemberFilterService::filterAccessibleMemberIds(array $memberIds) — последний фильтрует участников через CSocNetUser::CanProfileView, чтобы в списке участников не светились те, чьи профили пользователю недоступны. Подключается через ServiceLocator в фабрике sharing-ссылок.

REST: секция стала необязательной, ошибки перестали копиться

В CCalendarRestService при добавлении события section больше не обязателен, если auto_detect_section !== "Y". Точнее: секция определяется автоматически при пустом section даже когда опция выставлена в "N". Формально это изменение поведения — раньше отсутствие секции при выключенной опции было ошибкой. Практически — на одну причину отказа REST-вызова меньше.

Второе: CCalendar::GetAndClearErrors() возвращает накопленные ошибки и обнуляет массив, и REST теперь пользуется им. Статический массив ошибок, который никто не чистит, — это классическая причина «второй вызов в том же хите вернул ошибку от первого».

Ещё в релизе

  • Integration\Booking\EventDescription::getDescription() / clearOutFromDescription() — обёртка над \Bitrix\Booking\Service\EventDescription, если модуль booking подключён. Разумный способ не тащить жёсткую зависимость.
  • Синхронизация: ExceptionProcessorTrait теперь бросает NoLoggableException вместо RecoverableMessageException для NoLogSynchronizerException, HTTP 5xx и DtoValidationException. То есть такие сообщения больше не уходят в бесконечный ретрай очереди — сообщение, которое не станет валидным от повторной попытки, повторять бессмысленно.
  • Office365: EventResponse строит DateTimeDto из $data['start'], а не $item['start'] — похоже на обычный багфикс разбора ответа.
  • Из CCalendarEvent::Edit вычищены закомментированные deprecated-блоки про DAV_XML_ID и ConnectEventToSection.

Схемы БД в релизе нет, но появился migration_config.json (defaultTableName = b_calendar_event) — модуль готовят к переезду на UpdateSystem\Migration, самих файлов миграций пока нет.

Что делать

  • Импортируете внешние календари — знайте про потолок 10000 повторов, серии длиннее будут обрезаны.
  • Разбираете BYDAY руками — переходите на normalizeRRuleByDay().
  • Если у вас свои страницы просмотра sharing-событий, посмотрите на DeletedSharedEventAccessChecker: та же дыра могла быть и у вас.

Новая версия вышла — разбор уже в Telegram

В канале @bxmax_updates публикуем каждый свежий разбор: что сломается, что устарело и что появилось в API. Узнаете до того, как обновите прод.

Подписаться

Читайте дальше

calendar 26.300.0 Безопасность Свежее

Calendar 26.300.0: закрыты дыры в правах на календари и переговорки, дельта в REST

Calendar 26.300.0 закрывает три дыры в правах: перенос события в чужой календарь без права на добавление, подмену чужой брони переговорки через `LOCATION[’OLD’]` или `room_event_id` и добавление в участники проектов, где пользователь не состоит. Для интеграций в `calendar.event.get` появилось инкрем…

2 мин
calendar 26.200.0 Ломающее Свежее

Calendar 26.150.0–26.200.0: двойная бронь переговорки стала ошибкой, а форма бронирования больше не отдаёт чужую занятость

Календарь вышел двумя версиями, 26.150.0 и 26.200.0. В 26.150.0 закрыли утечку в анонимном экшене бронирования CRM-формы, через который любой посетитель мог узнать занятость и имена сотрудников и ресурсов портала. В 26.200.0 занятость переговорок проверяется по умолчанию в `CCalendar::SaveEvent`, RE…

1 мин
calendar 26.125.100 Безопасность

Calendar 26.125.100: карточка события без полного доступа больше не выдаёт хоста, участников и раздел

В Calendar 26.125.100 карточка события и планировщик перестали отдавать пользователю без полного доступа хоста, автора, участников, данные раздела, ссылки и пользовательские поля. Режет данные новый класс `Bitrix\Calendar\View\EventViewData`, а ответы экшенов `getViewEventSlider`, `getCalendarViewSl…

5 мин
calendar 26.100.0 Безопасность

Calendar 26.100.0: почтовые приглашения и calendar.section.update берут хоста, тип и владельца из базы

В Calendar 26.100.0 REST-метод `calendar.section.update` берёт тип и владельца секции из базы, а обработчик входящих iCal-приглашений ищет событие только среди встреч получателя и при обновлении встречи читает её хоста из базы. В участники встречи теперь можно звать команды из модуля `humanresources…

4 мин
Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.
AI Домовой

AI Домовой История

на связи

пишет…

Можно закрыть чат и перейти на другую страницу. Когда ответ будет готов, на кнопке Домового появится отметка.

Нет истории чатов
AI Домовой

Нужна авторизация

Войдите, чтобы задавать вопросы AI Домовому.

Войти