Last active
October 14, 2019 23:59
-
-
Save andronex/6b9bdbd546acfed3a799793c3be94568 to your computer and use it in GitHub Desktop.
Парсер товаров для импорта с oasiscatalog (аналог gifts.ru) для MODX Revolution v.2.6+ и miniShop2 v.2.4.10+
В связи с участившимися случаями обращения ко мне с вопросами по работе данного скрипта импорта товаров с https://www.oasiscatalog.com/ на сайты, работающие на MODX Revolution в связке с miniShop2 или без таковой, сообщаю расценки на услуги разработки любых парсеров данных, в том числе на доработку/интеграцию данного скрипта парсера под ваши нужды и под ваш проект. Подробности и минимальная цена здесь https://vk.com/modxrevo?w=product-77410673_1198119
/*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*/ /*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//настройки для коннекта к oasiscatalog.com | |
$apiKey = '***********e64837b3502915***********'; // ключ доступа | |
$oasisUrlTree = 'https://api.oasiscatalog.com/v4/categories?format=json'; | |
$oasisUrlProducts = 'https://api.oasiscatalog.com/v4/products?format=json&fieldset=full&fields=id,article,article_base,size,size_sort,stock_msk,attributes¬_on_order=1'; | |
$oasisUrlProduct = 'https://api.oasiscatalog.com/v4/products/{PRODUCT_ID}'; | |
//настройки для парсинга и установки шаблонов для создаваемых продуктов | |
$fileProductGroups = dirname(__FILE__).'/oasis_groups.txt'; | |
$fileCatExist = dirname(__FILE__).'/oasis_category_exist.txt'; | |
//настройки для обработки товаров | |
$tplProduct = 6;//номер шаблона для карточки товара | |
$numOffset = 5;//число товаров для загрузки за 1 проход парсера | |
$tplParent = 4;//номер шаблона для категорий | |
$tplChildParent = 4;//номер шаблона для подкатегорий | |
$idParent = 10;//id каталога товаров | |
$categoryArticleTVnumber = 'tv8';//ID TV поля для записи уникального идентификатора категории товаров для последующего сравнения с деревом категорий поставщика | |
$tag = 'oas_'; | |
//МЕТА поля массовые | |
$longtitle = ', цены в Москве, заказать оптом'; | |
$description = '. Достойный подарок - наша компания наносит логотипы и фирменный стиль на любые товары.'; | |
//API ключ для Яндекс переводчика, получить здесь https://tech.yandex.ru/translate/ | |
$apiYaTranslate = 'trnsl.1.1.20180130T145256Z.47c918f5ef8f8d90.b70043c53e0c440bb752c8df1f90829410aed9fd'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
** запускать с параметром /oasis_parser.php?tree=1 | |
*/ | |
//ini_set('display_errors', 1); | |
//ini_set('error_reporting', -1); | |
//error_reporting(E_ALL); | |
require_once(dirname(__FILE__).'/oasis_config.php'); | |
//функция запроса к серверу | |
function get_json_massive( $url ){ | |
global $apiKey; | |
$apiUrl = $url; | |
$headers = [ | |
'Accept:application/json', | |
]; | |
$resource = curl_init(); | |
curl_setopt_array($resource, [ | |
CURLOPT_URL => $apiUrl, // URL текущего запроса к сервису | |
CURLOPT_HEADER => true, // указать сервису включить заголовки в ответ | |
CURLOPT_HTTPHEADER => $headers, // массив заголовков для отправки запроса | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_USERPWD => $apiKey, // ключ доступа | |
CURLOPT_TIMEOUT => 30, | |
]); | |
$response = curl_exec($resource); | |
$headerSize = curl_getinfo($resource, CURLINFO_HEADER_SIZE); | |
$header = substr($response, 0, $headerSize); // отделяем заголовки ответа | |
$body = substr($response, $headerSize); // сохраняем непосредственно тело ответа | |
curl_close($resource); | |
return json_decode($body, true); | |
} | |
//функция рекурсивной проверки наличия ключа массива | |
function array_key_exists_recursive($key, $arr) { | |
if (array_key_exists($key, $arr)) { | |
return true; | |
} | |
foreach ($arr as $curval) { | |
if (is_array($curval)) { | |
if (array_key_exists_recursive($key, $curval)) { | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
//функция рекурсивного парсинга страниц и построения структуры каталога | |
function parseCategory($oasisUrlTree){ | |
global $idParent; | |
$counter = ['new' => 0, 'upd' => 0, 'error' => 0]; | |
$tree = get_json_massive($oasisUrlTree); | |
foreach($tree as $item){ | |
$counter_category = createCategory($item, $tree, $idParent); | |
foreach($counter_category as $key => $val) { | |
$counter[$key] += $counter_category[$key]; | |
} | |
} | |
return ($counter)?echoStat($counter, 'категорий'):false; | |
} | |
//функция скачивания и сохранения картинок | |
function downloadImg($image, $urlImages){ | |
global $modx; | |
if (!file_exists(dirname(__FILE__).'/thumbs/'.$image)) { | |
$ch = curl_init($urlImages); | |
curl_setopt($ch, CURLOPT_HEADER, 0); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); | |
if(!file_put_contents(dirname(__FILE__).'/thumbs/'.$image, curl_exec($ch))){ | |
$modx->log(modX::LOG_LEVEL_ERROR, "Неудача при скачивании картинки товара {$urlImages}"); | |
return ''; | |
} | |
curl_close($ch); | |
} | |
return dirname(__FILE__).'/thumbs/'.$image; | |
} | |
define('MODX_API_MODE', true); | |
require_once dirname(dirname(__FILE__)).'/index.php'; | |
// Включаем обработку ошибок | |
$modx->getService('error','error.modError'); | |
$modx->setLogLevel(modX::LOG_LEVEL_ERROR); | |
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML'); | |
$modx->error->message = null; // Обнуляем переменную | |
//функция получения массива сопоставляемых категорий | |
function getCategoryManual(){ | |
global $fileCatExist; | |
$category_manual = array(); | |
if($in = @file_get_contents($fileCatExist)){ | |
$category_manual = unserialize($in); | |
} | |
unset($in); | |
return ($category_manual)?:''; | |
} | |
//функция нахождения категории в дереве категорий сайта | |
function getCatExists($article){ | |
global $categoryArticleTVnumber, $modx; | |
$where = $modx->newQuery('msCategory'); | |
$where->leftJoin('modTemplateVarResource', 'TemplateVarResources'); | |
$where->leftJoin('modTemplateVar', 'tv', "tv.id=TemplateVarResources.tmplvarid"); | |
$where->limit(1); | |
$where->where(array( | |
array( | |
'tv.id' => str_replace('tv', '', $categoryArticleTVnumber), | |
'TemplateVarResources.value' => $article | |
) | |
)); | |
return ($res = $modx->getObject('msCategory', $where))?$res->id:false; | |
} | |
//функция обращения к процессору создания категории | |
function createCatProcess($prop, $i = 1){ | |
global $modx, $categoryArticleTVnumber; | |
$response = $modx->runProcessor('resource/create', $prop); | |
$modx->log(1, print_r($response->response['object'], true)); | |
if ($response->isError()) { | |
print_r($modx->error->failure($response->getMessage())); | |
if($i == 1){ | |
print_r('Пробуем создать категорию с уникальным URI с учётом артикула категории'); | |
$prop['pagetitle'] = $prop['pagetitle'] . '-' . $prop[$categoryArticleTVnumber]; | |
return createCatProcess($prop, 2); | |
} | |
return false; | |
} | |
$res = $modx->getObject('msCategory', array('id' => $response->response['object']['id'])); | |
$res->set('pagetitle', str_replace('-' . $prop[$categoryArticleTVnumber], '', $res->pagetitle)); | |
$res->save(); | |
return $response->response['object']['id']; | |
} | |
//функция создания категорий | |
function createCategory($massiv, $tree, $parent, $template = null) { | |
//return 12;//временно | |
global $tplParent,$tplChildParent; | |
global $modx; | |
global $idParent,$categoryArticleTVnumber; | |
global $tag,$longtitle,$description; | |
$new = $upd = $err = 0; | |
if(!$parent) $parent = $idParent; | |
if(!$template) $template = $tplParent; | |
$create = false; | |
$path = explode('.', $massiv['ltree_path']); | |
foreach($path as $path_item){ | |
$article_cat = $tag . $path_item; | |
//проверка наличия категории в массиве сопоставления категорий | |
if($category_manual = getCategoryManual()){ | |
if(isset($category_manual[$path_item])){ | |
$article_cat = $category_manual[$path_item]['article']; | |
} | |
} | |
if($parent_tree = getCatExists($article_cat)){ | |
$parent = $parent_tree; | |
$create = false; | |
if($massiv['id'] == $path_item){ | |
$upd++; | |
} | |
continue; | |
} | |
else{ | |
$create = true; | |
foreach($tree as $tree_item){ | |
if($tree_item['id'] == $path_item){ | |
$tree_item = $tree_item; | |
break; | |
} | |
} | |
$prop = array( | |
'tvs' => true, | |
$categoryArticleTVnumber => $article_cat, | |
'parent' => $parent, | |
'class_key' => 'msCategory', | |
'pagetitle' => $tree_item['name'], | |
'template' => $template, | |
'published' => 1, | |
'context_key' => 'web', | |
'longtitle' => $tree_item['name'] . $longtitle, | |
'description' => $tree_item['name'] . $description, | |
); | |
} | |
if($create){ | |
$parent = ($tmp = createCatProcess($prop))?$tmp:$parent; | |
if($massiv['id'] == $path_item){ | |
if($tmp){ | |
$new++; | |
} | |
else{ | |
$err++; | |
} | |
} | |
} | |
} | |
return (array)['new' => $new, 'upd' => $upd, 'error' => $err]; | |
} | |
//функция вывода результатов | |
function echoStat($data, $text = 'товаров'){ | |
global $modx; | |
global $time; | |
$out = ''; | |
if (!XPDO_CLI_MODE) {$out = '<pre>';} | |
$summ = $data['new'] + $data['upd'] + $data['error']; | |
$out .= "\nИмпорт прошёл за ".number_format(microtime(true) - $modx->startTime, 7) . " сек.\n"; | |
$time = microtime(true); | |
$out .= "Итого обработано {$text}\n за проход: {$summ}\n обновлено из них: {$data['upd']}\n создано новых из них: {$data['new']}\n ошибок, в том числе пропущенных: {$data['error']}\n"; | |
//$out .= "Всего обработано {$text}: <a id='link' href='$URL_GET'><span id='offset'>$off_set</span></a>\n"; | |
return $out; | |
} | |
//функция получение перечня товаров | |
function getTreeGoods($oasisUrlProducts){ | |
global $tag,$time; | |
$result = []; | |
if($result_orig = get_json_massive($oasisUrlProducts)) { | |
foreach($result_orig as $item){ | |
//удаляем товар, если кол-во 0 или null | |
if($item['total_stock']){ | |
$result[] = $item; | |
} | |
} | |
unset($result_orig); | |
$file_tree = fopen(dirname(__FILE__)."/{$tag}goods.txt",'w+'); | |
if($file_tree) { | |
fwrite($file_tree, serialize($result)); | |
fclose($file_tree); | |
} | |
unset($file_tree); | |
} | |
return "\nНайдено товаров в каталоге поставщика: " . count($result) . "\nЗапрос занял: ".number_format(microtime(true) - $time, 7) . " сек.\n"; | |
} | |
//функция получение конкретного товара | |
function getInfoGood($oasisUrlProduct, $id_product){ | |
if($result = get_json_massive(str_replace('{PRODUCT_ID}', $id_product, $oasisUrlProduct))) { | |
return $result; | |
} | |
return false; | |
} | |
//функция добавления к товару картинок | |
function addImages($image, $res, $pagetitle){ | |
if ($image) { | |
global $modx; | |
$response_img = $modx->runProcessor('gallery/upload', | |
array('id' => $res->get('id'), 'name' => $pagetitle, 'file' => $image), | |
array('processors_path' => MODX_CORE_PATH.'components/minishop2/processors/mgr/') | |
); | |
if ($response_img->isError()) { | |
$modx->log(modX::LOG_LEVEL_ERROR, "Ошибка привязки картинки \"{$image}\" к товару id = {$res->get('id')}: \n". print_r($response_img->getAllErrors(), 1)); | |
} | |
else { | |
$sql = "UPDATE {$modx->getTableName('msProductFile')} SET `name` = \"{$pagetitle}\" WHERE `product_id` = {$res->get('id')};"; | |
$stmt = $modx->prepare($sql); | |
$stmt->execute(); | |
$stmt->closeCursor(); | |
unset($sql, $stmt); | |
unlink($image); | |
$modx->log(modX::LOG_LEVEL_INFO, "Удачно загружена картинка \"$image\": \n". print_r($response_img->getObject(), 1)); | |
return true; | |
} | |
} | |
return false; | |
} | |
//ф-ия создания новых ресурсов или получения ID уже созданных | |
function createProduct ($prop, $filtersArray = array()) { | |
//return 'upd';//временно | |
global $tplProduct, $tag; | |
global $modx; | |
$prop['pagetitle'] = $prop['pagetitle'] . '-' . $prop['article']; | |
$prop['tvs'] = true; | |
//print_r($prop); | |
$q = $modx->newQuery('msProduct'); | |
$q->select($modx->getSelectColumns('msProduct','msProduct').','.$modx->getSelectColumns('msProductData','Data').','.$modx->getSelectColumns('msProductOption','Option')); | |
$q->innerJoin('msProductData', 'Data', 'msProduct.id = Data.id'); | |
$q->rightJoin('msProductOption', 'Option', 'msProduct.id = Option.product_id'); | |
$q->where(array('Data.article' => $prop['article'])); | |
$q->prepare(); | |
if($res = $modx->getObject('msProduct', $q)) { | |
//print_r($res->toArray()); | |
//$prop['id'] = $artProd->contentid; | |
//$prop['pagetitle'] = $res->pagetitle; | |
//$prop['introtext'] = $res->introtext; | |
//$prop['content'] = $res->content; | |
//$prop['alias'] = $res->alias; | |
//$prop['parent'] = $res->parent; | |
//$prop['tv3'] = $prop['tv3']; | |
//$prop['tv4'] = $res->getTVValue('image'); | |
//$prop['tv6'] = $prop['tv6']; | |
//$prop['published'] = $prop['published']; | |
$prop['editedon'] = date("Y-m-d H:i:s"); | |
//print_r($res->toArray());exit; | |
//корректное пересохранение опций товара | |
$resdata = $res->getOne('Data'); | |
$optionKeys = $resdata->getOptionKeys(); | |
//$optionKeys = $res->getOptionKeys(); | |
$productData = $res->toArray(); | |
if(count($optionKeys) > 0) { | |
$productOption = array(); | |
foreach ($optionKeys as $key) { | |
if(is_array($productData[$key])) { | |
foreach ($productData[$key] as $dataOption) { | |
$productOption[] = '('.$res->get('id').',"'.$key.'","'.$dataOption.'")'; | |
} | |
} | |
else if(!empty($productData[$key])) $productOption[] = '('.$res->get('id').',"'.$key.'","'.$productData[$key].'")'; | |
} | |
} | |
if (!empty($productOption)) { | |
$productOption = array_unique($productOption); | |
$sql = 'DELETE FROM '.$modx->getTableName('msProductOption').' WHERE product_id = ' . $res->get('id').';'; | |
$stmt = $modx->prepare($sql); | |
$stmt->execute(); | |
$stmt->closeCursor(); | |
$sql = 'INSERT INTO '.$modx->getTableName('msProductOption').' (`product_id`,`key`,`value`) VALUES ' . implode(',', $productOption).';'; | |
$stmt = $modx->prepare($sql); | |
$stmt->execute(); | |
$stmt->closeCursor(); | |
} | |
//$res->set('content',$prop['content']); | |
$res->setTVValue(9,$prop['tv9']); | |
$res->setTVValue(10,$prop['tv10']); | |
$res->setTVValue(12,$prop['tv12']); | |
$res->setTVValue(14,$prop['tv14']); | |
$res->set('new',$prop['new']); | |
$res->set('popular',$prop['popular']); | |
//$res->set('favorite',$prop['favorite']); | |
$res->set('editedon',$prop['editedon']); | |
$res->set('published',$prop['published']); | |
$res->set('price', $prop['price']); | |
$res->save(); | |
//удаление картинок | |
if(isset($prop['images'])){ | |
foreach($prop['images'] as $imgs){ | |
if(file_exists($imgs)) unlink($imgs); | |
} | |
} | |
return 'upd'; | |
} | |
$modx->error->message = null; | |
$response = $modx->runProcessor('resource/create', $prop, | |
array('processors_path' => MODX_CORE_PATH.'model/modx/processors/') | |
); | |
if ($response->isError()) { | |
$modx->log(1, print_r($response->getAllErrors(), true)); | |
return 'error'; | |
} | |
$resource = $response->getObject(); | |
//удаление из pagetitle артикулов, нужных на стадии создания товара для формирования alias ресурса | |
$res = $modx->getObject('msProduct', array('id' => $resource['id'])); | |
$res->set('pagetitle', str_replace('-' . $prop['article'], '', $res->get('pagetitle'))); | |
$res->save(); | |
//доп. категории только если их более одной в массиве $prop['parents'] | |
if($prop['parents']){ | |
foreach ($prop['parents'] as $catProduct){ | |
$category = $modx->newObject('msCategoryMember'); | |
$category->set('category_id', $catProduct); | |
$category->set('product_id', $resource['id']); | |
$category->save(); | |
} | |
} | |
//привязка фильтров к товару и к категории товара из массива фильтров товара $filtersArray | |
if($filtersArray){ | |
foreach($filtersArray as $keyF => $valsF){ | |
foreach($valsF as $valF){ | |
$optionProduct = $modx->newObject('msProductOption'); | |
$optionProduct->set('product_id', $resource['id']); | |
$optionProduct->set('key', $keyF); | |
$optionProduct->set('value', $valF); | |
$optionProduct->save(); | |
} | |
if($temp = $modx->getObject('msOption', array('key' => $keyF))){ | |
$optionId = $temp->get('id'); | |
$categoryId = $res->get('parent'); | |
if( !$modx->getObject('msCategoryOption', array('option_id' => $optionId, 'category_id' => $categoryId)) ){ | |
$optionCat = $modx->newObject('msCategoryOption'); | |
$optionCat->set('option_id', $optionId); | |
$optionCat->set('category_id', $categoryId); | |
$optionCat->set('active', 1); | |
$optionCat->save(); | |
} | |
unset($optionId, $categoryId); | |
} | |
unset($temp); | |
} | |
} | |
//удаление пустых значений фильтров из таблицы фильтров в БД | |
$sql = "DELETE FROM {$modx->getTableName('msProductOption')} WHERE `product_id` IN ({$resource['id']}) AND (`value`='' OR `value` IS NULL);"; | |
$stmt = $modx->prepare($sql); | |
$stmt->execute(); | |
$stmt->closeCursor(); | |
unset($sql, $stmt); | |
//построение массива групп товаров | |
/*if(isset($prop['groups_id'])) { | |
if (!function_exists('createGroups')) { | |
function createGroups ($id, $gid, $fileProductGroups) { | |
$productGroups = @file_get_contents($fileProductGroups); | |
if($productGroups) { | |
$productGroups = (array) unserialize($productGroups); | |
} else $productGroups = array(); | |
$productGroups[$gid][] = $id; | |
$productGroups = serialize($productGroups); | |
$file = fopen($fileProductGroups, 'w+'); | |
if($file) { | |
fwrite($file, $productGroups); | |
fclose ($file); | |
} else return false; | |
return true; | |
} | |
} | |
createGroups($resource['id'], $prop['groups_id'], $fileProductGroups); | |
}*/ | |
//привязка картинок addImages | |
if ($prop['images']) { | |
foreach ($prop['images'] as $v) { | |
addImages($v, $res, $res->pagetitle); | |
} | |
unset($res, $prop); | |
} | |
return 'new'; | |
} | |
//построение каталога и получение перечня товаров для дальнейшей загрузки с параметром ?tree=1 | |
if(isset($_GET['tree']) && $_GET['tree'] == 1){ | |
echo parseCategory($oasisUrlTree); | |
echo getTreeGoods($oasisUrlProducts); | |
$URL_GET = str_replace('?tree=1','?off_set=0',$_SERVER['REQUEST_URI']); | |
echo "Ссылка для продолжения обновления каталога: <a id='link' href='$URL_GET'><span id='offset'>{$URL_GET}</span></a>\n"; | |
echo "</pre>"; | |
echo '<script type="text/javascript"> | |
if(document.readyState||document.body.readyState==\'complete\'){ | |
var url = document.getElementById(\'link\').getAttribute(\'href\'); | |
window.location.href = url; | |
document.getElementById(\'link\').setAttribute("style", "pointer-events: none;cursor: default;"); | |
}; | |
</script>'; | |
exit; | |
} | |
//получение перечня товаров, скачанных на сервер в файл {$tag}goods.txt , параметр ?off_set=INTEGER | |
$catalog = $catalog_origin = unserialize(file_get_contents(dirname(__FILE__)."/{$tag}goods.txt")); | |
$info = array('upd' => 0, 'new' => 0, 'error' => 0); | |
$i = $a = 0; | |
if(empty($_GET['off_set'])) { | |
$off_set = 0; | |
} | |
else $off_set = (int)$_GET['off_set']; //определяем смещение парсинга | |
//получение всех размеров товара и массива для таблицы размеров товара | |
function getSizes($catalog, $article_base){ | |
$sizes = $table = $all = $tbl = []; | |
$etalon = ['Российский размер' => '']; | |
foreach($catalog as $tree){ | |
if($tree['article_base'] == $article_base){ | |
while(isset($sizes[$tree['size_sort']])){$tree['size_sort'] = $tree['size_sort'] + 1;} | |
$sizes[$tree['size_sort']]['size'] = $tree['size']; | |
$sizes[$tree['size_sort']]['stock'] = ($tree['total_stock'])?:0; //на складе | |
$sizes[$tree['size_sort']]['free'] = (($tree['stock_msk'])?:$tree['total_stock'])?:0; //доступно | |
if(isset($tree['attributes'])){ | |
foreach($tree['attributes'] as $attr){ | |
if (preg_match("/^(Российский |Ширина |Длина )/i", $attr['name'])) { | |
$table[$tree['size']][$attr['name']] = $attr['value'] . ' ' . $attr['dim']; | |
//$table[$attr['name']][$tree['size']] = $attr['value'] . ' ' . $attr['dim']; | |
} | |
} | |
} | |
} | |
} | |
ksort($sizes); | |
if($table){ | |
foreach($table as $k => $v){ | |
$all = array_merge($all,array_keys($v)); | |
} | |
$all = array_unique($all); | |
sort($all); | |
$all = array_flip($all); | |
$all = array_merge($etalon, $all); | |
foreach($all as &$item){ | |
$item = ''; | |
} | |
foreach($sizes as $size){ | |
if($table[$size['size']]){ | |
$table[$size['size']] = array_merge($all, $table[$size['size']]); | |
$i = 0; | |
foreach($table[$size['size']] as $title => $value){ | |
$tbl[$i][$i] = $title; | |
$tbl[$i][] = $value; | |
$i++; | |
} | |
} | |
} | |
} | |
//print_r($tbl); | |
return [$sizes, $tbl]; | |
} | |
foreach($catalog as $tree){ | |
$data = $filtersArray = array(); | |
$i++; | |
if($i <= $off_set) {continue;} | |
if(isset($tree['id'])){ | |
$product = getInfoGood($oasisUrlProduct, $tree['id']); | |
//print_r($tree);exit; | |
$data = array('parent' => $idParent, 'context_key' => 'web', 'template' => $tplProduct, 'class_key' => 'msProduct', 'published' => 1); | |
if(!$product['total_stock']){continue;} | |
$a++; | |
//снимаем с публикации, если товар удалён или под заказ, допускаем только те, которые в наличии | |
if($product['is_deleted'] || !$product['is_on_order']){ | |
$data['published'] = 0; | |
} | |
//получаем нужную инфу по товару | |
$data['product_id'] = $product['id']; | |
$data['groups_id'] = ($product['group_id'])?:$product['color_group_id']; | |
$data['article'] = $data['article_donor'] = $tag.($product['article_base'])?:($tag.($product['article'])?:$product['id']); | |
$data['pagetitle'] = $product['name']; | |
$data['longtitle'] = $product['full_name'] . ' - заказать у нас'; | |
$data['description'] = '[[*pagetitle]] - заказать печать и нанесение логотипа в Москве.'; | |
$data['content'] = "<p class=\"oas_description\">{$product['description']}</p>"; | |
$data['price'] = $product['price']; | |
//$data['weight'] = $product['price']; | |
$data['old_price'] = $product['old_price']; | |
$data['made_in'] = $filtersArray['brand'][] = $product['brand']; | |
$data['new'] = $data['popular'] = false; | |
if($product['rating'] == 1){ | |
$data['new'] = true; | |
} | |
if($product['rating'] == 2){ | |
$data['popular'] = true; | |
} | |
//скачиваем картинки товара | |
//$first = true; | |
if(is_array($product['images'])){ | |
foreach($product['images'] as $img){ | |
/*if($first){ | |
$data['image'] = downloadImg(end(explode('/', ($img['superbig'])?:$img['big'])), ($img['superbig'])?:$img['big']); | |
$first = false; | |
} | |
else{ | |
$data['images'][] = downloadImg(end(explode('/', ($img['superbig'])?:$img['big'])), ($img['superbig'])?:$img['big']); | |
}*/ | |
$data['images'][] = downloadImg(end(explode('/', ($img['superbig'])?:$img['big'])), ($img['superbig'])?:$img['big']); | |
} | |
} | |
//определяем родительскую рубрику | |
$main_category = $tag . ($product['categories'][0])?:$product['main_category']; | |
//проверка наличия категории в массиве сопоставления категорий | |
if($category_manual = getCategoryManual()){ | |
if(isset($category_manual[($product['categories'][0])?:$product['main_category']])){ | |
$main_category = $category_manual[($product['categories'][0])?:$product['main_category']]['article']; | |
} | |
} | |
//находим ID рубрики | |
if($parent_tree = getCatExists($main_category)){ | |
$data['parent'] = $parent_tree; | |
} | |
//устанавливаем дополнительные категории | |
$first = true; | |
foreach($product['categories'] as $add_cat_item){ | |
if($first){ | |
$first = false; | |
} | |
else{ | |
$add_category = $tag . $add_cat_item; | |
//проверка наличия категории в массиве сопоставления категорий | |
if($category_manual){ | |
if(isset($category_manual[$add_cat_item])){ | |
$add_category = $category_manual[$add_cat_item]['article']; | |
} | |
} | |
//находим ID рубрики | |
if($parent_tree = getCatExists($add_category)){ | |
$data['parents'][] = $parent_tree; | |
} | |
} | |
} | |
//Кастомные тэвэшки для кол-ва доступного товара и для описания упаковки | |
$data['tv9'] = $product['total_stock']; //на складе | |
$data['tv10'] = ($product['stock_msk'])?:$product['total_stock']; //доступно | |
$data['tv14'] = $data['groups_id']; | |
//размеры и доступность по размерам / массив для таблицы размеров | |
list($sizes, $tbl_sizes) = getSizes($catalog_origin, $product['article_base']); | |
foreach($sizes as $s_item){ | |
if($s_item['size']){ | |
$data['size'][] = $s_item['size']; | |
$data['tags'][] = "{$s_item['size']} (На складе: {$s_item['stock']} / Доступно: {$s_item['free']})"; | |
} | |
} | |
unset($sizes); | |
//Доп. характеристики | |
foreach($product['attributes'] as $attr_item){ | |
if($attr_item['name'] == 'Плотность'){ | |
$data['tv13'] = ($data['tv13'])?$data['tv13'] . ' ' . $attr_item['value']:''; //подробная информация о плотности | |
} | |
if($attr_item['name'] == 'Диаметр ручки/крандаша'){ | |
$data['content'] .= "<p class=\"dop_options\">Диаметр ручки/карандаша: <span>{$attr_item['value']}</span></p>"; | |
} | |
switch($attr_item['name']){ | |
case 'Материал товара': | |
case 'Материал': | |
$data['tv13'] = ($data['tv13'])?:$attr_item['value']; //подробная информация о материале | |
break; | |
case 'Вес': | |
$data['weight'] = ($attr_item['value'])?:0; //вес товара | |
break; | |
case 'Метод нанесения': | |
$filtersArray['print'][] = $filtersArray['type_of_application'][] = $attr_item['value']; //методы нанесения | |
break; | |
case 'Гендер (пол)': | |
if (preg_match("/муж/i", $attr_item['value'])) { //пол | |
$filtersArray['sex'][] = 'мужские'; | |
} | |
elseif (preg_match("/жен/i", $attr_item['value'])) { | |
$filtersArray['sex'][] = 'женские'; | |
} | |
else{ | |
$filtersArray['sex'][] = $attr_item['value']; | |
} | |
break; | |
case 'Размер товара (см)': | |
case 'Размер товара (мм)': | |
if(!$data['size']) $data['size'][] = $attr_item['value'] .' '. $attr_item['dim']; | |
break; | |
case 'Вид застежки': | |
case 'Кол-во панелей': | |
case 'Возможность замены стержня/картриджа': | |
case 'Диаметр ручки/карандаша': | |
case 'Тип стержня': | |
case 'Цвет чернил': | |
case 'Вид механизма': | |
case 'Вместимость': | |
case 'Кол-во визиток/карт': | |
case 'Объем': | |
case 'Объём': | |
case 'Комплектность': | |
case 'Температурный режим': | |
case 'Источник питания': | |
case 'Диаметр купола': | |
case 'Кол-во сложений': | |
case 'Наличие чехла/футляра': | |
case 'Кол-во спиц': | |
case 'Изнанка': | |
case 'Емкость элемента': | |
case 'Время воспроизведения': | |
case 'Версия Bluetooth®': | |
case 'Мощность': | |
case 'Соединительный разъем': | |
case 'Источник питания': | |
case 'Частотный диапазон': | |
case 'Чувствительность': | |
case 'Максимальная нагрузка': | |
case 'Герметичность': | |
case 'Состав': | |
case 'Масса нетто': | |
case 'Срок годности': | |
case 'Требуется обрешетка': | |
case 'Объем памяти': | |
case 'Интерфейс': | |
case 'Скорость записи': | |
case 'Скорость чтения': | |
case 'Крепление блока': | |
case 'Формат': | |
case 'Разлиновка': | |
case 'Кол-во листов': | |
case 'Обложка': | |
$dim = ($attr_item['dim'])?' <span class="dop_options_dim">'.$attr_item['dim'].'</span>':''; | |
$data['content'] .= "<p class=\"dop_options\">{$attr_item['name']}: <span class=\"dop_options_val\">{$attr_item['value']}</span>{$dim}</p>"; | |
break; | |
} | |
} | |
//цвета | |
if(is_array($product['colors'])){ | |
foreach($product['colors'] as $color_item){ | |
$data['color'][] = $color_item['name']; //цвета | |
} | |
} | |
//материалы | |
if(is_array($product['materials'])){ | |
foreach($product['materials'] as $mat_item){ | |
$filtersArray['material'][] = $mat_item; //фильтр по материалу | |
} | |
} | |
//упаковка | |
$data['tv12'] = ''; | |
$type_arr = []; | |
if(is_array($product['package'])){ | |
foreach($product['package'] as $attr_item){ | |
if(!$attr_item['weight'] && !$attr_item['volume'] && !$attr_item['size']){continue;} | |
$pack = ($attr_item['type'])?:$attr_item['description']; | |
if(isset($type_arr[ $attr_item['description'] ])){continue;} | |
$type_arr[ $attr_item['description'] ] = $attr_item['type']; | |
$data['tv12'] .= "<p><span class=\"pack_type\">Вид упаковки:</span> <span class=\"pack_val\">{$pack}</span><br> <span class=\"pack_type\">Количество в упаковке:</span> <span class=\"pack_val\">{$attr_item['amount']}</span><br> | |
<span class=\"pack_type\">Вес в упаковке:</span> <span class=\"pack_val\">{$attr_item['weight']}</span><br> <span class=\"pack_type\">Объём упаковки:</span> <span class=\"pack_val\">{$attr_item['volume']}</span><br> | |
<span class=\"pack_type\">ШxВxГ:</span> <span class=\"pack_val\">{$attr_item['size']}</span></p>"; | |
} | |
} | |
unset($type_arr); | |
//таблица размеров | |
if($tbl_sizes){ | |
$tables = '<div class="oas_table_sizes"><h6>Размерная таблица</h6><table><tr>'; | |
$first = true; | |
foreach($data['size'] as $size_item){ | |
if($first){ | |
$tables .= "<td></td>"; | |
$first = false; | |
} | |
$tables .= "<td>{$size_item}</td>"; | |
} | |
$tables .= "</tr>"; | |
foreach($tbl_sizes as $tbl_item_tr){ | |
$tables .= "<tr>"; | |
foreach($tbl_item_tr as $tbl_item_td){ | |
$tables .= "<td>{$tbl_item_td}</td>"; | |
} | |
$tables .= "</tr>"; | |
} | |
$tables .= "</table></div>"; | |
$data['content'] .= $tables; | |
} | |
unset($tbl_sizes); | |
$filtersArray = array_diff($filtersArray, array('')); | |
//print_r($filtersArray);exit; | |
//создание или обновление товара | |
$goods = createProduct($data, $filtersArray); | |
//print_r($data); | |
//print_r($filtersArray); | |
//плюсуем произведённое действие (товар обновлён, создан или ошибка) | |
switch($goods) { | |
case 'upd': | |
$info['upd']++; | |
break; | |
case 'new': | |
$info['new']++; | |
break; | |
default: | |
$info['error']++; | |
} | |
//прерываем цикл, если достигнут лимит по количеству обрабатываемых товаров за один проход | |
if ($a == $numOffset) break; | |
//print_r($data); | |
//print_r($info); | |
//exit; | |
} | |
} | |
$off_set = $off_set + $numOffset; | |
if (!strpos($_SERVER['REQUEST_URI'],'off_set')) $_SERVER['REQUEST_URI'] = $_SERVER['REQUEST_URI'].'?off_set='.($off_set-$numOffset); | |
$URL_GET = str_replace('off_set='.($off_set-$numOffset), 'off_set='.$off_set, $_SERVER['REQUEST_URI']); | |
if (!XPDO_CLI_MODE) {echo '<pre>';} | |
echo "\nИмпорт прошёл за ".number_format(microtime(true) - $modx->startTime, 7) . " сек.\n"; | |
echo "Итого обработано\n товаров за проход: {$a}\n обновлено из них: {$info['upd']}\n создано новых из них: {$info['new']}\n ошибок: {$info['error']}\n"; | |
echo "Всего обработано товаров: <a id='link' href='$URL_GET'><span id='offset'>$off_set</span></a>\n"; | |
if ($a == 0) { | |
$autofset = ''; | |
echo "<span style='color:green'>Загрузка завершена</span>"; | |
$paths = array('context_settings/'); | |
$options = array('objects' => null, 'extensions' => array('.php')); | |
$modx->cacheManager->clearCache($paths, $options); | |
} else $autofset = 'window.location = url;'; | |
if (!XPDO_CLI_MODE) { | |
echo '</pre> | |
<script type="text/javascript"> | |
if(document.readyState||document.body.readyState==\'complete\'){ | |
var url = document.getElementById(\'link\').getAttribute(\'href\'); | |
'.$autofset.' | |
}; | |
</script> | |
';} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment