Если у вас возникли какие либо вопросы которые вы не смогли решить по нашим публикациям самостоятельно,
то ждем ваше обращение в нашей службе тех поддержки.
Перенос торгового каталога из другой системы
Встала передо мной задача: перенести имеющийся сайт (назовем его оригинальным) с неизвестной мне CMS (смотрел сервисом http://2ip.ru/cms/) на CMS 1C-Битрикс Управление сайтом "Малый бизнес" (назовем его как сайт-приемник). У CMS оригинала нет никаких средств по выгрузке каталога, поэтому пришлось писать свой обработчик.
Был доступ к PhpMyAdmin оригинального сайта и доступ в его админку, чтоб понять взаимосвязь между всеми полями каталога и таблицами базы данных. В результате - нашел интересующую меня таблицу.
Для простоты обработки данных сделал бекап базы с сайта и получил sql-файлик.
Далее - берем битриксовую виртуальную машину и устанавливаем ее на VM Player.
Проводим установку стандартной демки интернет-магазина на малом бизнесе.
Устанавливаем PhpMyAdmin (см. тут) и в нем поднимаем бекап ( просто я не на столько серьезный специалист в работе с Linux, поэтому пользовался данным средством. Знатоки Linux могут развернуть бекап базы и средствами линуха). Разворачиваем созданный на оригинальном сайте бекап базы.
Дальше переходим к разработке скрипта, который будет проводить перенос данных.
Сразу предупреждаю. Заказчики решили сделать всю разработку сначала на стандартном шаблоне битрикса, поэтому старался максимально использовать имеющиеся данные, в том числе и инфоблок с каталогом (единственное - добавил нужные мне поля).
Разделов на сайте - не много, поэтому не стал заморачиваться с созданием скрипта, который создаст мне разделы, а просто вручную внес их в инфоблоке.
В будущем скрипте прописываю функцию, в которой через switch прописываю взаимосвязи кодов разделов оригинального сайта и сайта-приемника.
Пишем аналогичные функции по обработке других свойств, которые описывают каталог списками выбора (разные цветовые характеристики, фиксированные размеры и т.п.)
Определяем 2 массива: массив $items - будет собирать данные из базы и $unic_codes - расскажу позже о нем.
Делаем соединение с базой, выгруженной из оригинального сайта.
//соединение с базой данных при помощи функции mysql_connect()
//в аргументах функции укажите имя сервера, логин и пароль.
$db = mysql_connect("localhost","ваш_пользователь","ваш_пароль");
//функция mysql_select_db() выбирает текущую
//базу данных с именем базы с данными с оригинального сайта
if(!mysql_select_db("ваша_база" ,$db)){echo "not connected"; die;}
//функция mysql_query() выполняет запрос на выборку данных
//результирующий набор данных хранится в переменной $sql
//LIMIT ограничение на количество выгружаемых полей
$sql = mysql_query("SEL ECT * FR OM `таблица_с_каталогом` LIMIT 0, 1000" ,$db);
//закрытие соединение (рекомендуется)*/
mysql_close($db);
Небольшие пояснения:
У меня в оригинальной базе 2074 единиц товара. При попытке перенести все за один раз - просто падал сервер (Для сервера выделял всего 512 метров ОЗУ), поэтому делал обрезки по 1000 и еще 1074 единиц (скрипт просто 2 раза запускал....)
Дальше обрабатываем полученную выгрузку:
while ($rows = mysql_fetch_row($sql))
$item=array(
"Cur_ID"=>$rows[0], /*текущий ИД*/
"Cat_id"=> SetSection($rows[2]), /*категория*/
....
тут разные свойства
....
"code"=>$rows[8], /*Артикул*/
"el_CODE"=>unic_it(translit_it($rows[8])),
"name"=>$name, /*Название*/
"cost"=>$rows[10], /*Стоимость*/
"descr_short"=>$rows[17], /*Анонсовое описание*/
"descr"=>$rows[18], /*Детальное описание*/
"photo"=>$det_picture, /*Детальное изображение*/
"photo"=>$an_picture, /*Анонсовое изображение*/
) ;
$items[]= $item;
}
Пояснения:
Для себя, для удобства решил пользоваться ассоциативным массивом (если хотите - можете и обычный использовать....). В переменную $item закидываем в соответствующие поля значения из базы (смотрел на нужные номера полей через print_r() ) а потом эту переменную добавляем ко всем остальным. По поводу поля el_CODE: это будет символьным кодом нашего товара. В него заливаю имя товара (транслитерированное), которое сразу проверяю на уникальность (столкнулся с тем, что есть несколько одинаковых по названию товаров....). Вот функция проверки на уникальность:
function unic_it($code){ //проверяем выбранный код на уникальность
global $unic_codes;
if (in_array($code, $unic_codes)){
$code = $code."a";
}
$unic_codes[]=$code;
return $code;
}
Данная функция на входе получает код. Ищет его в глобальном (для данного скрипта) массиве $unic_codes и если находит - добавляет к коду символ "а". Полученный в результате код добавляется к списку уникальных. Поля с изображениями делал переменными, т.к. мне нужно было делать сложные манипуляции с выбором изображения.
В общих чертах данные переменные выглядят так:
$det_picture=CFile::MakeFileArray("абсоллютный путь к папке с изобржениями на оригинальном сайте".$rows[19]);
В базе хранилось только имя изображения, а все изображения - в одной общей папке. Поэтому по имени изображения нахожу его на оригинальном сайте и создаю файловый архив данного изображения.
Вот в принципе и все. Массив с записями из базы готов.
Теперь нужно его занести в каталог сайта-приемника.
foreach($items as $item):
$el = new CIBlockElement; //определяем новый элемент
$PROP = array(); //задаем его свойства
$PROP[1] = <значение>;
и другие свойства
$arLoadProductArray = Array(
"MODIFIED_BY" => $USER->GetID(),
"IBLOCK_SECTION_ID" => $item["Cat_id"],
"IBLOCK_ID" => 3, /*тут ставите свой инфоблок*/
"PROPERTY_VALUES"=> $PROP,
"NAME" => $item["name"],
"CODE" => $item["el_CODE"],
"DETAIL_PICTURE" => $item["photo"],
"PREVIEW_PICTURE" => $item["photo_small"],
"ACTIVE" => "Y",
);
if($PRODUCT_ID = $el->Add($arLoadProductArray, false, false, true))
{
//echo "New ID: ".$PRODUCT_ID."<br />";
//добавляем количество товара и его цену
$PRICE_TYPE_ID = 1; //базовая валюта
$arFields = Array(
"PRODUCT_ID" => $PRODUCT_ID,
"CATALOG_GROUP_ID" => $PRICE_TYPE_ID,
"PRICE" => $item["cost"],
"CURRENCY" => "UAH" /*код валюты*/
);
$res = CPrice::GetList(
array(),
array(
"PRODUCT_ID" => $PRODUCT_ID,
"CATALOG_GROUP_ID" => $PRICE_TYPE_ID
)
);
if ($arr = $res->Fetch())
{
CPrice::Update($arr["ID"], $arFields);
}
else
{
CPrice::Add($arFields);
}
//добавляем количество на складе (по умолчанию = 1)
$arFields = array(
"ID" => $PRODUCT_ID,
"QUANTITY"=>1
);
if(CCatalogProduct::Add($arFields))
//echo "Добавили параметры товара к элементу каталога ".$PRODUCT_ID.'<br>';
continue;
else
echo 'Ошибка добавления параметров для '.$PRODUCT_ID.'<br>';
// конец добавления элемента
}
else {
echo "Error: ".$el->LAST_ERROR;
echo "<pre>"; print_r($arLoadProductArray); echo "</pre>";
}
endforeach;
Теперь по порядку: В цикле перебираем все элементы массива. На каждой итерации создаем ассоциативный массив $arLoadProductArray, который описывает все поля вновь создаваемого элемента.
Дальше если добавление прошло удачно - нужно задать стоимость данного товара и его количество.
Все это достаточно хорошо расписано в документации продукта, поэтому сильно расписывать не буду. Кого заинтересует - спрашивайте по коду - буду рассказывать.
Не забудьте в визуальной части сайта отметить добавленные вами свойства, чтобы пользователи тоже смогли их увидеть:)