четверг, 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 Прописала в нем путь к своему файлу импорта и свой компонент импорта. В коде своих функций выводила отладочную информацию в лог-файл.

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

вторник, 26 марта 2013 г.

Как добавить в магазин на Битрикс возможность импорта из нового формата данных

Помогая своим близким друзьям делать интернет магазин, я столкнулась с задачей импорта данных в Битрикс из формата YML (из формата файлов, который обычно применяется для экспорта в Яндекс.Маркет). За деньги, наверное, не согласилась бы писать такой импорт. А по дружбе – святое дело, и я стала копать. И очень интересные вещи накопала, которые, как ни странно, слабо освещены в документации 1С Битрикс.

А вещи элементарные на самом деле. Оказывается, чтобы добавить возможность собственного импорта в магазин на Битрикс, достаточно добавить в директорию

bitrix/php_interface/include/catalog_import

Два файла

имя_нового _импорта_setup.php – с настройками импорта
имя_нового _импорта _run.php – собственно импорт

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

После того, как эти 2 файла добавлены, система САМА добавляет новый вид импорта в админку на страницу импорта товаров в магазин (/bitrix/admin/cat_import_setup.php) – пометила на рисунке зеленой стрелочке.

А вот оранжевой стрелочкой я пометила результат своего эксперимента с  функцией CCatalogImport::Add  Страница с документацией по этой функции пока практически пуста, но читая код  ядра, я поняла, что она применяется для добавления нового профиля для того или иного вида импорта, позволяет добавить его в меню или посадить на крон.

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