г. Санкт-Петербург
Войти
Логин
Пароль
Зарегистрироваться
После регистрации на сайте вам будет доступно отслеживание состояния заказов, личный кабинет и другие новые возможности
Заказать звонок
Логин
Пароль
Зарегистрироваться
После регистрации на сайте вам будет доступно отслеживание состояния заказов, личный кабинет и другие новые возможности
Логин
Пароль
Зарегистрироваться
После регистрации на сайте вам будет доступно отслеживание состояния заказов, личный кабинет и другие новые возможности

RSS
О событиях, которые возникают при импорте каталога из 1С в Битрикс
 
О событиях, которые возникают при импорте каталога из 1С в Битрикс

В контексте интеграции 1С Предприятия и Битрикс не утихают споры по поводу того, какие события при этом отрабатывают, а какие не отрабатывают. А спорить, в общем-то, не о чем – благо, Битрикс поставляется нам в исходных кодах.
Класс импорта CIBlockCMLImport, который я так люблю наследовать, описан в файле
\bitrix\modules\iblock\classes\general\cml2
Открыв этот файл, мы ясно видим, что элементы инфоблока товаров, как и элементы инфоблока предложений добавляются функцией CIBlockElement::Add
, а изменяются функцией CIBlockElement::Update

Исходные коды этих функций мы можем посмотреть в файлах (в одном описан класс CAllIBlockElement в другом – его наследник CIBlockElement)
\bitrix\modules\iblock\classes\general\iblockelement.php
\bitrix\modules\iblock\classes\mysql\iblockelement.php

Что же мы видим там?
В функции Add имеется вот такая конструкция – перед самым сбросом управляемого кеша:

$events = GetModuleEvents("iblock", "OnAfterIBlockElementAdd");
while ($arEvent = $events->Fetch())
ExecuteModuleEventEx($arEvent, array(&$arFields));

То есть вызывается и отрабатывает событие OnAfterIBlockElementAdd Причем каждый из описанных обработчиков этого события. Как мы можем видеть, вызов этого события происходит всегда – безусловно, то есть каждый раз при отработке функции CIBlockElement::Add и не важно, вызвана ли она в классе импорта или где-то еще.

Кроме этого в этой же функции вызывается другое событие

if(!isset($arFields["WF_PARENT_ELEMENT_ID"]) && $arIBlock["FIELDS"]["LOG_ELEMENT_ADD"]["IS_REQUIRED"] == "Y")
{
$USER_ID = is_object($USER)? intval($USER->GetID()) : 0;
$db_events = GetModuleEvents("main", "OnBeforeEventLog");
$arEvent = $db_events->Fetch();

}Но не каждый раз, а по условию. Это не что иное, как событие при записи в журнал событий. И оно выполняется, если в настройках инфоблока указано журналировать добавление элемента.

А вот вызова события OnBeforeIBlockElementAdd я в функции Add не нашла (оно там есть, но вызвано не напрямую). Нет его и в классе импорта CIBlockCMLImport

Посмотрим теперь, что у нас имеется в функции CIBlockElement::Update

$events = GetModuleEvents("iblock", "OnAfterIBlockElementUpdate");
while ($arEvent = $events->Fetch())
ExecuteModuleEventEx($arEvent, array(&$arFields));

Вызов события OnAfterIBlockElementUpdate – имеется
Вызова события OnBeforeIBlockElementUpdate – не имеется

Зато вызовы событий OnBeforeIBlockElementUpdate и OnBeforeIBlockElementAdd присутствует в методе класса CAllIBlockElement CheckFields, который в свою очередь вызывается и в Add, и в Update Но функция CheckFields вызывается в них уже по условию.

Из вышесказанного я делаю следующие выводы: безусловно, при импорте каталога из 1С Предприятия в Битрикс отрабатывают обработчики событий OnAfterIBlockElementAdd и OnAfterIBlockElementUpdate, они отрабатывают уже после вставки/обновления элемента и, в принципе, могут быть использованы для модификации данных в инфоблоке, но ценой дополнительных запросов к базе. А дополнительные запросы к базе при импорте – это порой убийство импорта.

События OnBeforeIBlockElementUpdate и OnBeforeIBlockElementAdd так же могут отрабатывать при импорте при определенных условиях, однако уже по тому, каким образом они вставлены в исходный код битрикс, видно, что они задуманы не для модификации данных перед вставкой/обновлением, а для какой-то необычной кастомной проверки, возможно, какого-то поля необычного формата.

Поэтому, как я уже писала в одной из предыдущих статей, мне однозначно не нравится кастомизация импорта посредством использования этих событий – я для этих целей предпочитаю кастомизировать компонент импорта и наследовать класс CIBlockCMLImport, добавив наследнику требуемый функционал. Еще лучшим решением было бы конечно, написание, композитного класса, но это очень трудоемко. (Кстати, как видно из исходных кодов, разработчики Битрикс не гнушаются использовать наследование, значит и нам – сам Бог велел).

О событиях, возникающих при добавлении/обновлении раздела инфоблока, а так же при обновлении/добавлении цены товара я писать здесь не буду – нужно вклиниться в них – открываем исходники и смотрим, где они и как.

О событии
foreach(GetModuleEvents("catalog", "OnSuccessCatalogImport1C", true) as $arEvent)
ExecuteModuleEventEx($arEvent);которое Битриксоиды вставили прямо на последний шаг работы своего стандартного компонента импорта из 1С, наверное, знают все. Но если вы используете его для кастомизации импорта … это плохо.

Единственное, что можно безболезненно повесить на это событие – это, к примеру, отправку письма администратору сайта о том, что импорт успешно завершен или что-то иное в этом роде. Но, к примеру, обходить в обработчике этого события весь многотысячный каталог и что-то там перераспределять – пересчитывать…. я думаю, все уже поняли, каково мое мнение на этот счет, так что я воздержусь от нелитературных выражений.

Я думаю, к интеграции 1С Предприятия и Битрикс нельзя подходить по принципу «если работает, то ничего не нужно менять». Нужно оптимизировать, оптимизировать и еще раз оптимизировать.

статья взята с сайта: http://bedrosova.blogspot.com/2013/04/1.html