Наверх

Генерация YML-файла для Яндекс-Маркета

<?php
@ini_set('display_errors', 1);

define('MODX_API_MODE', true);
require dirname(dirname(dirname(dirname(__FILE__)))) . '/index.php';
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');

if ($modx->cacheManager->get('running', array('cache_key' => 'ymarket'))) {
     echo 'Скрипт работает, повторный запуск отменён';
    exit;
}

$running = true;
$modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));

$limit = 500;
$offset = $modx->cacheManager->get('offset', array('cache_key' => 'ymarket'));
$filename = __DIR__ . '/yandexmarket-gen.yml';

if (!$offset) {
    if (file_exists($filename)) {
        echo 'Файл существует, больше ничего не делаем';
        $running = false;
        $modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
        exit;
    }
    echo 'Приступаю к генерации YML-файла' . PHP_EOL;
    $data = '<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="'.date("Y-m-d H:i").'" >
<shop>
<name>'.$modx->getOption('site_name').'</name>
<company>'.$modx->getOption('site_name').'</company>
<url>'.$modx->getOption('site_url').'</url>
<currencies>
<currency id="RUR" rate="1"/>
</currencies>
<categories>'.
    $modx->runSnippet('pdoResources', array(
        'parents' => 23,
        'where' => '{"class_key":"msCategory"}',
        'depth' => 0,
        'sortby' => '{"menuindex":"ASC"}',
        'limit' => 0, 'tpl' => 'categories'
    )) .
'</categories>
<offers>';
    
    if (!$handle = fopen($filename, 'w')) {
        echo "Не могу открыть файл $filename" . PHP_EOL;
        $running = false;
        $modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
        exit;
    }
    if (fwrite($handle, $data) === FALSE) {
        echo "Не могу произвести запись в файл $filename" . PHP_EOL;
        $running = false;
        $modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
        exit;
    }
    fclose($handle);
    unset($data);
    unset($handle);
    // echo 'Записана шапка файла' . PHP_EOL;
    $offset = 0;
}

$end_of_file = false;

if ($data = $modx->runSnippet('msProducts', array(
       'parents' => 0, 'limit' => $limit, 'offset' => $offset, 'tpl' => 'offer', 'includeContent' => 1, 'includeTVs' => 'img,image', 'where' => '{"Data.price:>":0}'
    ))) {
    if (is_writable($filename)) {
        if (!$handle = fopen($filename, 'a')) {
            echo "Не могу открыть файл $filename" . PHP_EOL;
            $running = false;
            $modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
            exit;
        }
        if (fwrite($handle, $data) === FALSE) {
            echo "Не могу произвести запись в файл $filename" . PHP_EOL;
            $running = false;
            $modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
            exit;
        }
        fclose($handle);
    } else {
        echo "Файл $filename недоступен для записи" . PHP_EOL;
        $running = false;
        $modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
        exit;
    }
    // echo 'Записана группа товаров от '.$offset.' до ' . ($offset + $limit);
    $offset = $offset + $limit;
    $modx->cacheManager->set('offset', $offset, 0, array('cache_key' => 'ymarket'));
    unset($data);
    if ($offset > 200000) {
        $end_of_file = true;
    }
} else {
    $end_of_file = true;
}

if ($end_of_file) {
    $data = '</offers>
    </shop>
    </yml_catalog>';
    if (is_writable($filename)) {
        if (!$handle = fopen($filename, 'a')) {
            echo "Не могу открыть файл $filename" . PHP_EOL;
            $running = false;
            $modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
            exit;
        }
        if (fwrite($handle, $data) === FALSE) {
            echo "Не могу произвести запись в файл $filename" . PHP_EOL;
            $running = false;
            $modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
            exit;
        }
        fclose($handle);
    } else {
        echo "Файл $filename недоступен для записи" . PHP_EOL;
        $running = false;
        $modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
        exit;
    }
    unlink(MODX_BASE_PATH . 'yandexmarket.yml');
    rename($filename, MODX_BASE_PATH . 'yandexmarket.yml');
    fopen($filename, 'w');
    echo 'Генерация файла YML завершена';
    $offset = 0;
    $modx->cacheManager->set('offset', $offset, 0, array('cache_key' => 'ymarket'));
}

$running = false;
$modx->cacheManager->set('running', $running, 0, array('cache_key' => 'ymarket'));
exit;


21 комментарий

  1. Артем 14 декабря 2018, 01:31 # 0
    Буду первопроходцем… Уважаемый Илья, подскажите, где вызвать данный сниппет? Пытался создать страницу — пустой шаблон с типом содержимого XML доступный для поиска и т.д, вызываю там этот сниппет, но не получается. Данная тема очень слабо освещена в интернете, прошу Вашей помощи.
    1. Илья Уткин 14 декабря 2018, 07:46 # 0
      Создайте файл /core/components/ymarket/generate.php, в этот файл вставьте код и настройте запуск этого файла по CRON каждую минуту. Внёс изменения в код, в предыдущем варианте было не всё правильно.
      1. Илья Уткин 14 декабря 2018, 09:52 # 0
        Скрипт начнёт создавать YML-файл, сохраняя его в файле /core/components/ymarket/yandexmarket-gen.yml

        Когда генерация будет завершена, содержимое файла будет скопировано в корень сайта. После этого, чтобы запустить генерацию нового файла, нужно просто удалить файл yandexmarket-gen.yml

        У меня настроена задача ежедневно удалять файл в 3 часа ночи. Тогда к утру файл для яндекс-маркета обновляется и каждый день он более-менее свежий.
    2. Артем 14 декабря 2018, 15:59 # 0
      Большое спасибо, буду пробовать!
      1. Виталий 31 января 2019, 13:48 # 0
        Здравствуйте. Все сделал по примеру. При проверке в яндекс вебмастере вот такая ошибка skrinshoter.ru/s/310119/iZ1WALBJ можете подсказать с чем это может быть связано? Ссылка на страницу yml
        1. Илья Уткин 31 января 2019, 13:58 # 0
          Здравствуйте. Вы не поменяли ID-шник вашего каталога вот здесь:
          'parents' => 23,
          1. Виталий 31 января 2019, 16:00(Комментарий был изменён) # 0
            Да. Такой косяк был, 30-го числа заменил skrinshoter.ru/s/310119/RT5yngEQ и заново сгенерировал файл. Может закэшировалось сильно? Хотя я все кэши почистил. Только что снова сгенерировал новый файл.
            1. Илья Уткин 01 февраля 2019, 19:04 # 0
              Значит, у вас не создан чанк categories. Пример этого чанка у меня не сохранился. Попробуйте воспроизвести его сами.
              1. Виталий 01 февраля 2019, 19:18 # 0
                А я еще думаю, в сниппете вижу обращение к чанкам. Значит нужно 2 чанка создать как я понял. Ок, попробую, спасибо.
                1. Илья Уткин 02 февраля 2019, 18:33 # 0
                  Оставите здесь в комментариях код чанков, если у вас получится? Чтобы другим пользователям было понятнее, что надо делать.
                  1. Виталий 07 февраля 2019, 12:03 # 0
                    Без проблем, но пока у меня чанки не работают. Не подскажете skrinshoter.ru/s/070219/ZIKsujvk в чем может быть проблема?
                    1. Илья Уткин 07 февраля 2019, 12:36 # 0
                      Неизвестная категория, значит у товара parent такой, которого нет в списке categories. Может, какие-то категории не попали в выборку?
                      1. Виталий 07 февраля 2019, 12:40 # 0
                        Вообще да. Попали в выборку лишь главные категории, а дочерние нет. Ниже указал свои чанки.
                        1. Виталий 07 февраля 2019, 12:50(Комментарий был изменён) # 0
                          Нашел косяк. Стояла глубина 0, чтобы вывести все дочерние категории поставил 99 глубину.

                          'depth' => 99
                          
                          1. Виталий 07 февраля 2019, 19:32 # 0
                            Снова ругается skrinshoter.ru/s/070219/qyLStMz2
            2. Виктор 01 февраля 2019, 18:27 # 0
              Здравствуйте. Подскажите, нужно создать сниппет, поставить нужный ид и что еще сделать?
              1. Илья Уткин 01 февраля 2019, 19:03 # 0
                А вот, выше в комментариях я добавил инструкцию.
                1. Виктор 01 февраля 2019, 19:33(Комментарий был изменён) # 0
                  Спасибо за ответ. т.е нужно только создать файл, в коде указать нужные ид и через какое-то время будет результат?
                  У меня ничего не происходит.
                  1. Илья Уткин 02 февраля 2019, 18:29 # 0
                    Нужно настроить CRON на запуск этого файла каждую минуту.
              2. Виталий 07 февраля 2019, 12:06 # 0
                У меня такие чанки:

                Категория
                <category id="[[+id]]" 
                [[+parent:is=`12`:then=``:else=`parentId="[[+parent]]"`]] >
                    [[+pagetitle:stripString=`&`:stripString=`
                `:striptags=``:replace=`&==&`]]
                </category>
                
                Продукт
                <offer id="[[+id]]" available="true">
                <url>http://site.ru/[[~[[+id]]]]</url>
                <price>[[+price:stripString=` `]]</price>
                <currencyId>RUR</currencyId>
                <categoryId>[[+parent]]</categoryId>
                <picture>http://site.ru/[[+image]]</picture>
                <name>[[+pagetitle]]</name>
                <model>[[+article]]</model>
                </offer>
                
                1. Raman Navadvorski 17 февраля 2019, 03:45(Комментарий был изменён) # 0
                  :replace=`&==& amp;`]]
                  
                  вот так должно быть (без пробелов) )
                  YML любит ругаться на запрещенные символы, поэтому их нужно вырезать или заменять на допустимые

                Авторизация

                через сервис Loginza:

                Подписка или RSS

                Буду присылать новые статьи — никакого спама



                Шаблоны MODX

                1 2 Дальше »

                Объектная
                модель
                MODX