calendar 26.0.100: почему у людей пропадали встречи при синхронизации с Google и iCloud

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

Маленький релиз с большими последствиями — исправлена потеря данных при импорте календаря. Если внешний сервис отдавал неполную страницу событий, Битрикс считал недостающие экземпляры удалёнными и вычищал их у себя. Публичного API изменение не трогает, но поставить его стоит всем, у кого работает синхронизация.

В чём была проблема

Импорт устроен так: получили от Google или iCloud список экземпляров повторяющегося события, сравнили с локальным, чего нет в ответе — удалили. Логика верная ровно при одном условии: ответ полный.

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

Комментарий в новом коде описывает ровно это: на неполном или обрезанном ответе отсутствующие экземпляры могли просто не попасть в страницу, а не быть удалёнными; пропуск очистки нужен, чтобы не терять данные и сохранить EventConnections для следующего полного прохода.

Как исправили

В DTO EventListResponse (и у Google, и у iCloud) появилось поле public bool $isPartial = false. Процедуры импорта проставляют его по ответу вендора, а AbstractEventImportProcessor::removeDeprecatedInstances() при isPartialResponse просто выходит, ничего не удаляя.

Ключевое разграничение — явные удаления применяются всегда. Google, присылающий событию статус cancelled, и iCloud, отвечающий 404, — это утверждение «этого события нет», ему верят при любом флаге. Подавляется только вывод удаления из факта отсутствия в списке.

Условия выставления флага стоит знать точно, потому что они не «всегда на всякий случай»:

  • Google: isPartial = true на начальной синхронизации (syncToken отсутствует), если в запросе был pageToken или в ответе есть nextPageToken. Одностраничный полный снимок — без pageToken на входе и без nextPageToken на выходе — очистку не отключает. Инкрементальная синхронизация (когда syncToken есть) не затрагивается вообще.
  • iCloud: аналогичный флаг на DTO; ICloudEventSynchronizer перестал безусловно выставлять syncToken из nextSyncToken на каждом ответе.

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

Заодно поправлена логика удаления

Роль master/owner против guest теперь берётся из локального события в $this->map, а не из внешнего. Причина техническая и показательная: у внешнего события getParentId() всегда null, так что определить по нему, экземпляр это или мастер, невозможно. Экземпляр повторения ищется через мастера и getSameInstance().

Что делать

  • Ставить, если у вас включена синхронизация с Google Calendar или iCloud. Это исправление потери пользовательских данных, а не улучшение.
  • Если пользователи жаловались на «пропали встречи после подключения календаря» — вот объяснение, и после обновления повторяться не должно.
  • Пишете свою синхронизацию с внешним источником — здесь хороший общий урок: отсутствие записи в ответе не равно её удалению, пока вы не уверены, что ответ полный.

Новая версия вышла — разбор уже в 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 Домовому.

Войти