Исправляем редкий случай массовой очистки свойств товара
Последние записи
Хостинг для сайта
Если выбираете хостинг под проект — советую Timeweb. Современная инфраструктура, широкий выбор тарифов от стартовых до VPS под нагрузку, отзывчивая техподдержка, которая отвечает по существу, а не отписками. Я сам держу на нём часть своих проектов и рекомендую клиентам.
Перейти Партнёрская ссылка. Для вас цена не меняется.Внезапная очистка свойств товаров в Битриксе: разбор инцидента
Ситуация: у ряда товаров (каждый раз новых) как по таймеру по 1-2 раза в час в инфоблоке внезапно стирались почти все свойства — артикулы, материалы, размеры, названия. Оставались только «ID поста блога для комментариев» и картинки галереи. Картина выглядит как массовое повреждение данных или работа чужого скрипта, но на самом деле причина в штатной функции, которая годами стояла и молча портила данные. Ниже — краткий разбор.
Симптом
- У товара остаются заполненными только два поля: ID поста блога для комментариев и картинки галереи. Всё остальное — пусто.
- Пострадавшие товары каждый раз новые, но всегда относятся к конкретным завершённым заказам, а не ко всему каталогу.
- Срабатывает как по таймеру: 1-2 раза в час, с привязкой к активности покупателей.
- Проблема наблюдается на свежих версиях ядра
Битриксв связке со старым шаблономАспро.
Причина
Виноват компонент оценок товаров vote.products.lite из шаблона Аспро. Логика такая: покупатель получил заказ, сайт предлагает ему оценить купленные товары в личном кабинете. Чтобы запомнить, какой товар оценён, код записывает в карточку товара номер отзыва.
Ошибка в том, как именно он это делает. Вместо «добавь номер отзыва к свойствам» код фактически говорит сайту «вот полный список свойств товара — запиши его». А в списке — только номер отзыва. Сайт послушно перезаписывает свойства и стирает всё, чего в списке нет. Картинки уцелевают, потому что хранятся отдельно, в поле картинок галереи.
Срабатывает не по отдельному запросу, а как побочный эффект обычной загрузки страницы личного кабинета. Каждый раз, когда покупатель заходит оценивать товары из оплаченного заказа, компонент находит товары без оценок, создаёт им посты блога и портит свойства.
Почему access.log не помог
Порча выглядела как обычный GET /personal/ 200 — заурядный заход покупателя в личный кабинет. Ни POST-запроса к свойствам, ни ошибок, ни логинов админа в логе нет. Логика компонента срабатывала внутри PHP при отрисовке страницы, и в access.log это не отличить от миллионов других заходов.
Косвенное подтверждение всё же нашлось: браузер покупателя в ту же секунду запрашивал иконки icons.svg именно из шаблона vote.products.lite с реферером /personal/. То есть блок оценок реально отрисовался, компонент сработал, посты созданы и свойства стёрты.
Работающее направление расследования — не access.log, а журналы самой базы (какие элементы и когда менялись) и журнал событий Битрикс. Только там видно, что именно сделал код внутри запроса.
Что сделали
Решением стала замена метода записи свойств. Вместо CIBlockElement::SetPropertyValues, который перезаписывает весь набор свойств элемента, используется CIBlockElement::SetPropertyValuesEx — он обновляет только переданные свойства и не трогает остальные.
Было:
\CIBlockElement::SetPropertyValues(
$arItem['ID'],
$arItem['IBLOCK_ID'],
[
\CIBlockPropertyTools::CODE_BLOG_POST => $postId,
]
);
Стало:
\CIBlockElement::SetPropertyValuesEx(
$arItem['ID'],
$arItem['IBLOCK_ID'],
[
\CIBlockPropertyTools::CODE_BLOG_POST => $postId,
]
);
Помимо правки метода:
- Функцию оценок полностью выключили — пока шаблон не обновлён, она не работает.
- Пострадавшие товары восстановили из резервной копии базы.
- Поставили сторожа: раз в пять минут проверяет карточки и пишет в лог, если что-то подобное повторится.
Отдельная ложная версия, которая всплывала в процессе: следы «adminimum» на карточках. Оказалось, это старый след от обмена с 1С под учётной записью интегратора. К инциденту отношения не имеет.
Что проверить у себя
- Версия шаблона
Аспров вашем проекте. Если шаблон старый, а ядроБитрикссвежее — риск такой же. - Наличие компонента
vote.products.liteи его настройки в личном кабинете покупателя. - Использование
CIBlockElement::SetPropertyValuesв коде проекта и шаблонов — этот метод перезаписывает свойства целиком и легко стирает данные, если в массиве не весь набор. Для точечного обновления нуженSetPropertyValuesEx. - Журнал изменений элементов инфоблока и журнал событий
Битрикс— там видны следы подобных «тихих» перезаписей, которые не отражаются в access.log. - Актуальность резервных копий базы. В разборе именно бэкап позволил восстановить свойства.
Комментарии