Skip to content

Instantly share code, notes, and snippets.

@andronex
Created April 2, 2021 12:51
Show Gist options
  • Save andronex/09fe88bb36b64337cf94bf245f6eecef to your computer and use it in GitHub Desktop.
Save andronex/09fe88bb36b64337cf94bf245f6eecef to your computer and use it in GitHub Desktop.
Парсер товаров с сайта поставщика portobello.ru для MODX Revolution от 2.6.5-pl + miniShop2 от 2.4.12-pl / можно запускать как из браузера с offset, так из консоли или по cron
<?php
//настройки для коннекта к portobello.ru
$portobelloUrlTree = 'https://portobello.ru/export/new-products.xml'; //весь каталог товаров
$portobelloUrlStock = 'https://portobello.ru/export/new-products-quantity.xml'; //наличие товаров
//настройки для парсинга и установки шаблонов для создаваемых продуктов
$fileProductGroups = dirname(__FILE__).'/portobello_groups.txt';
$fileCatExist = dirname(__FILE__).'/portobello_category_exist.txt';
//настройки для обработки товаров
$tplProduct = 6;//номер шаблона для карточки товара
$numOffset = 3;//число товаров для загрузки за 1 проход парсера
$tplParent = 4;//номер шаблона для категорий
$tplChildParent = 4;//номер шаблона для подкатегорий
$idParent = 10;//id каталога товаров
$categoryArticleTVnumber = 'tv8';//ID TV поля для записи уникального идентификатора категории товаров для последующего сравнения с деревом категорий поставщика
$tag = 'pto_';
//МЕТА поля массовые
$longtitle = ', цены в Москве, заказать оптом на «Gitwell»';
$description = '. Достойный подарок - Gitwell наносит логотипы и фирменный стиль на любые товары.';
<?php
/*
* первый запуск с параметром ?tree=1
*/
//ini_set('display_errors', 1);
//ini_set('error_reporting', -1);
//error_reporting(E_ALL);
require_once(dirname(__FILE__).'/portobello_config.php');
if(!$xml = simplexml_load_file($portobelloUrlTree)){
die('Не получен каталог товаров');
}
if(!$stocks = simplexml_load_file($portobelloUrlStock)){
die('Не получены остатки товаров');
}
//функция рекурсивной проверки наличия ключа массива
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;
}
//функция рекурсивного парсинга страниц и построения структуры каталога
/*
$item
SimpleXMLElement Object
(
[@attributes] => Array
(
[id] => 1353
[parentId] =>
[title] => Шеврон для пледа
)
)
$tree
SimpleXMLElement Object
(
[category] => Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[id] => 1353
[parentId] =>
[title] => Шеврон для пледа
)
)
[1] => SimpleXMLElement Object
(
[@attributes] => Array
(
[id] => 1136
[parentId] =>
[title] => Ежедневники
)
)
...............
*/
function parseCategory(){
global $xml,$idParent;
$counter = ['new' => 0, 'upd' => 0, 'error' => 0];
$tree = $xml->categories;
foreach($tree->xpath('//category') 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; // Обнуляем переменную
if (XPDO_CLI_MODE) {
$numOffset = 50000;
$_GET['tree'] = @$argv[1];
}
//функция получения массива сопоставляемых категорий
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, $return = false, $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;
$article_cat = $tag . (int)$massiv['id'];
//проверка наличия категории в массиве сопоставления категорий
if($category_manual = getCategoryManual()){
if(isset($category_manual[ (int)$massiv['id'] ])){
$article_cat = $category_manual[ (int)$massiv['id'] ]['article'];
}
}
/*if($article_cat == 'pto_1330'){//для проверки
$article_cat = 'pto_13300';
}*/
if($parent_tree = getCatExists($article_cat)){
$parent = $parent_tree;
$create = false;
$upd++;
if($return){
return $parent;
}
}
else{
$parentId = (int)$massiv['parentId'];
$parentMassive = $tree->xpath("//category[@id='".$parentId."']")[0];
$parent = createCategory($parentMassive, $tree, $parent, true);
$create = true;
$prop = array(
'tvs' => true,
$categoryArticleTVnumber => $article_cat,
'parent' => $parent,
'class_key' => 'msCategory',
'pagetitle' => (string)$parentMassive['title'],
'template' => $template,
'published' => 1,
'context_key' => 'web',
'longtitle' => (string)$parentMassive['title'] . $longtitle,
'description' => (string)$parentMassive['title'] . $description,
);
}
if($create){
$parent = ($tmp = createCatProcess($prop))?$tmp:$parent;
if($tmp){
$new++;
}
else{
$err++;
}
if($return){
return $parent;
}
}
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;
}
//функция преобразования SimpleXML Object в массив с поддержкой вложенности и CDATA в описании
function SimpleXML2ArrayWithCDATASupport($xml)
{
$array = (array)$xml;
if (count($array) === 0) {
return (string)$xml;
}
foreach ($array as $key => $value) {
if (!is_object($value) || strpos(get_class($value), 'SimpleXML') === false) {
if($key == 'personalization'){
$array[$key] = SimpleXML2ArrayWithCDATASupport($value);
}
else{
continue;
}
}
$array[$key] = SimpleXML2ArrayWithCDATASupport($value);
}
return $array;
}
//функция получение перечня товаров
function getTreeGoods(){
global $tag,$time,$xml,$stocks;
$time = $time?:microtime(true);
$result = [];
if($result_orig = $xml->products->product) {
foreach($result_orig as $item){
//удаляем товар, если кол-во 0 или null
if($item->price > 0 && $item->bigImage){
$free = $stocks->productsStocks->xpath("//product[@article='{$item->article}']/stock[@xmlId='000000116']");
$is_cat = $xml->categories->xpath("//category[@id='{$item->categoryId}']");
if($free && $is_cat && $free[0] instanceof SimpleXMLElement){
if((int)$free[0]->free){
$tmp = SimpleXML2ArrayWithCDATASupport($item);
$tmp['free'] = (int)$free[0]->free;
$tmp['balance'] = (int)$free[0]->balance;
$tmp['reserve'] = (int)$free[0]->balance - (int)$free[0]->free;
$result[] = $tmp;
}
}
}
}
unset($result_orig);
$file_tree = fopen(dirname(__FILE__)."/{$tag}goods.txt",'w+');
if($file_tree) {
fwrite($file_tree, json_encode($result));
fclose($file_tree);
}
unset($file_tree);
}
return "\nНайдено товаров в каталоге поставщика: " . count($result) . "\nЗапрос занял: ".number_format(microtime(true) - $time, 7) . " сек.\n";
}
//функция получение конкретного товара
function getInfoGood($id_product){
global $xml,$stocks;
if($result = $xml->products->xpath("//product[./article='".$id_product."']")){
$free = $stocks->productsStocks->xpath("//product[@article='{$id_product}']/stock[@xmlId='000000116']");
$tmp = SimpleXML2ArrayWithCDATASupport($result[0]);
$tmp['free'] = (int)$free[0]->free;
$tmp['balance'] = (int)$free[0]->balance;
$tmp['reserve'] = (int)$free[0]->balance - (int)$free[0]->free;
return $tmp;
}
return false;
}
//функция получение резерва товара
/*
$id_product = article
Array
(
[free] => 72
[balance] => 72
[reserve] => 0
)
*/
function getReserveGood($id_product){
global $xml,$stocks;
if($free = $stocks->productsStocks->xpath("//product[@article='{$id_product}']/stock[@xmlId='000000116']")){
$tmp = [];
$tmp['free'] = (int)$free[0]->free;
$tmp['balance'] = (int)$free[0]->balance;
$tmp['reserve'] = (int)$free[0]->balance - (int)$free[0]->free;
return $tmp;
}
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;
/*if($prop['article'] == 'oas_18664' || $prop['article'] == 'oas_18666'){
return false;
}*/
$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->set('old_price', $prop['old_price']);
$res->save();
if(is_array($prop['images']) && !$modx->getObject('msProductFile', array('product_id' => $res->id))){
//привязка картинок addImages
foreach ($prop['images'] as $v) {
addImages($v, $res, $res->pagetitle);
}
}
//удаление картинок
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('Первая ошибка', true));
$modx->log(1, print_r($response->getAllErrors(), true));
//пробуем поменять название и создать повторно
$prop['pagetitle'] = $prop['pagetitle'] . '-' . $prop['article'] . '-double';
$modx->error->message = null;
$response = $modx->runProcessor('resource/create', $prop,
array('processors_path' => MODX_CORE_PATH.'model/modx/processors/')
);
//если всё же ошибка, то выбрасываем error
if ($response->isError()) {
$modx->log(1, print_r('Повторная ошибка: выбрасывание error', true));
$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'] . '-double', '', $res->get('pagetitle')));
$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->set('value', '');
$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();
echo getTreeGoods();
$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 = json_decode(file_get_contents(dirname(__FILE__)."/{$tag}goods.txt"), true);
$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']; //определяем смещение парсинга
foreach($catalog as $tree){
$data = $filtersArray = array();
$i++;
if($i <= $off_set) {continue;}
if(isset($tree['article'])){
$product = getInfoGood($tree['article']);
$reserve = getReserveGood($tree['article']);
//if($product['article'] != '15GIFT-BOX-321-BLUE-L/1'){ continue; }
/*print_r($reserve[0]['reserve']);exit;*/
$data = array('parent' => $idParent, 'context_key' => 'web', 'template' => $tplProduct, 'class_key' => 'msProduct', 'published' => 1);
//if(!$product['total_stock'] || !is_array($product['images'])){continue;}
if(!$product || !is_array($reserve)){continue;}
$a++;
//снимаем с публикации, если товара нет, допускаем только те, которые в наличии
if($reserve['free'] <= 0){
$data['published'] = 0;
}
//получаем нужную инфу по товару
//$data['product_id'] = $product['id'];
$data['groups_id'] = ($product['model'])?:$product['collection'];
$data['article'] = $data['article_donor'] = $tag.$product['article'];
$data['pagetitle'] = $product['title'];
$data['longtitle'] = $product['title'] . ' - заказать в «Gitwell»';
$data['description'] = '[[*pagetitle]] - заказать печать и нанесение логотипа в Москве, компания «Gitwell»';
$data['content'] = "<p class=\"pto_description\">{$product['description']}</p>";
$data['price'] = $product['price'];
$data['weight'] = $product['weight'];
$data['old_price'] = $product['price_old']?:0;
$data['made_in'] = $filtersArray['brand'][] = $product['brand'];
$data['new'] = $data['popular'] = false;
if(isset($product['specials']['value']) && $product['specials']['value'] == 'Новинка'){
$data['new'] = true;
$filtersArray['migalki'][] = 'Новинки';
}
if(isset($product['specials']['value']) && $product['specials']['value'] == 'Промо'){
$data['popular'] = true;
$filtersArray['migalki'][] = 'Выгодные предложения';
$filtersArray['migalki'][] = 'Распродажа';
}
//скачиваем картинки товара
//$first = true;
$images = array( $product['bigImage'] );
if($product['addImages'] && $product['addImages']['image']){
if(is_array($product['addImages']['image'])){
foreach($product['addImages']['image'] as $img){
$images[] = $img;
}
}
else{
$images[] = $product['addImages']['image'];
}
}
foreach($images as $img){
$data['images'][] = downloadImg(end(explode('/', $img)), $img);
}
//определяем родительскую рубрику
$main_category = $tag . $product['categoryId'];
//проверка наличия категории в массиве сопоставления категорий
if($category_manual = getCategoryManual()){
if(isset($category_manual[ $product['categoryId'] ])){
$main_category = $category_manual[ $product['categoryId'] ]['article'];
}
}
//находим ID рубрики
if($parent_tree = getCatExists($main_category)){
$data['parent'] = $parent_tree;
}
//Кастомные тэвэшки для кол-ва доступного товара и для описания упаковки
$data['tv9'] = $reserve['balance']; //на складе
$data['tv10'] = $reserve['free']?:0; //доступно
$data['tv14'] = $data['groups_id'];
if($product['size'] && $product['size'] != '//'){//размеры
$tmp = trim(str_replace('/','x',$product['size']), 'x');
$tmp = str_replace('xx', 'x', $tmp);
$data['size'][] = $tmp . ' мм';
}
$idx_option = 1;
while(isset($product['material'.$idx_option])){//подробная информация о материале
if($product['material'.$idx_option]){
$data['tv13'][] = $product['material'.$idx_option];
if($idx_option == 1){
$filtersArray['material'] = array_map('trim', explode('/', mb_strtolower(trim($product['material'.$idx_option])) ));
}
}
$idx_option++;
}
if($data['tv13']){
$data['tv13'] = implode(', ', $data['tv13']);
}
//цвета
$data['color'] = [];
if(isset($product['multi_color']['value'])){
if(is_array($product['multi_color']['value'])){
foreach($product['multi_color']['value'] as $color){
if( array_search(mb_strtolower(trim($color)), $data['color']) === true ){continue;}
$data['color'][] = mb_strtolower(trim($color));
}
}
else{
if( array_search(mb_strtolower(trim($product['multi_color']['value'])), $data['color']) === true ){continue;}
$data['color'][] = mb_strtolower(trim($product['multi_color']['value']));
}
}
//нанесения
if(isset($product['personalization_list']['personalization'])){
if(is_array($product['personalization_list']['personalization'])){
foreach($product['personalization_list']['personalization'] as $personalization){
preg_match('/уф-печать|уф печать/ui', $personalization['name'], $personal_array);
if($personal_array){
$filtersArray['type_of_application'][] = 'УФ печать';
}
preg_match('/тиснение/ui', $personalization['name'], $personal_array);
if($personal_array){
$filtersArray['type_of_application'][] = 'Тиснение';
}
preg_match('/шелкография/ui', $personalization['name'], $personal_array);
if($personal_array){
$filtersArray['type_of_application'][] = 'Шелкография';
}
preg_match('/термотрансфер/ui', $personalization['name'], $personal_array);
if($personal_array){
$filtersArray['type_of_application'][] = 'Термотрансфер';
}
preg_match('/шеврон/ui', $personalization['name'], $personal_array);
if($personal_array){
$filtersArray['type_of_application'][] = 'Шеврон';
}
preg_match('/шильда/ui', $personalization['name'], $personal_array);
if($personal_array){
$filtersArray['type_of_application'][] = 'Шильда';
}
preg_match('/полимерная наклейка/ui', $personalization['name'], $personal_array);
if($personal_array){
$filtersArray['type_of_application'][] = 'Полимерная наклейка';
}
preg_match('/гравировка/ui', $personalization['name'], $personal_array);
if($personal_array){
$filtersArray['type_of_application'][] = 'Гравировка';
}
preg_match('/тампопечать/ui', $personalization['name'], $personal_array);
if($personal_array){
$filtersArray['type_of_application'][] = 'Тампопечать';
}
if( $filtersArray['print'] && (array_search($personalization['name'], $filtersArray['print']) !== true) ){
$filtersArray['print'][] = $personalization['name'];
}
elseif(!$filtersArray['print']){
$filtersArray['print'][] = $personalization['name'];
}
if($filtersArray['type_of_application']){
$filtersArray['type_of_application'] = array_unique($filtersArray['type_of_application']);
}
}
}
}
if(isset($product['personalization_list']['personalization']) && empty($filtersArray['type_of_application'])){
$filtersArray['type_of_application'][] = 'Прочие нанесения';
}
//Доп. характеристики
foreach($product as $key => $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($key){
case 'coating':
$data['content'] .= $attr_item?"<p class=\"dop_options\">Покрытие: <span>{$attr_item}</span></p>":'';
break;
case 'capacity':
$data['content'] .= $attr_item?"<p class=\"dop_options\">Ёмкость, мА*ч: <span>{$attr_item}</span></p>":'';
break;
case 'format':
$data['content'] .= $attr_item?"<p class=\"dop_options\">Формат: <span>{$attr_item}</span></p>":'';
if($attr_item){
$data['content'] .= $product['dated']?"<p class=\"dop_options\">Датированный: <span>{$product['dated']}</span></p>":'';
$filtersArray['dating'][] = mb_strtolower(trim($product['dated']));
}
break;
case 'flexibility':
$data['content'] .= $attr_item?"<p class=\"dop_options\">Обложка: <span>{$attr_item}</span></p>":'';
if($attr_item){
$filtersArray['type_cover'][] = mb_strtolower(trim($attr_item));
}
break;
case 'stitching':
$data['content'] .= $attr_item?"<p class=\"dop_options\">Сшит: <span>{$attr_item}</span></p>":'';
break;
case 'pages':
$data['content'] .= $attr_item?"<p class=\"dop_options\">Кол-во страниц: <span>{$attr_item}</span></p>":'';
break;
case 'volume_ml':
if($attr_item && ($attr_item < 1)){
$attr_item = $attr_item * 1000;
}
$data['content'] .= $attr_item?"<p class=\"dop_options\">Объём, мл: <span>{$attr_item}</span></p>":'';
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;*/
}
}
//упаковка
$data['tv12'] = '';
if($product['numberPackaged'] || $product['volume']){
if($product['packaging']){
$data['tv12'] .= "<p><span class=\"pack_type\">Вид упаковки единицы товара:</span> <span class=\"pack_val\">{$product['packaging']}</span></p>";
}
if($product['numberPackaged']){
$data['tv12'] .= "<p><span class=\"pack_type\">Количество в транспортной коробке:</span> <span class=\"pack_val\">{$product['numberPackaged']}</span></p>";
}
if($product['numberPackaged'] && $product['volume']){
$volume = $product['numberPackaged'] * $product['volume'];
$data['tv12'] .= "<p><span class=\"pack_type\">Объём коробки, м&sup3;:</span> <span class=\"pack_val\">{$volume}</span></p>";
}
elseif(!$product['numberPackaged'] && $product['volume']){
$data['tv12'] .= "<p><span class=\"pack_type\">Объём коробки, м&sup3;:</span> <span class=\"pack_val\">{$product['volume']}</span></p>";
}
if($product['weight']){
$weight = $product['weight'] * ($product['numberPackaged']?:1);
$data['tv12'] .= "<p><span class=\"pack_type\">Вес коробки, кг:</span> <span class=\"pack_val\">{$weight}</span></p>";
}
}
$filtersArray = array_diff($filtersArray, array(''));
//print_r($filtersArray);exit;
//создание или обновление товара
$modx->error->message = null;
$goods = createProduct($data, $filtersArray);
/*print_r($product);
print_r($reserve);
print_r($data);
print_r($filtersArray);
print_r($goods);
exit;*/
//плюсуем произведённое действие (товар обновлён, создан или ошибка)
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>";
$resources = $modx->getCollection('modResource', array('template' => 4, 'class_key' => 'msCategory'));
$disabled = 0;
$active = 0;
foreach($resources as $res){
if(!count($modx->getChildIds($res->id,10,array('context' => 'web')))){
$res->set('published', false);
$res->save();
$disabled++;
}
else{
$res->set('published', true);
$res->save();
$active++;
}
}
/*print_r($disabled);
echo '/';
print_r($active);*/
$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