четверг, 28 марта 2013 г.

Как подогнать стандартный импорт из 1С под готовое решение из маркетплейс Битрикс

Недавно передо мной встала задача сделать, чтобы при импорте из 1С Предприятия в Битрикс, свойства товаров аккуратненько вставали туда, куда предполагается в одном из готовых решений маркетплейс. Решение - не мое. В маркетплейсе его уже нет, и партнера-разработчика тоже нет. Но заказчику это решение очень нравилось, и он хотел использовать именно его.

При стандартном же импорте данных из 1С свойства товаров, привязанные к справочникам в 1С, привязывались к элементу инфоблока, как списочные свойства, а для решения было нужно, чтобы они привязывались к элементам другого инфоблока по ID.

Сказать по правде, думала я над этой задачей долго – разные варианты в голове перебирала. Была мысль дать импорту отработать, как есть, а потом последним шагом все перераспределить. Но хотелось, конечно, чтобы данные сразу в процессе импорта попадали на свое место.

Пришла к выводу, что в данном случае стоит прибегнуть к наследованию и полиморфизму.

Что я сделала. Сначала, как обычно, скопировала компонент импорта в свое пространство имен, завела другой файл импорта, чтобы он обращался уже к моему компоненту, а не к стандартному. После этого объявила класс наследник для класса CIBlockCMLImport

Вот так:

class CIBlockCMLCustomImport extends CIBlockCMLImport
{

}

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

ImportProperties

В php 5 перегрузку делать очень просто – нужно в теле наследника написать перегружаемую функцию с тем же самым именем, что и в классе-предке. И тогда для объектов класса-наследника будет выполняться именно она. А для объектов предка – его старая функция. Это и есть полиморфизм.


Метод ImportProperties непосредственно формирует структуру и состав свойств инфоблока для импорта.

Я нашла там место, где формируется

$arProperty

и вместо вот этой строки

if($arP["VALUE"] == GetMessage("IBLOCK_XML2_TYPE_LIST"))
$arProperty["PROPERTY_TYPE"] = "L";

написала свой код, проверяющий создан ли инфоблок для хранения значений этого свойства, и если не создан – я его создаю. (проверяю по XML_ID). А так же сделала полю тип E вместо L.

Кстати, чтобы создалось свойство типа «привязка к элементу инфоблока», нужно еще указать для создаваемого свойства LINK_IBLOCK_ID – ID инфоблока, к которому привязывать.

$arProperty["PROPERTY_TYPE"] = "E";
$arProperty["LINK_IBLOCK_ID"] = $найденный_выше_код_инфоблока;

А потом ниже по коду, там где в стандартном методе заполнялся список списочного поля, я вместо этого заполняю инфоблоки.

Но это еще не все – потом я еще начала искать то место, где непосредственно записывалось для данного элемента значение данного поля и поняла, что нужно делать перегрузку и для метода ImportElement. Я перегрузила этот метод и в теле уже своего перегруженного метода после обработки свойств типа L дописала свою обработку для свойства типа E.

После того, как я перегрузила эти функции, я прошла по файлу components.php своего кастамизированного компонента и заменила там все конструкторы системного класса CIBlockCMLImport на конструкторы своего - CIBlockCMLCustomImport.

Потом уже после того, как скрипт импорта сформировал мне в новом инфоблоке нужную структуру, я открыла старый инфоблок и новый – и перенесла в старый инфоблок все параметры свойств, их внешние коды, внешний код самого каталога.

Потом я сделала то же самое со старыми инфоблоками брендов, материалов, подошв и т.д., к-е были ранее в решении. Новые инфоблоки поудаляла. И все – импорт пошел куда надо.

Кстати, на форуме частенько появляются вопросы из разряда «Почему 1С не хочет грузить в существующий инфоблок, а создает рядом такой же другой?» Потому что он не такой же. Забывают люди, что в настройках инфоблока на закладке свойств есть еще и кнопочка такая, кликнув по которой можно редактировать дополнительные параметры свойства, и большинство таких вопросов – от банальной невнимательности.

На словах – все просто, а отлаживать этот кастомизированный импорт было тяжковато.

Работу обмена эмулировала скрипом bx_1c_import.php Прописала в нем путь к своему файлу импорта и свой компонент импорта. В коде своих функций выводила отладочную информацию в лог-файл.

Нет ничего невозможного.

2 комментария:

Юрий комментирует...

Крутяк.

Юлия комментирует...

Спасибо