Last active
October 12, 2019 08:20
-
-
Save andronex/34a028afa56b9697019b to your computer and use it in GitHub Desktop.
Парсер товаров для импорта с gifts.ru для MODX Revolution v.2.6+ и miniShop2 v.2.4.10+ (обновлённая, рабочая версия на 02.02.2018 г.) !!!ВНИМАНИЕ!!! Просьба обратить внимание на комментарий @dumbuzz ниже. Если будете использовать, то внесите изменения в код. Если будет время, доработаю сам и выложу.
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
/*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*/ | |
/*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*//*/*/ | |
В связи с участившимися случаями обращения ко мне с вопросами по работе данного скрипта импорта товаров с gifts.ru на сайты, работающие на 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 | |
//настройки для коннекта к gifts | |
$giftsLogin = '****_xmlexport'; | |
$giftsPass = '****'; | |
$giftsUrlProduct = "http://{$giftsLogin}:{$giftsPass}@api2.gifts.ru/export/v2/catalogue/product.xml"; | |
$giftsUrlTree = "http://{$giftsLogin}:{$giftsPass}@api2.gifts.ru/export/v2/catalogue/tree.xml"; | |
$giftsUrlStock = "http://{$giftsLogin}:{$giftsPass}@api2.gifts.ru/export/v2/catalogue/stock.xml"; | |
$giftsUrlFilters = "http://{$giftsLogin}:{$giftsPass}@api2.gifts.ru/export/v2/catalogue/filters.xml"; | |
$urlImages = 'http://files.gifts.ru/reviewer/'; | |
//настройки для входа в админку MODX (уже не используются) | |
$username = 'admin'; | |
$userpass = '****'; | |
//настройки для парсинга XML файла и установки шаблонов для создаваемых продуктов | |
$fileProduct = dirname(__FILE__).'/product.xml'; | |
$fileParentCat = dirname(__FILE__).'/product.txt'; | |
$fileProductStock = dirname(__FILE__).'/stock.txt'; | |
$fileProductFilters = dirname(__FILE__).'/filters.txt'; | |
$fileProductGroups = dirname(__FILE__).'/groups.txt'; | |
$fileTree = dirname(__FILE__).'/tree.xml'; | |
$fileStock = dirname(__FILE__).'/stock.xml'; | |
$fileFilters = dirname(__FILE__).'/filters.xml'; | |
$xpath_expression['product'] = '//doct/product'; //DOM структура до продукта | |
$xpath_expression['page'] = '//doct/page/page'; //DOM структура до страницы | |
$xpath_expression['stock'] = '//doct/stock'; //DOM структура до наличия на складе | |
$xpath_expression['filters'] = '//root/filtertypes/filtertype'; //DOM структура до фильтров товара | |
//настройки для обработки товаров | |
$tplProduct = 6;//номер шаблона для карточки товара | |
$numOffset = 50;//число товаров для загрузки за 1 проход парсера | |
$tplParent = 4;//номер шаблона для категорий | |
$tplChildParent = 4;//номер шаблона для подкатегорий | |
$idParent = 10;//id каталога товаров | |
$categoryArticleTVnumber = 'tv8';//ID TV поля для записи уникального идентификатора категории товаров для последующего сравнения с деревом категорий поставщика | |
//API ключ для Яндекс переводчика, получить здесь https://tech.yandex.ru/translate/ | |
$apiYaTranslate = 'trnsl.1.1.20180130T1***************043c53e0c440bb752c8df1f90829410aed9fd'; |
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 | |
/** | |
* запускать отдельно после первого запуска парсера, когда все товары добавлены на сайт | |
* связывает товары по цветам в группы | |
* */ | |
require_once(dirname(__FILE__).'/config.php'); | |
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; // Обнуляем переменную | |
// Логинимся в админку | |
$response = $modx->runProcessor('security/login', array('username' => $username, 'password' => $userpass)); | |
if ($response->isError()) { | |
$modx->log(modX::LOG_LEVEL_ERROR, $response->getMessage()); | |
return; | |
} | |
$modx->initialize('mgr'); | |
/****************************************************************/ | |
$groupsArray = @file_get_contents(dirname(__FILE__).'/groups.txt'); | |
$groupsArray = unserialize($groupsArray); | |
foreach($groupsArray as $groups){ | |
if(is_array($groups)) { | |
if(count($groups) < 2) continue; | |
for($a = 0;$a < count($groups);$a++){ | |
if($a == 0) continue; | |
if(!$modx->getObject('msProduct', $groups[$a])) continue; | |
$master = $groups[0]; | |
$slave = $groups[$a]; | |
$linkid = 1; | |
//print_r($master.$slave.$linkid);exit; | |
$response = $modx->runProcessor('product/productlink/create', | |
array('master' => $master, 'slave' => $slave, 'link' => $linkid), | |
array('processors_path' => MODX_CORE_PATH.'components/minishop2/processors/mgr/')); | |
if ($response->isError()) { | |
$modx->log(modX::LOG_LEVEL_ERROR, "Ошибка установки связи товара-мастера {$master} к товару {$slave}: \n". print_r($response->getAllErrors(), 1)); | |
} | |
} | |
} | |
} |
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 | |
/** | |
* в скрипте есть TV поля, не представленные в config.php по причине уникальности каждого магазина | |
* см. строки 160 и 425 | |
*/ | |
//ini_set('display_errors', 1); | |
//ini_set('error_reporting', -1); | |
/***************************************/ | |
require_once(dirname(__FILE__).'/config.php'); | |
require_once(dirname(__FILE__).'/tree.parser.php'); | |
if(empty($_GET['off_set'])) { | |
$off_set = 0; | |
if (!treeParser($giftsLogin, $giftsPass, $giftsUrlTree, $giftsUrlStock, $username, $userpass, $fileTree, $fileStock, $xpath_expression['page'], $xpath_expression['stock'], $tplParent, $tplChildParent, $giftsUrlFilters, $fileFilters, $xpath_expression['filters'], $apiYaTranslate)) { | |
die("ошибка парсинга структуры каталога"); | |
} | |
} | |
else $off_set = (int)$_GET['off_set']; //определяем смещение парсинга | |
$i = $ii = $iii = $a = $aa = $all = 0; | |
$treeTxt = ''; | |
$tree = array(); | |
/***************************************/ | |
if (!file_exists($fileProduct) || (time() - filemtime($fileProduct)) > 43200 || file_get_contents($fileProduct) === '') { //12 часов | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_URL, $giftsUrlProduct); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
$result = curl_exec($ch); | |
curl_close($ch); | |
if ($result) { | |
$file_tree = fopen ($fileProduct,'w+'); | |
if ($file_tree) { | |
fwrite($file_tree, $result); | |
fclose ($file_tree); | |
} | |
} | |
} | |
unset ($file_tree,$result,$file_filters); | |
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; // Обнуляем переменную | |
// Логинимся в админку | |
/*$response = $modx->runProcessor('security/login', array('username' => $username, 'password' => $userpass)); | |
if ($response->isError()) { | |
$modx->log(modX::LOG_LEVEL_ERROR, $response->getMessage()); | |
return; | |
} | |
$modx->initialize('mgr');*/ | |
/***************************************/ | |
$xml = new DOMDocument(); | |
$xml->load($fileProduct); | |
$xpath = new DOMXPath($xml); | |
$nodes = $xpath->query($xpath_expression['product']); | |
$productTree = @file_get_contents($fileParentCat); | |
if(!$productTree) die('Дерево каталога ещё не построено.'); | |
$productTree = (array) unserialize($productTree); | |
$productStock = @file_get_contents($fileProductStock); | |
if(!$productStock) die('Нет .txt файла с наличием товара на складе поставщика.'); | |
$productStock = (array) unserialize($productStock); | |
$productFilters = @file_get_contents($fileProductFilters); | |
if(!$productFilters) die('Нет .txt файла с фильтрами для товаров.'); | |
$productFilters = (array) unserialize($productFilters); | |
//проверка на существование или создание отсутствующих фильтров | |
foreach($productFilters as $keyFilters => $productFilter){ | |
$temp = $modx->getObject('msOption', array('key' => $productFilter['filtertypenameEng'])); | |
if(!$temp && $productFilter['filtertypenameEng'] != 'color') { | |
$newFilters = $modx->newObject('msOption',array( | |
'key' => $productFilter['filtertypenameEng'], | |
'caption' => $productFilter['filtertypename'], | |
'type' => 'combo-options'//тип опции | |
)); | |
$newFilters->save(); | |
unset($newFilters); | |
} | |
$productFilters[$keyFilters]['filteridMODX'] = $temp->id ? $temp->id : null; | |
unset($temp); | |
} | |
//ф-ия создания новых ресурсов или получения ID уже созданных | |
function createProduct ($prop, $filtersArray = array(), $gallery = array(), $artForAlias = '') { | |
//return 'upd';//временно | |
global $tplProduct; | |
global $modx; | |
global $productTree; | |
global $fileProductGroups; | |
global $urlImages; | |
$prop['template'] = $tplProduct; | |
$prop['context_key'] = 'web'; | |
$prop['class_key'] = 'msProduct'; | |
$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());exit; | |
//$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(); | |
return 'upd'; | |
} | |
$modx->error->message = null; | |
$response = $modx->runProcessor('resource/create', $prop, | |
array('processors_path' => MODX_CORE_PATH.'model/modx/processors/') | |
); | |
if ($response->isError()) { | |
return $response->getAllErrors(); | |
} | |
$resource = $response->getObject(); | |
//удаление из pagetitle артикулов, нужных на стадии создания товара для формирования alias ресурса | |
$res = $modx->getObject('msProduct', array('id' => $resource['id'])); | |
$res->set('pagetitle', str_replace($artForAlias, '', $res->get('pagetitle'))); | |
$res->save(); | |
//доп. категории только если их более одной в массиве $productTree[$prop['product_id']], начиная со второй, первая основная (parent) | |
if(count($productTree[$prop['product_id']]) > 1){ | |
$aCat = 0; | |
foreach ($productTree[$prop['product_id']] as $catProduct){ | |
$aCat++; | |
if($aCat == 1) continue; | |
$category = $modx->newObject('msCategoryMember'); | |
$category->set('category_id', $catProduct); | |
$category->set('product_id', $resource['id']); | |
$category->save(); | |
} | |
} | |
//привязка фильтров к товару и к категории товара из массива фильтров $productFilters и массива фильтров товара $filtersArray | |
if(is_array($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); | |
} | |
//привязка картинок | |
if (is_array($gallery)) { | |
foreach ($gallery as $v) { | |
if (empty($v)) {continue;} | |
$image = $v; | |
$image = explode('/', $image); | |
$image = $image[count($image)-1]; | |
$image = str_replace('_', '-', $image); | |
if (!file_exists(dirname(__FILE__).'/thumbs/'.$image)) { | |
$ch = curl_init($urlImages.$v); | |
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}{$v}"); | |
$noimg = true; | |
} | |
curl_close($ch); | |
} | |
if(!$noimg) { | |
$response_img = $modx->runProcessor('gallery/upload', | |
array('id' => $res->get('id'), 'name' => $image, 'file' => dirname(__FILE__).'/thumbs/'.$image), | |
array('processors_path' => MODX_CORE_PATH.'components/minishop2/processors/mgr/') | |
); | |
if ($response_img->isError()) { | |
$modx->log(modX::LOG_LEVEL_ERROR, "Ошибка привязки картинки \"$image\" к товару id = {$resource['id']}: \n". print_r($response_img->getAllErrors(), 1)); | |
} | |
else { | |
$sql = "UPDATE {$modx->getTableName('msProductFile')} SET `name` = \"{$res->get('pagetitle')}\" WHERE `product_id` IN ({$resource['id']});"; | |
$stmt = $modx->prepare($sql); | |
$stmt->execute(); | |
$stmt->closeCursor(); | |
unset($sql, $stmt); | |
$modx->log(modX::LOG_LEVEL_INFO, "Удачно загружена картинка \"$image\": \n". print_r($response_img->getObject(), 1)); | |
} | |
} | |
} | |
unset($response_img, $res, $image, $resource); | |
} | |
return 'new'; | |
} | |
/***************************************/ | |
foreach($nodes as $node){$all++;} | |
foreach($nodes as $node){ | |
$i++; | |
if($i <= $off_set) {continue;} | |
$massiv_data = $gallery = $filtersArray = array(); | |
$a++; | |
$massiv_data['product_id'] = $node->getElementsByTagName('product_id')->item(0)->nodeValue; | |
if(isset($node->getElementsByTagName('group')->item(0)->nodeValue)) | |
{$massiv_data['groups_id'] = $node->getElementsByTagName('group')->item(0)->nodeValue;} | |
$massiv_data['pagetitle'] = $node->getElementsByTagName('name')->item(0)->nodeValue; | |
$massiv_data['article'] = $node->getElementsByTagName('code')->item(0)->nodeValue; | |
$massiv_data['price'] = $node->getElementsByTagName('price')->item(1)->nodeValue; | |
$gallery[] = $node->getElementsByTagName('super_big_image')->item(0)->getAttribute('src'); | |
$attachCount = $node->getElementsByTagName('product_attachment')->length; | |
for($aa = 0; $aa < $attachCount; $aa++) { | |
switch($node->getElementsByTagName('product_attachment')->item($aa)->getElementsByTagName('meaning')->item(0)->nodeValue){ | |
case 0: | |
$gallery[] = $node->getElementsByTagName('product_attachment')->item($aa)->getElementsByTagName('file')->item(0)->nodeValue; | |
break; | |
default: | |
$gallery[] = $node->getElementsByTagName('product_attachment')->item($aa)->getElementsByTagName('image')->item(0)->nodeValue; | |
} | |
$gallery = array_unique($gallery); | |
} | |
if(isset($productTree[$massiv_data['product_id']])){ | |
foreach ($productTree[$massiv_data['product_id']] as $catProduct){ | |
$massiv_data['parent'] = $catProduct; | |
break; | |
} | |
} | |
else $massiv_data['parent'] = $idParent; | |
$massiv_data['published'] = ($node->getElementsByTagName('status')->item(0)->getAttribute('id') == '3') ? 0 : 1; | |
$massiv_data['new'] = ($node->getElementsByTagName('status')->item(0)->getAttribute('id') == '0') ? 1 : 0; | |
$massiv_data['popular'] = 0; //не распродажа | |
$massiv_data['favorite'] = 0;//не эко-товар | |
//далее по коду переопределяются, если найдены соответствующие фильтры | |
$massiv_data['matherial'] = $node->getElementsByTagName('matherial')->item(0)->nodeValue; | |
if(isset($node->getElementsByTagName('brand')->item(0)->nodeValue)) | |
{$massiv_data['made_in'] = $node->getElementsByTagName('brand')->item(0)->nodeValue;} | |
$massiv_data['size'] = array($node->getElementsByTagName('product_size')->item(0)->nodeValue); | |
$sizeCount = $node->getElementsByTagName('product')->length; | |
for($aa = 0; $aa < $sizeCount; $aa++) { | |
if($node->getElementsByTagName('product')->item($aa)->getElementsByTagName('main_product')->item(0)->nodeValue == $massiv_data['product_id']){ | |
$massiv_data['size'][$aa] = $node->getElementsByTagName('product')->item($aa)->getElementsByTagName('size_code')->item(0)->nodeValue; | |
} | |
} | |
$massiv_data['weight'] = $node->getElementsByTagName('weight')->item(0)->nodeValue; | |
if($productStock[$massiv_data['product_id']]['amount'] != 0){ | |
if($productStock[$massiv_data['product_id']]['inwayamount']) $massiv_data['inwayamount'] = " <small>+{$productStock[$massiv_data['product_id']]['inwayamount']} в поставке</small>"; | |
$massiv_data['amount'] = "На складе: {$productStock[$massiv_data['product_id']]['amount']}{$massiv_data['inwayamount']}<br>Можно зарезервировать: {$productStock[$massiv_data['product_id']]['free']}"; | |
} | |
else $massiv_data['amount'] = 'под заказ'; | |
if($node->getElementsByTagName('pack')->length) { | |
$massiv_data['pack_amount'] = $node->getElementsByTagName('pack')->item(0)->getElementsByTagName('amount')->item(0)->nodeValue; | |
$massiv_data['pack_weight'] = (int)round($node->getElementsByTagName('pack')->item(0)->getElementsByTagName('weight')->item(0)->nodeValue)/1000; | |
$massiv_data['pack_volume'] = (float)round($node->getElementsByTagName('pack')->item(0)->getElementsByTagName('volume')->item(0)->nodeValue/1000000,3); | |
$massiv_data['pack_sizex'] = $node->getElementsByTagName('pack')->item(0)->getElementsByTagName('sizex')->item(0)->nodeValue; | |
$massiv_data['pack_sizey'] = $node->getElementsByTagName('pack')->item(0)->getElementsByTagName('sizey')->item(0)->nodeValue; | |
$massiv_data['pack_sizez'] = $node->getElementsByTagName('pack')->item(0)->getElementsByTagName('sizez')->item(0)->nodeValue; | |
} | |
$massiv_data['print'] = $node->getElementsByTagName('print'); | |
$massiv_data['prints'] = "<p><label>Возможные виды нанесения:</label>"; | |
$printCount = $massiv_data['print']->length; | |
for($aa = 0;$aa < $printCount;$aa++) { | |
$massiv_data['print_name'] = $massiv_data['print']->item($aa)->getElementsByTagName('name')->item(0)->nodeValue; | |
$massiv_data['print_description'] = $massiv_data['print']->item($aa)->getElementsByTagName('description')->item(0)->nodeValue; | |
$massiv_data['prints'] .= "<br>{$massiv_data['print_name']}: {$massiv_data['print_description']}"; | |
$filtersArray['print'][] = $massiv_data['print_name'].': '.$massiv_data['print_description']; //фильтры: возможная печать | |
} | |
unset($massiv_data['print'], $massiv_data['print_name'], $massiv_data['print_description'], $printCount, $aa); | |
$massiv_data['filters'] = $node->getElementsByTagName('filters')->item(0)->getElementsByTagName('filter'); | |
$filtersCount = $massiv_data['filters']->length; | |
for($aa = 0;$aa < $filtersCount;$aa++) { | |
if($productFilters[$massiv_data['filters']->item($aa)->getElementsByTagName('filtertypeid')->item(0)->nodeValue]['filtertypenameEng'] == 'color'){ | |
$massiv_data['color'][] = $productFilters[$massiv_data['filters']->item($aa)->getElementsByTagName('filtertypeid')->item(0)->nodeValue][$massiv_data['filters']->item($aa)->getElementsByTagName('filterid')->item(0)->nodeValue]; //присвоение цветов товара | |
} | |
if($massiv_data['filters']->item($aa)->getElementsByTagName('filtertypeid')->item(0)->nodeValue == 8){ | |
switch($massiv_data['filters']->item($aa)->getElementsByTagName('filterid')->item(0)->nodeValue){ | |
case 230: | |
$massiv_data['popular'] = 1; | |
break; | |
case 229: | |
$massiv_data['new'] = 1; | |
break; | |
case 220: | |
$massiv_data['favorite'] = 1; | |
break; | |
} | |
} | |
$filtersArray[ $productFilters[$massiv_data['filters']->item($aa)->getElementsByTagName('filtertypeid')->item(0)->nodeValue]['filtertypenameEng'] ][] = $productFilters[$massiv_data['filters']->item($aa)->getElementsByTagName('filtertypeid')->item(0)->nodeValue][$massiv_data['filters']->item($aa)->getElementsByTagName('filterid')->item(0)->nodeValue]; //фильтры: все остальные | |
} | |
$massiv_data['prints'] .= "</p>"; | |
$massiv_data['content'] = '[+content]'; | |
//Кастомные тэвэшки для кол-ва доступного товара и для описания упаковки | |
$massiv_data['tv9'] = $productStock[$massiv_data['product_id']]['amount']; //на складе | |
$massiv_data['tv10'] = $productStock[$massiv_data['product_id']]['free']; //доступно | |
$massiv_data['tv12'] = (!$massiv_data['pack_amount']) ? '' : "<p>Количество в упаковке: {$massiv_data['pack_amount']} шт.<br>Вес в упаковке: {$massiv_data['pack_weight']} кг.<br>Объём упаковки: {$massiv_data['pack_volume']} м<sup>3</sup><br>ШxВxГ: {$massiv_data['pack_sizex']}x{$massiv_data['pack_sizey']}x{$massiv_data['pack_sizez']} см.</p>"; | |
$massiv_data['tv13'] = $massiv_data['matherial']; //подробная информация о материале | |
$massiv_data['tv14'] = ($massiv_data['groups_id']) ? $massiv_data['groups_id'] : $massiv_data['article']; //группа товаров для дополнительной привязки через TV поля | |
//$info = "<p><label>Материал:</label> {$massiv_data['matherial']}</p><p><label>Упаковка:</label><br>количество в упаковке: {$massiv_data['pack_amount']} шт.<br>вес в упаковке: {$massiv_data['pack_weight']} кг.<br>объём упаковки: {$massiv_data['pack_volume']} м<sup>3</sup><br>ШxВxГ: {$massiv_data['pack_sizex']}x{$massiv_data['pack_sizey']}x{$massiv_data['pack_sizez']} см.</p>{$massiv_data['prints']}"; | |
$content = $node->getElementsByTagName('content')->item(0)->nodeValue; | |
//if(!empty($content)) $content = "<p><label>Описание</label><br>{$content}</p>"; | |
//$amount = "<p><label>Сведения о наличии:</label><br>{$massiv_data['amount']}</p>"; | |
$massiv_data['content'] = str_replace(array('[+info]','[+amount]','[+content]'),array($info, $amount, $content),$massiv_data['content']); | |
unset($info,$content,$amount,$massiv_data['filters'],$massiv_data['prints'],$filtersArray['color'],$massiv_data['urltoimg'],$massiv_data['matherial'],$massiv_data['inwayamount'],$massiv_data['amount'],$massiv_data['pack_amount'],$massiv_data['pack_weight'],$massiv_data['pack_volume'],$massiv_data['pack_sizex'],$massiv_data['pack_sizey'],$massiv_data['pack_sizez']); | |
$massiv_data['pagetitle'] .= $artForAlias = " арт.{$massiv_data['article']}"; | |
//для проверки нужного товара if($massiv_data['product_id'] != 75424) continue; | |
//print_r($massiv_data); print_r($filtersArray);exit; | |
$Product = createProduct($massiv_data, $filtersArray, $gallery, $artForAlias); | |
//print_r($Product); | |
switch($Product) { | |
case 'upd': | |
$ii++; | |
break; | |
default: | |
$iii++; | |
} | |
if ($a == $numOffset) break; | |
} | |
$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 = 'http://'.$_SERVER['SERVER_NAME'].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 обновлено из них: {$ii}\n создано новых из них: {$iii}\n"; | |
echo "Всего обработано товаров: <a id='link' href='$URL_GET'><span id='offset'>$off_set</span></a>\n"; | |
echo "Всего основных товаров в XML файле: $all\n"; | |
if ($off_set >= $all) { | |
$autofset = ''; | |
$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> | |
';} |
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 | |
function treeParser ($giftsLogin, $giftsPass, $giftsUrlTree, $giftsUrlStock, $username, $userpass, $file, $file_stock, $xpath_expression, $xpath_expression_stock, $tplParent, $tplChildParent, $giftsUrlFilters, $fileFilters, $xpath_expression_filters, $apiYaTranslate) { | |
global $modx; | |
global $idParent; | |
global $categoryArticleTVnumber; | |
$globalIdParent = $idParent; | |
$i = $ii = $iiii = 0; | |
$treeTxt = $productTxt = ''; | |
$massiv_data = $tree = array(); | |
/***************************************/ | |
if (!file_exists($file) || (time() - filemtime($file)) > 43200 || file_get_contents($file) === '') { //12 часов | |
function update_xml ($giftsUrlTree, $file) { | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_URL, $giftsUrlTree); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
$result = curl_exec($ch); | |
curl_close($ch); | |
if ($result) { | |
$file_tree = fopen ($file,'w+'); | |
if ($file_tree) { | |
fwrite($file_tree, $result); | |
fclose ($file_tree); | |
return true; | |
} | |
} | |
return false; | |
} | |
update_xml ($giftsUrlTree, $file); | |
update_xml ($giftsUrlStock, $file_stock); | |
update_xml ($giftsUrlFilters, $fileFilters); | |
} | |
unset ($file_tree,$result); | |
define('MODX_API_MODE', true); | |
require 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; // Обнуляем переменную | |
// Логинимся в админку | |
/*$response = $modx->runProcessor('security/login', array('username' => $username, 'password' => $userpass)); | |
if ($response->isError()) { | |
$modx->log(modX::LOG_LEVEL_ERROR, $response->getMessage()); | |
return; | |
} | |
$modx->initialize('mgr');*/ | |
/***************************************/ | |
function newDomXml ($file, $xpath_expression) { | |
$xml = new DOMDocument(); | |
$xml->load($file); | |
$xpath = new DOMXPath($xml); | |
$nodes = $xpath->query($xpath_expression); | |
return $nodes; | |
} | |
$nodes = newDomXml ($file, $xpath_expression); | |
//ф-ия создания новых ресурсов или получения ID уже созданных | |
function createCategory ($parent = 2, $pagetitle, $art, $template = null) { | |
//return 12;//временно | |
global $tplParent; | |
global $modx; | |
global $categoryArticleTVnumber; | |
$prop = array( | |
'parent' => $parent, | |
'class_key' => 'msCategory', | |
'pagetitle' => $pagetitle, | |
'template' => (empty($template)) ? $tplParent : $template, | |
'published' => 1, | |
$categoryArticleTVnumber => $art | |
); | |
//print_r($prop);exit; | |
if($artCat = $modx->getObject('modTemplateVarResource', array('value' => $art))) return $artCat->contentid; | |
$response = $modx->runProcessor('resource/create', $prop); | |
if ($response->isError()) { | |
return $modx->error->failure($response->getMessage()); | |
} | |
$newResource = $response->response['object']; | |
return $newResource['id']; | |
} | |
/***************************************/ | |
foreach($nodes as $node){ | |
$i++; | |
$massiv_data['parent'] = ($node->getAttribute('parent_page_id') == 1) ? $globalIdParent : $node->getAttribute('parent_page_id'); | |
$massiv_data['pagetitle'] = $node->getElementsByTagName('name')->item(0)->nodeValue; | |
$massiv_data[ $categoryArticleTVnumber ] = 'cat_'.$node->getElementsByTagName('page_id')->item(0)->nodeValue; | |
$idParent = createCategory($massiv_data['parent'], $massiv_data['pagetitle'], $massiv_data[ $categoryArticleTVnumber ]); | |
if(is_array($idParent)) { | |
die('Ошибка создания категории или подкатегории товаров: ' . $idParent['message']); | |
} | |
//$tree[$idParent] = array(); | |
if($nodesClild = $node->childNodes) { | |
foreach($nodesClild as $nodeClild) { | |
if($nodeClild->nodeName == 'page') { | |
$ii++; | |
$massiv_data['parent'] = $idParent; | |
$massiv_data['pagetitle'] = $nodeClild->getElementsByTagName('name')->item(0)->nodeValue; | |
$artId = $nodeClild->getElementsByTagName('page_id')->item(0)->nodeValue; | |
$massiv_data[ $categoryArticleTVnumber ] = 'cat_'.$artId; | |
$idChildParent = createCategory($massiv_data['parent'], $massiv_data['pagetitle'], $massiv_data[ $categoryArticleTVnumber ], $tplChildParent); | |
//$tree[$idParent+$i][] = $idChildParent; | |
$treeTxt .= $artId.':'.$idChildParent.','; | |
if($nodesClildProduct = $nodeClild->childNodes) { | |
foreach($nodesClildProduct as $nodeClildProduct) { | |
if($nodeClildProduct->nodeName == 'product') { | |
$massiv_data['parent'] = $idChildParent; | |
$massiv_data[ $categoryArticleTVnumber ] = $nodeClildProduct->getElementsByTagName('product')->item(0)->nodeValue; | |
$tree[$massiv_data[ $categoryArticleTVnumber ]][$iiii] = $idChildParent; | |
$productTxt .= $massiv_data[ $categoryArticleTVnumber ].':'.$idChildParent.','; | |
$iiii++; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
$iii = count($tree); | |
$tree = serialize($tree); | |
if ($tree) { | |
$file_tree = fopen (dirname(__FILE__).'/product.txt','w+'); | |
if ($file_tree) { | |
fwrite($file_tree, $tree); | |
fclose ($file_tree); | |
} | |
unset ($file_tree,$tree); | |
} | |
//наличие | |
unset($nodes, $artId); | |
$nodes = newDomXml ($file_stock, $xpath_expression_stock); | |
foreach($nodes as $node){ | |
$artId = $node->getElementsByTagName('product_id')->item(0)->nodeValue; | |
$tree[$artId]['amount'] = $node->getElementsByTagName('amount')->item(0)->nodeValue; | |
$tree[$artId]['free'] = $node->getElementsByTagName('free')->item(0)->nodeValue; | |
$tree[$artId]['inwayamount'] = $node->getElementsByTagName('inwayamount')->item(0)->nodeValue; | |
} | |
if ($tree) { | |
$tree = serialize($tree); | |
$file_tree = fopen (dirname(__FILE__).'/stock.txt','w+'); | |
if ($file_tree) { | |
fwrite($file_tree, $tree); | |
fclose ($file_tree); | |
} | |
unset ($file_tree,$tree); | |
} | |
//фильтры | |
unset($nodes, $artId); | |
$nodes = newDomXml ($fileFilters, $xpath_expression_filters); | |
foreach($nodes as $node){ | |
$artId = $node->getElementsByTagName('filtertypeid')->item(0)->nodeValue; | |
foreach ($node->getElementsByTagName('filters')->item(0)->getElementsByTagName('filter') as $artFilters) { | |
$tree[$artId][$artFilters->getElementsByTagName('filterid')->item(0)->nodeValue] = $artFilters->getElementsByTagName('filtername')->item(0)->nodeValue; | |
} | |
$tree[$artId]['filtertypename'] = $node->getElementsByTagName('filtertypename')->item(0)->nodeValue; | |
$POST = array( | |
'key'=>$apiYaTranslate | |
,'text'=>$tree[$artId]['filtertypename'] | |
,'lang'=>'ru-en' | |
); | |
$curl = curl_init(); | |
curl_setopt($curl,CURLOPT_RETURNTRANSFER,1); | |
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,0); | |
curl_setopt($curl,CURLOPT_URL,'https://translate.yandex.net/api/v1.5/tr.json/translate'); | |
curl_setopt($curl,CURLOPT_USERAGENT,'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13'); | |
curl_setopt($curl, CURLOPT_POST, true); | |
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($POST)); | |
curl_setopt($curl,CURLOPT_FOLLOWLOCATION,1); | |
$translate = curl_exec($curl); | |
curl_close($curl); | |
switch($tree[$artId]['filtertypename']){ | |
case 'Пол': | |
$tree[$artId]['filtertypenameEng'] = 'sex'; | |
break; | |
case 'Материал': | |
$tree[$artId]['filtertypenameEng'] = 'material'; | |
break; | |
default: | |
$tree[$artId]['filtertypenameEng'] = str_replace(' ', '_', mb_strtolower(json_decode($translate)->text[0])); | |
} | |
} | |
if ($tree) { | |
$tree = serialize($tree); | |
$file_tree = fopen (dirname(__FILE__).'/filters.txt','w+'); | |
if ($file_tree) { | |
fwrite($file_tree, $tree); | |
fclose ($file_tree); | |
} | |
unset ($file_tree,$tree,$nodes,$artId,$POST); | |
} | |
$paths = array('context_settings/'); | |
$options = array('objects' => null, 'extensions' => array('.php')); | |
$modx->cacheManager->clearCache($paths, $options); | |
if (!XPDO_CLI_MODE) {echo '<pre>';} | |
echo "\nИтого в каталоге\n категорий: {$i}\n подкатегорий: {$ii}";//\n товаров: {$iii}"; | |
if (!XPDO_CLI_MODE) {echo '</pre>';} | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Настоятельно просим изменить конфигурационный параметр $urlImages = 'http://files.gifts.ru/reviewer/'
Это недокументированная возможность, которая создаёт избыточную нагрузку на сервер files.gifts.ru
Картинки нужно скачивать с базового адреса: "http://login:password@api2.gifts.ru/export/v2/catalogue/" и с частотой - не более 5 запросов в секунду.
Разработчики gifts.ru