[mSync] Вопрос по импорту через XML

Добрый день.

Прошу помочь, кто владеет информацией. В описании/документации не нашел ответ, а у автора вопросы отключены.

Вопрос в следующем. Есть ссылка в формате XML, необходимо синхронизировать товары по ней. Это просто ссылка от другого интернет-магазина, т.е. мне НЕ нужна интеграция/связка с 1С и т.д.

Из документации не понятно, является ли связка/авторизация в 1С обязательна или нет? Могу ли я использовать модуль, только для импорта/обновление товаров по XML ссылке.
Роман
15 марта 2023, 09:16
modx.pro
583
0

Комментарии: 5

Алексей
15 марта 2023, 09:47
0
Есть такой компонент msImportExport
    Роман
    15 марта 2023, 09:53
    0
    Да есть, но он не умеет в импорт по XML
    Артур Шевченко
    15 марта 2023, 11:48
    0
    Связка с 1C обязательна, без этого запустить обработку, по словам автора, сложно. Я писал свой импорт, могу скинуть код скорректируешь под себя.
      Роман
      15 марта 2023, 11:53
      0
      Брось пожалуйста, посмотрю смогу ли адаптировать его под себя. Спасибо
        Артур Шевченко
        15 марта 2023, 12:54
        0
        <?php
        ini_set('memory_limit', '512M');
        
        class ImportFeed
        {
            public ModX $modx;
            public string $basepath;
            public string $filename;
            public string $feedurl;
            public string $logpath;
            public array $categoryDefaultFields;
        
            public function __construct($modx, $filename, $feedurl)
            {
                $this->modx = $modx;
                $this->feedurl = $feedurl;
                $this->basepath = $this->modx->getOption('base_path');
                $this->logpath = $this->basepath . 'import_log.txt';
                $this->filename = $this->basepath . $filename;
                $this->categoryDefaultFields = array(
                    'parent' => 89,
                    'template' => 15,
                    'hidemenu' => 1,
                    'published' => 1,
                    'class_key' => 'msCategory'
                );
        
                return true;
            }
        
            public function start($import_categories = true, $import_products = true, $download_feed = true)
            {
                if(file_exists($this->logpath)){
                    unlink($this->logpath);
                }
        
                if ($download_feed) {
                    if ($this->downloadFeed()) {
                        $this->log('[ImportFeed::start] Загружен файл фида.');
                    } else {
                        $this->log('[ImportFeed::start] Не удалось скачать файл фида.');
                        return false;
                    }
                } else {
                    if (file_exists($this->filename)) {
                        $this->log('[ImportFeed::start] Будет произведён импорт из имеющегося файла фида.');
                    } else {
                        $this->log('[ImportFeed::start] Файл фида отсутствует. Загрузите его, чтобы выполнить импорт.');
                        return false;
                    }
                }
        
                $this->log('[ImportFeed::start] Начат импорт.');
                if ($import_categories) {
                    $this->getCategoriesData();
                }
                if ($import_products) {
                    $this->getProductsData();
                }
            }
        
            function downloadFeed()
            {
                $ch = curl_init($this->feedurl);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_HEADER, false);
                $html = curl_exec($ch);
                curl_close($ch);
        
                return file_put_contents($this->filename, $html);
        
            }
        
            private function getCategoriesData()
            {
                $this->log('[ImportFeed::getCategoriesData] Начато получение данных категорий для импорта.');
                if ($reader = $this->getXmlReader($this->filename, 'categories')) {
                    $this->modx->log("[ImportFeed::getCategoriesData] Выделено памяти:" . (memory_get_usage() / 1048576).  " МБ.", 0, 1);
                    if ($xml = $this->readXml($reader)) {
                        $this->log('[ImportFeed::getCategoriesData] Начат импорт категорий.');
                        $c = 0;
                        foreach ($xml->category as $item) {
                            $c++;
                            $parentId = $item->attributes()->parentId ? $item->attributes()->parentId->__toString() : '';
                            $id = $item->attributes()->id ? $item->attributes()->id->__toString() : '';
                            if ($id && !$parentId) {
                                $categoryData = array(
                                    'pagetitle' => $item->__toString(),
                                    'feed_id' => $id,
                                );
                            } else {
                                $categoryData = array(
                                    'feed_id' => $id,
                                    'parentId' => $parentId,
                                    'pagetitle' => $item->__toString(),
                                );
                            }
                            $this->manageCategories($categoryData);
                        }
                        $this->log('[ImportFeed::getCategoriesData] Импорт окончен. Импортировано категорий: ' . $c);
                        unset($xml);
                    } else {
                        $this->log('[ImportFeed::getCategoriesData] Не удалось прочитать данные категорий из фида.');
                    }
                    unset($reader);
                } else {
                    $this->log('[ImportFeed::getCategoriesData] Не удалось получить данные категорий для чтения.');
                }
            }
        
            private function manageCategories($categoryData)
            {
                $categoryData = array_merge($this->categoryDefaultFields, $categoryData);
                if ($categoryData['parentId']) {
                    $data['feed_id'] = $categoryData['parentId'];
                    $data = array_merge($this->categoryDefaultFields, $data);
                    if ($parent = $this->manageObject('modResource', $data, array('class_key' => 'msCategory', 'feed_id' => $data['feed_id'], 'template' => 15))) {
                        $categoryData['parent'] = $parent;
                    }
                }
                $this->manageObject('modResource', $categoryData, array('class_key' => 'msCategory', 'feed_id' => $categoryData['feed_id'], 'template' => 15));
                unset($categoryData);
            }
        
            private function getProductsData()
            {
                $this->log('[ImportFeed::getProductsData] Начато получение данных товаров для импорта.');
                if ($reader = $this->getXmlReader($this->filename, 'offers')) {
                    if ($xml = $this->readXml($reader)) {
                        $this->log('[ImportFeed::getProductsData] Начат импорт товаров.');
                        $c = 0;
                        foreach ($xml->offer as $item) {
                            $c++;
                            $id = $item->attributes()->id ? $item->attributes()->id->__toString() : '';
                            $productData = array(
                                'pagetitle' => $item->name->__toString(),
                                'longtitle' => $item->url->__toString() . '?utm_source=petrovich_znaet',
                                'introtext' => $item->picture->__toString(),
                                'price' => $item->price->__toString(),
                                'categoryId' => $item->categoryId->__toString(),
                                'feed_id' => $id,
                                'published' => 1
                            );
                            $this->manageProducts($productData);
                        }
                        $this->log('[ImportFeed::getProductsData] Импорт окончен. Импортировано товаров: ' . $c);
                        unset($xml);
                    }
                    else {
                        $this->log('[ImportFeed::getProductsData] Не удалось прочитать данные товаров из фида.');
                    }
                    unset($reader);
                } else {
                    $this->log('[ImportFeed::getProductsData] Не удалось получить данные товаров для чтения.');
                }
            }
        
            private function manageProducts($productData)
            {
                $productData['parent'] = 89;
                $productData['class_key'] = 'msProduct';
                $productData['show_in_tree'] = 0;
                if ($parent = $this->modx->getObject('msCategory', array('feed_id' => $productData['categoryId']))) {
                    $productData['parent'] = $parent->get('id');
                }
                $this->manageObject('modResource', $productData, array('class_key' => 'msProduct', 'feed_id' => $productData['feed_id']));
                unset($productData);
            }
        
            private function getXmlReader($filename, $search)
            {
                //read xml file
                $reader = new XMLReader;
                $success = $reader->open($filename);
                if (!$success) {
                    $this->modx->log("[ImportFeed::getXmlReader] Невозможно считать файл $filename. Возможно он содержит ошибки XML.", 0, 1);
                }
        
                //search categories
                while ($reader->read() && $reader->name !== $search);
                return $reader;
            }
        
            private function readXml($reader)
            {
                $outerXml = $reader->readOuterXML();
                return $outerXml ? new SimpleXMLElement($outerXml) : null;
            }
        
            private function manageObject($class, $data, $conditions)
            {
                if ($data['pagetitle']) {
                    $data['description'] = $data['pagetitle'];
                    $data['pagetitle'] = $this->truncate($data['pagetitle']);
                    $data['pagetitle'] .= ' ' . $data['feed_id'];
                }
                if (!$obj = $this->modx->getObject($class, $conditions)) {
                    if (!$data['pagetitle']) {
                        $data['pagetitle'] = 'Ресурс' . $data['feed_id'];
                    }
                    $obj = $this->modx->newObject($class);
                    if ($class === 'modResource') {
                        $data['alias'] = $this->translit($data['pagetitle']);
                    }
                }
                $obj->fromArray($data);
                if ($obj->save()) {
                    $this->log('[ImportFeed::manageObject] Обработан ресурс: ' . $data['pagetitle'] . ' ' . print_r($data,1));
                    $id = $obj->get('id');
                    unset($obj);
                    return $id;
                } else {
                    $this->log('[ImportFeed::manageObject] Не удалось сохранить объект со следующими данными ' . print_r($data, 1));
                }
            }
        
            private function translit($value)
            {
                $converter = array(
                    'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd',
                    'е' => 'e', 'ё' => 'e', 'ж' => 'zh', 'з' => 'z', 'и' => 'i',
                    'й' => 'y', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n',
                    'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't',
                    'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch',
                    'ш' => 'sh', 'щ' => 'sch', 'ь' => '', 'ы' => 'y', 'ъ' => '',
                    'э' => 'e', 'ю' => 'yu', 'я' => 'ya',
                );
        
                $value = mb_strtolower($value);
                $value = strtr($value, $converter);
                $value = mb_ereg_replace('[^-0-9a-z]', '-', $value);
                $value = mb_ereg_replace('[-]+', '-', $value);
                $value = trim($value, '-');
        
                return $value;
            }
        
            private function truncate($str, $length = 90)
            {
                $arr = explode(' ', $str);
                $c = 0;
                $newArr = [];
                foreach ($arr as $r) {
                    $c += mb_strlen($r);
                    $newArr[] = $r;
                    if ($c > $length) {
                        break;
                    }
                }
                return implode(' ', $newArr);
            }
        
            private function log($msg)
            {
                file_put_contents($this->logpath, date('d.m.Y H:i:s') . ' ' . $msg . PHP_EOL, FILE_APPEND);
            }
        }
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      5