calendar 25.200.0: таймзона пользователя переехала в b_user.TIME_ZONE — и это ломающий релиз

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

Ломающее обновление

Удалены или изменены публичные API — прикладной код может перестать работать.

Самый «ломающий» календарный релиз батча. Часовой пояс пользователя перестал быть настройкой календаря и стал полем пользователя, из-за чего у AJAX-экшена сохранения настроек изменилась сигнатура. Плюс вырезаны два метода SynchronizationFeature. Обновление стоит смотреть внимательно, если вы что-то дописывали вокруг настроек календаря.

Таймзона: один источник правды вместо двух

Раньше имя часового пояса лежало в CUserOptions (категория calendar, ключ вида timezone{offset}), а в b_user было поле TIME_ZONE. Два хранилища одного факта — классический источник расхождений: пользователь меняет пояс в профиле, календарь продолжает считать по своему.

Теперь CCalendar::GetUserTimezoneName() берёт имя из $user['TIME_ZONE'], а чтение из CUserOptions оставлено только как fallback и помечено как deprecated compatibility. Метод CCalendar::SaveUserTimezoneName($user, $tzName = '') тоже помечен @deprecated с прямым указанием причины: «now using TIME_ZONE field in b_user». Он остался и по-прежнему пишет в CUserOptions, но опираться на него не надо.

Второе изменение того же круга: GetCurrentOffsetUTC() считает смещение через (new DateTime())->getOffset(), а не через date('Z'). Разница проявляется на переходах на летнее время и в зонах с нецелым смещением — date('Z') отдаёт смещение по текущей таймзоне PHP, а не по таймзоне вычисляемой даты.

Что сломается

  • CalendarAjax::saveSettingsAction() — удалён аргумент string $user_timezone_name = ''. Сигнатура стала (string $type, array $user_settings = [], array $settings = []). Вызов CCalendar::SaveUserTimezoneName() из экшена убран. Если у вас есть свой JS, который дёргает этот экшен и передаёт имя таймзоны, — параметр просто перестанет доезжать, молча.
  • SynchronizationFeature::isOnForUser(int $userId) и setUserId(?int $userId) удалены. Остался isOn(): bool, который возвращает true. Признак того, что синхронизация перестала быть пофичефлажной настройкой на пользователя — вызовы setUserId сняты в нескольких точках синхронизации. Наследники и вызовы этих методов упадут с фаталом.
  • CCalendar при пустом $type сразу отдаёт access_denied: проверка стала empty($type) || !…check(ACTION_TYPE_VIEW…). Раньше пустой тип уходил дальше и мог трактоваться по умолчанию. Код, который вызывал календарные методы без явного типа, начнёт получать отказ — это не баг, а закрытая дыра в проверке прав.

Ужесточение прав на групповые календари

Тема релиза продолжается и в правах:

  • CreateEventHandler дополнительно проверяет CCalendar::GetPermissions с ключом edit, если секция групповая ($section->isGroup()).
  • CalendarAjax при type=group и заданном $ownerId тоже требует permission['edit'], иначе access denied.

Для этого в Section появились isGroup() и isCompany() — сравнение type со значениями Dictionary::CALENDAR_TYPE. Мелочь, но она убирает из кода россыпь сравнений со строками.

Прочее

  • ICal\MailInvitation\Helper::getAttendee(?int $userId, …) — $userId стал nullable и при null метод сразу возвращает null. Меньше проверок на стороне вызывающего.
  • Sync\Icloud\Helper::getImportLockName(int $connectionId) — имя лока импорта вынесено в метод.
  • Section::isVirtual() читает роли reader / freeBusyOrder из Google\Dictionary::ACCESS_ROLE_TO_EXTERNAL_TYPE, а не из общего Dictionary.

Схема БД не менялась: b_user.TIME_ZONE — существующее поле пользователя, новой колонки в календаре не появилось.

Что делать

  1. Найдите вызовы SynchronizationFeature::isOnForUser и setUserId — их больше нет.
  2. Проверьте свой JS/PHP, который зовёт calendar.api.calendarajax.saveSettings с именем таймзоны.
  3. Читаете таймзону пользователя — берите b_user.TIME_ZONE, а не CUserOptions.
  4. Проверьте места, где календарные методы вызывались без явного $type.

Устаревшие и удалённые API в этой версии

Символ Статус Чем заменять
CCalendar::SaveUserTimezoneName() Deprecated —
SynchronizationFeature::isOnForUser() Удалено SynchronizationFeature::isOn()
SynchronizationFeature::setUserId() Удалено —

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

Войти