Импорт/Экспорт товаров в virtuemart 2.0

История импорта/экспорта началась, как всегда, в один прекрасный день:
был старый сайт, на собственном движке и собственной базой данных на 60 товаров. И при переезде на новый, с joomla и virtuemart’ом, остро встал вопрос о том, как перетащить все товары разом. Вариант с ручным переносом отпадал сразу, ибо лень. Через некоторое время, потраченное на ковыряние базы данных virtuemart, было найдено простое, хоть и не совсем элегантное решение. Описание этого решения и пойдет ниже.

База данных Virtuemart 2.0

Нам нужна не вся БД, а только некоторые таблицы.

На всякий случай напомню что речь идет именно о втором виртумарте. Первый я уже не застала, но, думаю, что если там такой же порядок таблиц и связей между ними, то мой импорт/экспорт можно использовать и для первой версии.

Итак, поехали рассматривать нужные нам таблицы. Сразу оговорюсь что буду комментировать только необходимые для заполнения строки, значения по умолчанию, остаются значениями оп умолчанию.

jos_virtemart_products

  • virtuemart_product_id = autoincrement
  • virtuemart_vendor_id = 1 (у меня только один вендор — мы сами)
  • product_parent_id = 0
  • product_sku = sku-товара/артикул, 64 знака, уникальное
  • product_weight = 0.000 (нет у меня веса, если есть необходимость — заполняется)
  • product_weight_nom = GR (вес в граммах)
  • product_length = 0.000 (с длиной, как и с весом)
  • product_width = 0.000
  • product_height = 0.000
  • product_lwh_nom = MM
  • product_url = ‘ ‘ (пустой, генерируется сам в недрах виртумарта)
  • product_in_stock = 0 (количество на складе, надо — вносите)

jos_virtemart_products_ru_ru

  • virtuemart_product_id = ID из предыдущей таблицы
  • product_s_desc = короткое описание
  • product_desc = длинное описание
  • product_name = заголовок — название продукта (180 символов)
  • metadesc = ‘ ‘ (пустое, мне не до SEO)
  • metakey = ‘ ‘ (аналогично)
  • customtitle = ‘ ‘
  • slug = product_name на транслите. (значительно можно упростить, если писать sku)

jos_virtemart_product_medias

  • id = autoincrement
  • virtuemart_prodict_id = ID товара из jos_virtemart_products
  • virtuemart_media_id = ID изображения из jos_virtemart_medias
  • ordering = 1,2,3,4… (в зависимости от кол-ва картинок к данному товару: 1-е изображение — ordering=1, 2-e — ordering=2, 3-e — ordering=3 и т.д.)

jos_virtemart_medias

  • virtuemart_media_id = autoincrement
  • virtuemart_vendor_id = 1 (у меня один вендор)
  • file_title = ‘1.jpg’ (название файла изображения)
  • file_description = ‘ ‘ (пустое)
  • file_meta = ‘ ‘
  • file_mimetype = ‘image/jpeg’ (тип файла, если png — image/png)
  • file_type = product (это тип для продуктов)
  • file_url = path/to/img/1.jpg (путь к файлу на сервере)
  • file_url_thumb = path/to/img/1_90x90.jpg (путь к превьюшке)
  • file_is_product_img = 0
  • file_is_download = 0
  • file_for_sale = 0
  • file_param = ‘ ‘
  • shared = 0
  • published =1
  • created_on = ‘0000-00-00 00:00:00’
  • created_by = (id юзера или админа, кто создал запись)
  • modified_on = ‘2012-08-13 10:10:10’
  • modified_by = (id юзера или админа, кто создал запись)
  • locked_on = ‘0000-00-00 00:00:00’
  • locked_by = 0

jos_virtemart_product_prices

  • virtuemart_product_price_id = autoincrement
  • product_id = ID продукта из jos_virtemart_products
  • остальные поля для этой таблицы не трогаю, т.к. цены меня не интересуют.

Соответственно, импорт/экспорт товаров в виртумарте затрагивает только следующие 5 таблиц:

  • jos_virtemart_products
  • jos_virtemart_products_ru_ru
  • jos_virtemart_product_medias
  • jos_virtemart_product_prices
  • jos_virtemart_medias

Импорт

Сам импорт идет по следующей схеме:

  1. Создаем продукт в jos_virtuemart_products
  2. Запоминаем ID созданного продукта
  3. В jos_virtuemart_products_ru_ru вносим описание по полученному ID
  4. В jos_virtuemart_medias вносим картинки
  5. Запоминаем ID внесенного изображения
  6. В jos_virtuemart_product_medias вносим по ID товара ID изображения и ordering (в цикле, по кол-ву картинок)
  7. В jos_virtuemart_product_prices вносим по ID товара цены

Экспорт

Экспорт делается так:

  1. В цикле по порядку выбираем ID товара из jos_virtuemart_products
  2. Забираем описание из jos_virtuemart_products_ru_ru
  3. Забираем ID изображений из jos_virtuemart_product_medias
  4. Забираем изображения из jos_virtuemart_medias
  5. Из jos_virtuemart_product_prices забираем цены (если есть)
  6. Формируем из всего этого файл/таблицу/хэш-массив и т.п., с чем будем дальше работать.

Реализация

В завершение, покажу реализацию импорта товаров в virtuemart на php. Опущу подготовку таблиц для импорта, только основная рабочая часть:

$res = mysql_query('select * from tsubmain') or die(mysql_error());
while ($row = mysql_fetch_array($res))
{
$tname=$row['name'];
mysql_query("insert into jos_virtuemart_products (`product_sku`, `product_available_date`, `product_params`, `created_on`, `created_by`, `modified_on`, `modified_by`) values ('$tname', '2012-08-02 00:00:00', 'min_order_level="0"|max_order_level="0"|', '2012-08-02 12:24:51', 524, '2012-08-02 12:24:55', 524)") or die(mysql_error());
$last_product_id=mysql_insert_id(); //последний введенный ID
$short_desc=file_get_contents($row['sdesc']);
$long_desc=file_get_contents($row['desc']);
mysql_query("insert into jos_virtuemart_products_ru_ru (`virtuemart_product_id`, `product_s_desc`, `product_desc`, `product_name`, `slug`) values ('$last_product_id', '$short_desc', '$long_desc', '$tname', '$tname')") or die(mysql_error());
$file1_url='images/stories/virtuemart/product/'.$tname.'/1.jpg'; //папка с изображением называлась как sku - удобно
$file2_url='images/stories/virtuemart/product/'.$tname.'/2.jpg';
$file1_url_tn='images/stories/virtuemart/product/'.$tname.'/1_90x90.jpg';
$file2_url_tn='images/stories/virtuemart/product/'.$tname.'/2_90x90.jpg';
mysql_query("insert into jos_virtuemart_medias (`file_title`, `file_mimetype`, `file_type`, `file_url`, `file_url_thumb`, `modified_on`, `modified_by`) values ('1.jpg', 'image/jpeg', 'product', '$file1_url', '$file1_url_tn', '2012-08-13 10:00:53', 524)") or die(mysql_error());
$last_img1_id=mysql_insert_id();
mysql_query("insert into jos_virtuemart_medias (`file_title`, `file_mimetype`, `file_type`, `file_url`, `file_url_thumb`, `modified_on`, `modified_by`) values ('2.jpg', 'image/jpeg', 'product', '$file2_url', '$file2_url_tn', '2012-08-13 10:00:53', 524)") or die(mysql_error());
$last_img2_id=mysql_insert_id();
mysql_query("insert into jos_virtuemart_product_medias (`virtuemart_product_id`, `virtuemart_media_id`, `ordering`) values ('$last_product_id', '$last_img1_id', 1)") or die(mysql_error());
mysql_query("insert into jos_virtuemart_product_medias (`virtuemart_product_id`, `virtuemart_media_id`, `ordering`) values ('$last_product_id', '$last_img2_id', 2)") or die(mysql_error());
mysql_query("insert into jos_virtuemart_product_prices (`virtuemart_product_id`, `product_override_price`, `product_tax_id`, `product_discount_id`, `product_currency`, `modified_on`, `modified_by`) values ('$last_product_id', '0.00000', 0, 0, 131, '2012-08-13 07:01:08', 524)") or die(mysql_error());
}

Все, после этого заходим в Joomla и радуемся перенесенным товарам. И еще тому, что не пришлось все делать вручную.

Итог

Не в коем случае не буду спорить что предложенный алгоритм импорта/экспорта самый лучший. Скорее самый упрощенный.

У него есть свои недостатки:

  1. Нет проверки на уникальность sku (а если не уникальный — импорт останавливается и все приходится начинать заново, после переименовки)
  2. Длина в некоторых полях задана весьма строго, и тоже отсутствуют на это проверки
  3. Многие параметры, которые важны для интернет-магазина — длина-ширина-высота-цена — не заданы и не используются. Но это одно из меньших зол и его просто победить.

Много к чему еще можно придраться, но и доработать простенький скрипт тоже вполне по силам под свои нужды каждому, кто хоть немного знаком с php и mysql.

  • не увидел информации о добавлении информации о том в какой категории лежит товар <br />virtuemart_product_categories

  • Не вижу проблем в том, чтобы предварительно подготовить категории (ручками, ага), потом в таблицу добавить столбик с номерами категорий для данного товара (это уже можно не ручками, если будет не лень — напишу как можно быстро сделать) и сделать сакраментальное:<br />mysql_query(&quot;insert into virtuemart_product_categories (`virtuemart_product_id`, `virtuemart_category_id`, `ordering`) values