Для того чтобы сделать экспорт (выгрузку) используем пакет catalogfill.
//разбивка по столбцам при импорте и экспорте (content|tv|category)
$cf_config['content_row'] = array(
array('RES_category',array(13,'category')),//3 - ID шаблона категории
array('RES_subcategory',array(13,'category')),//3 - ID шаблона подкатегории
array('RES_pagetitle',array('pagetitle','content')),
array('RES_introtext',array('introtext','content')),
array('RES_content',array('content','content')),
array('RES_uri',array('uri','content')),
array('RES_alias',array('alias','content')),
// Товар TV
array('TV_articul', array(16, 'tv')), // id Дополнительного поля
array('TV_available', array(32, 'tv')),
array('TV_id_similar', array(18, 'tv')),
array('TV_main_img', array(14, 'tv')),
array('TV_mark', array(19, 'tv')),
array('TV_other_img', array(17, 'tv')),
array('TV_price', array(15, 'tv')),
array('TV_price_1', array(35, 'tv')),
array('TV_price_10', array(22, 'tv')),
array('TV_price_100', array(24, 'tv')),
array('TV_price_5', array(21, 'tv')),
array('TV_price_50', array(23, 'tv')),
array('TV_price_500', array(25, 'tv')),
array('TV_specification', array(34, 'tv')),
array('TV_desc', array(30, 'tv')),
array('TV_key', array(29, 'tv')),
array('TV_tit', array(28, 'tv')),
array('HitsPage',array(31,'tv'))
);
//значения по умолчанию при импорте или проверка при экспорте
$cf_config['imp_content_default'] = array(
'content' => array(
'published' => 1,
'template' => array(4)
//'createdon' => strtotime("now")
),
'tv' => array(
//7 => 0
)
);
//первая строка - названия полей
$cf_config['include_captions'] = true;
//число товаров импортируемых за один раз (загрузка по группам). 0 - не ограничивать.
$cf_config['batch_import'] = 300;
//разбивать по категориям
$cf_config['include_categories'] = true;
//удалять дочерние категории при очистке и обновлении каталога
$cf_config['delete_subcategories'] = true;
//по какому полю проверять соответствие товара при обновлении. false - не проверять (очистка категории при обновлении).
$cf_config['imp_chk_field'] = 'pagetitle';
//проверять соответствие товара при обновлении по значению TV. Указать ID TV. false - не проверять (очистка категории при обновлении).
$cf_config['imp_chk_tvid_val'] = false;
//Добавлять товары, которые не найдены при обновлении по TV (imp_chk_tvid_val) или полю (imp_chk_field)
$cf_config['imp_if_not_exist'] = true;
//удалять HTML-теги при экспорте
$cf_config['exp_strip_tags'] = false;
//автоматически генерировать псевдоним (alias) при импорте
//false - выключено; true - генерировать с переводом в транслит; 'notranslit' - генерировать без перевода в транслит.
$cf_config['imp_autoalias'] = true;
//Изменить значения поля для всех вложенных товаров до начала импорта.
//Например можно отменить публикацию для всех товаров и публиковать только те, которые есть в новом прайс-листе.
//первый массив - какие поля и на какие значения менять, второй массив - условия которые нужно проверять (можно сделать пустым)
$cf_config['imp_before_change'] = false;//'[{"tv.inventory":0},{}]';//'[{"published":0},{"tv.pricename":"Поставщик1"}]';//false - для отмены
//удалить файл после экспорта (скачивания)
$cf_config['exp_delete_file'] = false;
//кодировка CSV-файла при экспорте
$cf_config['exp_csv_charset'] = 'UTF-8';//'windows-1251'
//Импортировать (обновлять) пустые значения
$cf_config['imp_empty'] = true;
//Имя файла процессора, который использовать для импорта. Если пусто, используется стандартный процессор "import".
$cf_config['imp_custom_processor'] = '';
//путь (xpath) в XML структуре до товаров
$cf_config['imp_xml_itemsparent_path'] = '';//'/catalog/shop/offers'
//Структура XML файла для импорта
$cf_config['imp_xml_structure'] = '';
//тестирование конфигурации (без записи в БД)
$cf_config['imp_testmode'] = false;
//функция для фильтрации значений при ИМПОРТЕ
function filter_import($value_arr){
$output_arr = $value_arr;
/*
if(isset($output_arr['content']['pagetitle']))
$output_arr['content']['pagetitle'] = mb_strtoupper($output_arr['content']['pagetitle'], 'UTF-8');
*/
return $output_arr;
}
//функция для фильтрации значений при ЭКСПОРТЕ
function filter_export($value_arr,$doc_id=0){
$output_arr = $value_arr;
//var_dump($value_arr,$output_arr);
//exit;
/*
if(isset($output_arr['price']))
$output_arr[1] = floatval($output_arr[1]) - 200;
*/
return $output_arr;
}
Экспортируем в CSV
Так как я переносил еще и картинки, и имел доступ к обоим серверам, то я просто скопировал их с одного сайта на другой через FTP клиент. Для этого я использовал вот этот нехитрый метод
Далее делаем импорт — загрузку полученных данных в магазин. Для этого я уже не использовал это дополнение, так как хотел четко контролировать что куда помещать.
В системе нового сайта создаем сниппет с поэтическим названием import_x
set_time_limit(0);
// !!! Отредактировать
$parent_id = 2722;
$template_id = 3;
$csv_file = "exp_10_03_18__12_53_40.csv";
// Получаем список УЖЕ импортированных нами ресурсов
$q = $modx->newQuery('modResource');
$q->select(array('pagetitle'));
$q->where(array(
'template' => $template_id,
'parent' => $parent_id
));
$q->limit(0);
$q->prepare();
$q->stmt->execute();
$res = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
$alredy_imp = array();
foreach($res as $v){
$alredy_imp[] = $v['pagetitle'];
}
// Обрабатываем файл CSV
$csv_file_open = fopen($csv_file, 'r');
// Формируем удобочитаемый массив с данными из CSV:
$arr_keys = array();
$prod_array = array();
while ( ($data = fgetcsv($csv_file_open, 0, ";") ) !== FALSE ) {
if($data[2] == "RES_pagetitle"){ // Таким странным образом определяем что это первая строка CSV файла
$arr_keys = $data;
}else{
$temp_array = array();
foreach($data as $k => $v){
$temp_array[$arr_keys[$k]] = $v;
}
$prod_array[] = $temp_array;
}
}
//print_r($prod_array);
//die;
$count = 0;
$hadErrors = false;
foreach($prod_array as $v){
//print_r($v);
$data = array();
$data['class_key'] = 'msProduct';
$data['pagetitle'] = $v['RES_pagetitle'];
// Проеверяем, не добавлен ли этот ресурс уже в систему (просто оп имени)
if(in_array($v['RES_pagetitle'], $alredy_imp)){
continue;
}
// Добавляем только 15 рексурсов
$count++;
if($count > 15){
break;
}
// Формируем соответствие полей - тут все индивидуально и надо править.
if(in_array($v['RES_pagetitle'], $names)){
$data['published'] = 0;
}else{
$data['published'] = 1;
}
$data['parent'] = $parent_id;
$data['template'] = $template_id;
$data['show_in_tree'] = '1';
$data['content'] = $v['RES_content'];
$data['description'] = $v['RES_category']." - ".$v['RES_subcategory'];
//Данные
if(!empty($v['TV_price'])){$data['price'] = $v['TV_price'];}
if(!empty($v['TV_price_1'])){$data['price1'] = $v['TV_price_1'];}
if(!empty($v['TV_price_10'])){$data['price10'] = $v['TV_price_10'];}
if(!empty($v['TV_price_100'])){$data['price100'] = $v['TV_price_100'];}
if(!empty($v['TV_price_5'])){$data['price5'] = $v['TV_price_5'];}
if(!empty($v['TV_price_50'])){$data['price50'] = $v['TV_price_50'];}
if(!empty($v['TV_price_500'])){$data['price500'] = $v['TV_price_500'];}
if(!empty($v['TV_mark'])){
$TV_mark = explode("||", $v['TV_mark']);
foreach($TV_mark as $v1){
switch($v1){
case 2:
$data['new'] = 1;
break;
case 3:
$data['popular'] = 1;
break;
}
}
}
/*
*** Эта область из другого импорта, но примеры значения полей могут быть полезны:
if($v['page_tags'] === 'хит' || $v['yml_param_recomend'] === "есть"){
$data['popular'] = 1;
}
if($v['page_tags'] === 'распродажа'){
$data['favorite'] = 1;
}
if($v['page_tags'] === 'новинка'){
$data['new'] = 1;
}
$data['vendor'] = $v['local_manuf_id'];
//стандартные опции товара
if(!empty($v['yml_param_color'])){
$data['color'] = $v['yml_param_color'];
}
$data['size'] = '';
$data['tags'] = '';
свои опции созданные в настройках MiniShop2
if(!empty($v['yml_param_less70'])){
$data['options-cups'] = "до 70";
}
if(!empty($v['yml_param_more70'])){
$data['options-cups'] = "от 70";
}
if(!empty($v['yml_param_capuchinator'])){
$data['options-capuchinator'] = $v['yml_param_capuchinator'];
}
if((int)$v['exist_topvar'] === 0){
$data['options-exist'] = "Нет в наличии";
}
*/
//TV
if(!empty($v['TV_specification'])){$data['tv3'] = $v['TV_specification'];} // 3 в "tv3" это id TV
if(!empty($v['TV_key'])){$data['tv1'] = $v['TV_key'];}
if(!empty($v['TV_desc'])){$data['tv2'] = $v['TV_desc'];}
// Формирование массива с фотографиями
$product_images = array();
if(!empty($v['TV_main_img'])){
$imgName = $v['TV_main_img'];
if(strpos($imgName,"items/") === false){
$imgName = "items/".$imgName;
}
$product_images[] = "userimg/".$imgName;
}
if(!empty($v['TV_other_img'])){
$TV_other_img = json_decode($v['TV_other_img'], true);
foreach($TV_other_img as $k => $v){
$imgName = $v['images'];
if(strpos($imgName,"items/") === false){
$imgName = "items/".$imgName;
}
$product_images[] = "userimg/".$imgName;
}
}
//print_r($data);
//print_r($product_images);
//continue;
// Запуск создания ресурса
$response = $modx->runProcessor('resource/create', $data);
/////////////////////////////////////////
if ($response->isError()) {
$hadErrors = true;
echo __LINE__."\r\n";
echo "<pre>".print_r($response->getResponse(), true)."</pre>";
$id = false;
}else{
$id = $response->response['object']['id']; //id товара
echo $id."
\r\n";
}
if(count($product_images) && $id){ // Если все Окей - добавляем картинки
foreach($product_images as $img){
$imgPath = MODX_BASE_PATH.$img;
// Проверям - существует ли файл
if(!is_file($imgPath)) {
echo "файл ".$img." не найден";
continue;
}
// Особая магия загрузки картинок по API в галерею MiniShop2
$gallery = array(
'id' => $id,
'name' => basename($imgPath),
'file' => $imgPath
);
$upload = $modx->runProcessor('gallery/upload', $gallery, array(
'processors_path' => MODX_CORE_PATH.'components/minishop2/processors/mgr/'
));
if ($upload->isError()) {
$hadErrors = true;
echo __LINE__."\r\n";
echo $imgPath."\r\n";
echo "<pre>".print_r($upload->getResponse(), true)."</pre>";
}
}
}
}
if(!$hadErrors){
echo "<script>location.reload();</script>"; // Так как операция рексурсоемкая, делаем автоматизацию на JS - если нет ошибок, перезагружаем страницу
}
Комментарии (1)
Не писать ответ