[mSync] Вопрос по импорту через XML
        Добрый день.
Прошу помочь, кто владеет информацией. В описании/документации не нашел ответ, а у автора вопросы отключены.
Вопрос в следующем. Есть ссылка в формате XML, необходимо синхронизировать товары по ней. Это просто ссылка от другого интернет-магазина, т.е. мне НЕ нужна интеграция/связка с 1С и т.д.
Из документации не понятно, является ли связка/авторизация в 1С обязательна или нет? Могу ли я использовать модуль, только для импорта/обновление товаров по XML ссылке.
    
    
                                                                                
            Прошу помочь, кто владеет информацией. В описании/документации не нашел ответ, а у автора вопросы отключены.
Вопрос в следующем. Есть ссылка в формате XML, необходимо синхронизировать товары по ней. Это просто ссылка от другого интернет-магазина, т.е. мне НЕ нужна интеграция/связка с 1С и т.д.
Из документации не понятно, является ли связка/авторизация в 1С обязательна или нет? Могу ли я использовать модуль, только для импорта/обновление товаров по XML ссылке.
Комментарии: 5
                Есть такой компонент msImportExport            
                    
                Да есть, но он не умеет в импорт по XML            
                    
                Связка с 1C обязательна, без этого запустить обработку, по словам автора, сложно. Я писал свой импорт, могу скинуть код скорректируешь под себя.            
                    
                Брось пожалуйста, посмотрю смогу ли адаптировать его под себя. Спасибо            
                    <?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);
    }
}            
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.