При разработке сайтов на Битрикс, с интеграцией с 1С Управление Тороговлей, нужно запретить изменения полей при обмене. В частности, детальное описание и картинку товара.
Если вы используете 1C для выгрузки структуры каталога, цен, торговых предложений и свойств товаров на ваш сайт, а описания и картинки вы добавляете уже после выгрузки, то у вас могут возникнуть проблемы. При обмене данными, информация, добавленная на сайте, может быть перезаписана. Это происходит потому, что 1C "видит", что у товара нет описания (в своей базе), но на сайте оно присутствует, и поэтому происходит удаление этого товара.
Чтобы избежать такой ситуации, можно воспользоваться событиями OnBeforeIBlockElementUpdate и OnBeforeIBlockElementAdd. Для этого добавьте следующий код в файл /bitrix/php_interface/init.php (если файла нет, создайте его):
AddEventHandler("iblock", "OnBeforeIBlockElementUpdate","DoNotUpdate");
function DoNotUpdate(&$arFields)
{
if ($_REQUEST['mode'] == 'import') {
unset($arFields['PREVIEW_PICTURE']);
unset($arFields['DETAIL_PICTURE']);
unset($arFields['PREVIEW_TEXT']);
unset($arFields['DETAIL_TEXT']);
}
}
AddEventHandler("iblock", "OnBeforeIBlockElementAdd","DoNotAdd");
function DoNotAdd(&$arFields)
{
if ($_REQUEST['mode'] == 'import') {
unset($arFields['PREVIEW_PICTURE']);
unset($arFields['DETAIL_PICTURE']);
unset($arFields['PREVIEW_TEXT']);
unset($arFields['DETAIL_TEXT']);
}
}
В данном случае мы запретили изменение и добавление следующих полей: картинка анонса, детальная картинка, текст анонса и детальный текст. Путем добавления соответствующих строк вы можете запретить изменение любого поля товара.
Аналог на D7 для запрета изменений при обмене данными
Вы также можете использовать D7 для реализации запрета на изменение полей при обмене данными. Вот пример кода:
use Bitrix\Main\EventManager;
EventManager::getInstance()->addEventHandler(
'iblock',
'OnBeforeIBlockElementUpdate',
'DoNotUpdate'
);
EventManager::getInstance()->addEventHandler(
'iblock',
'OnBeforeIBlockElementAdd',
'DoNotAdd'
);
function DoNotUpdate(&$arFields)
{
if ($_REQUEST['mode'] == 'import') {
unset($arFields['PREVIEW_PICTURE']);
unset($arFields['DETAIL_PICTURE']);
unset($arFields['PREVIEW_TEXT']);
unset($arFields['DETAIL_TEXT']);
}
}
function DoNotAdd(&$arFields)
{
if ($_REQUEST['mode'] == 'import') {
unset($arFields['PREVIEW_PICTURE']);
unset($arFields['DETAIL_PICTURE']);
unset($arFields['PREVIEW_TEXT']);
unset($arFields['DETAIL_TEXT']);
}
}
Дополнено: изменение полей товара при обмене с 1С
Написано спустя какое-то время, в обсуждении к заметке описаны случаи когда нужно изменить информацию о товарах, а не о элементах (это немного разное).
Дополняю: обновление габаритов товаров после обмена с 1С, например нужно увеличить все габариты на 1000:
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "UpdateDimensionsAfterElementAddOrUpdate");
AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "UpdateDimensionsAfterElementAddOrUpdate");
function UpdateDimensionsAfterElementAddOrUpdate(&$arFields)
{
if (CModule::IncludeModule("iblock") && CModule::IncludeModule("catalog")) {
if ($_REQUEST['mode'] == 'import' || $_REQUEST['mode'] == 'update') {
// Обновление габаритов (увеличение на 1000 из 1С)
$arProduct = CCatalogProduct::GetByID($arFields['ID']);
if ($arProduct) {
$updatedFields = array(
'WIDTH' => $arProduct['WIDTH'] * 1000,
'LENGTH' => $arProduct['LENGTH'] * 1000,
'HEIGHT' => $arProduct['HEIGHT'] * 1000
);
CCatalogProduct::Update($arFields['ID'], $updatedFields);
}
}
}
}
В этом примере обработчик события UpdateDimensionsAfterElementAddOrUpdate будет срабатывать как при добавлении нового элемента, так и при его обновлении. Внутри обработчика происходит проверка на режим импорта или обновления, и соответственно выполняется обновление габаритов.
Информацию о товаре (как товаре) получаем и обновляем методами CCatalogProduct::GetByID и CCatalogProduct::Update