воскресенье, 15 мая 2011 г.

Особенности OnBeforeIBlockElementUpdate в Bitrix

В ходе работы сайта на Bitrix вдруг начали пропадать содержания статей.
Сначала я грешил на человеческий фактор, что кто-то случайно или специально удаляет содержания статей.

После недолгих разбирательств (создания истории изменений) выяснилось, что ошибка скорей техническая. Т.к. ошибку удалось локализовать, она проявлялась при привязки раздела к статье из списка элементов. Тогда как изменение раздела из самой статьи не приводило к ошибке.
Следующим этапом было штудирование файла init.php, где хранятся обработчики событий портала.
В файле init.php хранился обработчик, заменяющий текст статьи на другой в автоматическом режиме.
AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", Array("MyClass", "OnBeforeIBlockElementUpdateHandler"));

class MyClass
{
    function OnBeforeIBlockElementUpdateHandler(&$arFields)
    {
       $arFields["DETAIL_TEXT"] = str_replace('src="../../upload/', 'src="/upload/', $arFields["DETAIL_TEXT"]);
    }
}

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

Правильный код в этом случае выглядит так (т.е. необходима проверка существования поля):
AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", Array("MyClass", "OnBeforeIBlockElementUpdateHandler"));

class MyClass
{
    function OnBeforeIBlockElementUpdateHandler(&$arFields)
    {
        if(!empty($arFields["DETAIL_TEXT"])) {
          $arFields["DETAIL_TEXT"] = str_replace('src="../../upload/', 'src="/upload/', $arFields["DETAIL_TEXT"]);
        }
    }
}