На практике после миграции CIBlockProperty::Update возвращает true, а в админке галочка "Показывать в умном фильтре" пустая. На следующем шаге разработчик вызвал CIBlockProperty::Delete, думая что "почистит" значения у 12 000 SKU, и снёс все данные каталога - хотел только обнулить поле через SetPropertyValuesEx. Ниже - безопасный Update (NAME, CODE, SMART_FILTER, UpdateEnum) и Delete с каскадом, LAST_ERROR и альтернативой ACTIVE=N на проде.
CIBlockProperty::Update и CIBlockProperty::Delete в 1С-Битрикс: Управление сайтом - legacy-методы класса CIBlockProperty для изменения схемы свойства инфоблока (NAME, CODE, PROPERTY_TYPE, SMART_FILTER, VALUES) и полного удаления свойства вместе со всеми значениями элементов. Update - нестатический, возвращает true/false и LAST_ERROR; Delete - статический с 3.0.3, каскадно чистит enum, section links и колонки b_iblock_element_prop_s*. Не меняют значения элементов точечно - для этого SetPropertyValuesEx. Сегодня: перед Update снимите GetList, для SMART_FILTER передавайте IBLOCK_ID в arFields, для enum - полный массив в UpdateEnum, Delete только на staging с бэкапом.
Речь про 1С-Битрикс: Управление сайтом (CMS на вашем сервере), не про облачный Bitrix24 CRM. Свойство инфоблока - "колонка" каталога: цвет, бренд, артикул. Создать новое поле - CIBlockProperty::Add (B93). Записать значение в карточку товара - CIBlockElement::Update и SetPropertyValuesEx (B40). Здесь - правка и удаление уже существующей схемы свойства.
Разберите, когда нужен Update или Delete, а не Add и не SetPropertyValuesEx
CIBlockProperty::Update меняет описание поля в структуре инфоблока: подпись, CODE, тип, флаги фильтра. CIBlockProperty::Delete убирает поле целиком из схемы и каскадно стирает все значения у элементов. Это другой уровень, чем правка товара.
| Задача | Метод | Что трогает |
|---|---|---|
| Новое поле в каталоге | CIBlockProperty::Add (B93) | Схема: новая строка в b_iblock_property |
| Поменять NAME, SMART_FILTER, CODE | CIBlockProperty::Update | Схема существующего свойства по ID |
| Обнулить цвет у одного SKU | SetPropertyValuesEx(false) | Значение у элемента, схема цела |
| Убрать legacy-поле с 12 000 товаров | Delete или ACTIVE=N | Delete - схема + все значения; ACTIVE=N - только скрыть |
Типичный сценарий: Sprint Migration (B65) на деплое массово включает SMART_FILTER через Update в цикле GetList. Настройка фильтра руками в админке - гайд B53.
Делайте: Update/Delete в миграциях и скрипах чистки legacy-схемы. Не делайте: Delete когда нужно только очистить значения - это SetPropertyValuesEx.
Что такое CIBlockProperty::Update и Delete
Update - нестатический, при false - LAST_ERROR. Delete - статический с 3.0.3. На проде - ACTIVE=N, не Delete.
Выполните Update: GetList до/после, NAME, CODE и LAST_ERROR
- Модуль:
Loader::includeModule('iblock'). - Снимок до: GetList по ID - NAME, CODE, SMART_FILTER.
- Объект и вызов:
$ibp = new CIBlockProperty;$ok = $ibp->Update($propId, $arFields); - Ошибка и проверка: при
!$okчитайте$ibp->LAST_ERRORв лог миграции; при успехе - повторный GetList, поля должны совпасть с ожиданием.
<?php
use Bitrix\Main\Loader;
Loader::includeModule('iblock');
$iblockId = 7;
$propId = 42;
$ibp = new CIBlockProperty;
$ok = $ibp->Update($propId, [
'IBLOCK_ID' => $iblockId,
'NAME' => 'Цвет товара',
'SORT' => 150,
]);
if (!$ok) {
throw new \RuntimeException($ibp->LAST_ERROR);
}
Делайте: IBLOCK_ID в arFields при каждом Update. Не делайте: менять PROPERTY_TYPE с данными - ядро очистит значения элементов.
Устраните ловушку SMART_FILTER: IBLOCK_ID и SECTION_PROPERTY
Типичная ошибка на стейдже: Update с SMART_FILTER=Y возвращает true, но галочка в админке пустая. Например, в arFields забыли IBLOCK_ID - LAST_ERROR в этом случае тоже молчит (кейс с форума и пример 4 в Update.php).
Цепочка умного фильтра: SECTION_PROPERTY=Y у инфоблока → Update с IBLOCK_ID и SMART_FILTER=Y → CIBlockSectionPropertyLink для разделов → сброс кеша catalog.smart.filter
- Проверьте инфоблок:
CIBlock::GetArrayByID($iblockId)['SECTION_PROPERTY']должен быть Y. - Если N:
CIBlock::Update($iblockId, ['SECTION_PROPERTY' => 'Y']). - Массовый паттерн (bazarow): GetList по IBLOCK_ID, в цикле Update с IBLOCK_ID, SMART_FILTER=Y, при необходимости DISPLAY_TYPE и DISPLAY_EXPANDED.
$res = CIBlockProperty::GetList(['SORT' => 'ASC'], ['IBLOCK_ID' => $iblockId]);
$ibp = new CIBlockProperty;
while ($row = $res->Fetch()) {
$ibp->Update($row['ID'], [
'IBLOCK_ID' => $iblockId,
'SMART_FILTER' => 'Y',
]);
}
Делайте: проверьте галочки и фильтр на витрине. Не делайте: Update SMART_FILTER без IBLOCK_ID.
Настройте SECTION_PROPERTY и CIBlockSectionPropertyLink
SMART_FILTER в карточке свойства не равен фильтру в разделе - нужен CIBlockSectionPropertyLink::Add. SaveAction в админке ставит SECTION_PROPERTY=Y; legacy Update - нет. UI - гайд B53.
Правьте списки (PROPERTY_TYPE=L) через UpdateEnum без потери enum
Для списочных свойств варианты хранятся в CIBlockPropertyEnum. UpdateEnum требует полный массив arVALUES: отсутствующие ID удаляются из enum. Перед правкой снимите GetPropertyEnum и сохраните все существующие ID.
- До:
CIBlockProperty::GetPropertyEnum($code, [], ['IBLOCK_ID' => $iblockId]). - Merge: добавьте новый вариант как n0, сохраните старые как ID=>поля.
- Вызов:
$ibp->UpdateEnum($propId, $arVALUES)или через Update с ключом VALUES при полной замене. - После: снова GetPropertyEnum - ни один старый ID не должен пропасть без намерения.
Enum ID - B88. Не делайте: UpdateEnum только с новыми вариантами - старые enum удалятся.
Удалите свойство через Delete: каскад и OnBeforeIBlockPropertyDelete
Delete каскадно: enum, CIBlockSectionPropertyLink, колонки prop_s*, все значения элементов. Порядок: бэкап → ACTIVE=N на проде → Delete на staging → фасет и тест B90.
- OnBeforeIBlockPropertyDelete с ThrowException отменяет Delete.
CIBlockProperty::Delete($propId)только после GetList на копии.
Делайте: Delete только для legacy без данных. Не делайте: Delete вместо SetPropertyValuesEx(false).
Сравните Delete, SetPropertyValuesEx, Element::Update и ACTIVE=N
| Задача | Метод | Результат |
|---|---|---|
| Убрать поле из схемы и БД | CIBlockProperty::Delete | Свойство и все значения удалены |
| Очистить цвет у товара #123 | SetPropertyValuesEx(['COLOR' => false]) | Значение пусто, свойство COLOR есть |
| Скрыть legacy-поле на проде | Update ACTIVE=N | Не в админке, данные в БД |
| Поменять название товара | CIBlockElement::Update | Элемент, не схема свойства (B40) |
Делайте: выбирайте метод по таблице перед любым скриптом чистки. Не делайте: массовый Delete в проде без ACTIVE=N и бэкапа.
Подключите события OnBeforeIBlockPropertyUpdate и миграции
OnBeforeIBlockPropertyUpdate блокирует смену CODE на проде; OnBeforeIBlockPropertyDelete - страховка от Delete. В arrilot/bitrix-migrations update() бросает LAST_ERROR; deleteIblockElementPropertyByCode() - GetList по CODE и Delete.
Проверьте чек-лист после Update и Delete на staging
Финальный контроль перед merge в main:
- GetList подтверждает новые NAME, CODE, SMART_FILTER или отсутствие свойства после Delete.
- LAST_ERROR пуст при успешном Update; при false - текст в логе миграции.
- Для списка L: GetPropertyEnum до/после - enum не пропали.
- Фасетный индекс пересоздан; умный фильтр на витрине показывает поле; тестовый элемент через CIBlockElement::Add (B90) записывается в оставшиеся свойства без ошибок.
Облачный Bitrix24 здесь не применим - только коробочная CMS. Вопросы по цепочке Add → Update → Delete - обсудим проект. Кейсы миграций каталога - в портфолио.
Автор: Максим Мольков, разработчик 1С-Битрикс.
Источники: CIBlockProperty::Update, CIBlockProperty::Delete, CIBlockProperty::UpdateEnum, OnBeforeIBlockPropertyDelete.
Частые вопросы
Чем CIBlockProperty::Update отличается от Add?
Add создаёт новое свойство и возвращает ID. Update меняет уже существующее по числовому ID свойства: NAME, CODE, флаги SMART_FILTER и др. Для нового поля - Add (B93); для правки схемы - Update с IBLOCK_ID в arFields.
Можно ли изменить CODE свойства через Update?
Да, CODE передаётся в arFields Update. Но на проде это ломает шаблоны, импорт и PROPERTY_VALUES по старому коду. Блокируйте смену CODE в OnBeforeIBlockPropertyUpdate или делайте миграцию данных перед Update.
Почему SMART_FILTER не сохраняется при успешном Update?
Чаще всего в arFields CIBlockProperty::Update не передан IBLOCK_ID - метод возвращает true, галочка пустая, LAST_ERROR молчит. Второй случай: SECTION_PROPERTY=N у инфоблока. Проверьте CIBlock::GetArrayByID и CIBlockSectionPropertyLink::Add для разделов.
Удаляются ли значения элементов при CIBlockProperty::Delete?
Да, Delete каскадно удаляет все значения этого свойства у всех элементов инфоблока, enum-варианты, связи с разделами и колонки в prop_s. Для очистки одного товара используйте SetPropertyValuesEx с false, не Delete.
Когда использовать UpdateEnum, а не VALUES в Update?
UpdateEnum - для точечной правки списка PROPERTY_TYPE=L: добавить вариант, сохранить старые ID. VALUES в Update - при создании свойства или полной замене списка. Перед UpdateEnum снимите GetPropertyEnum и передавайте полный массив - подробнее в B88.
Когда Delete опасен на проде?
При любом свойстве с живыми данными каталога. Порядок: бэкап, staging с копией, ACTIVE=N на проде, проверка фасета и фильтра, Delete только если поле точно не нужно. OnBeforeIBlockPropertyDelete может отменить удаление через ThrowException.
Было полезно?
Поставьте лайк, если статья помогла разобраться.
Поделиться статьёй
Отправьте тому, кому это пригодится.
Можно поделиться и фрагментом: выделите текст статьи.