Автогенерация Sitemap

Автогенерация карты для Сотбит: SEO умного фильтра

Чтобы вручную не запускать генерацию карты модуля Сотбит: SEO умного фильтра – мета-теги, заголовки, карта сайта, можно сделать автоматическую генерацию по cron заданию.

Настройки генерации карт

В первую очереде необходимо добавить настройки для генерации карт сайта и модуля

Модуль Поисковая оптимизация

В первую очеред должн абыть создана основная карта сайт на странице - Администрирование / Маркетинг / Поисковая оптимизация / Настройка sitemap.xml

2022-04-28_19-35.png

Если карты для нужного сайта нет, ее нужно добавить. На детальной странице настроек нужно обратить внимание на название файла карты сайта. Оно может быть любым, его точное название понадобится дальше.

2022-04-28_19-36.png

Модуль SEO умного фильтра

Далее необходимо добавить настройки для генерации sitemap c ссылками на страницы организованные модулем - Сотбит: SEO умного фильтра – мета-теги, заголовки, карта сайта

Для этого переходим на страницу Администрирование / Сотбит / SEO умного фильтра / Генерация карты сайта. И добавляем либо редактируем настроки sitemap для конкретного сайта.

2022-04-28_19-50.png

На странице редактирвоания натсроек важно обратить внимание на название файла, оно должно быть только таким же как в настройках основной карты сайта.

2022-04-28_19-52.png

Настройка автогенерации

Теперь необходимо настроить модуль автогенерации карты сайта, выбрав нужные нужные настройки формирвоания и добавив задание в cron.

Включение и выбор карт

Переодим в настройки модуля Администрирование / BXmaker / Автогенерация Sitemap / Настройки модуля.

На вкладке с нужным сайтом необходимо включить автогенерацию и отметить нужные карты. В некоторых случаях можно указать интервал, по умолчанию раз в 360 минут = 6 часов.

2022-04-28_19-58.png

Cron задание

Фоновую задачу (cron задание) необходимо запускать ежеминутно, так как генерация файлов многошаговая. По окончании генерации карты сайта модуль просто ничего не будет делать пока не наступит время следуюущего запуска исходя из заданных интервалов.

Путь до запускаемого файла выводится на странице настроек модуля в самом низу и даны некоторые комментарии.

2022-04-28_20-12.png

Обработчики событий

И самый главный этап это добавление обработчиков событий модуля. Эти обработчик пво время автоматической генерации галвнйо краты сайта:

  1. Запустят генерацию файлов sitemap модуля SEO умного фильтра
  2. Добавят ссылки на сгенерированые файлы в конец основной карты

Для этого добавляем напримре в файл /bitrix/php_interface/init.php следующий код


// карта сайта
//добавление дополнительного файла с сылками в карту сайта при генерации
$eventManager->addEventHandler(
    "bxmaker.autositemap",
    "onSitemapStep",
    ["CBXmakerEventHandler", 'bxmaker_autositemap_onSitemapStep']
);

$eventManager->addEventHandler(
    "bxmaker.autositemap",
    "onSitemapStepPrepare",
    ["CBXmakerEventHandler", 'bxmaker_autositemap_onSitemapStepPrepare']
);


class CBXmakerEventHandler
{
    //карту seo умного фильтра перемещаем в конец
    public function bxmaker_autositemap_onSitemapStep(\Bitrix\Main\Event $event)
    {
        $NS = $event->getParameter('NS');

        if(!empty($NS['XML_FILES']))
        {
            usort($NS['XML_FILES'], function($row) {
               if(strpos($row, 'sitemap_seometa_') !== false)
               {
                   return 1;
               }
               return 0;
            });
        }

        //завершаем
        $arReturn = [
            'NS' => $NS,
        ];

        $result = new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $arReturn);
        return $result;
    }


    // генерируем карту сотбит перед использованием в основной карте
    public function bxmaker_autositemap_onSitemapStepPrepare(\Bitrix\Main\Event $event)
    {
        $NS = $event->getParameter('NS');
        $arMainSitemap = $event->getParameter('arSitemap');
        $percent = 0;
        $dataKey = 'bxmaker_autositemap_onSitemapStepPrepare_' . $arMainSitemap['ID'];

        if (!isset($NS[$dataKey])) {
            $NS[$dataKey] = [];
        }

        $requestData = &$NS[$dataKey];


        try {
            if (empty($requestData)) {

                //ищем настройки
                $sitemapId = null;
                $dbr = \Sotbit\Seometa\SitemapTable::getList([
                    'filter' => [
                        'SITE_ID' => $arMainSitemap['SITE_ID']
                    ]
                ]);
                if ($ar = $dbr->Fetch()) {

                    $arSettings = unserialize($ar['SETTINGS']);

                    if($arSettings['FILENAME_INDEX'] === $arMainSitemap["SETTINGS"]["FILENAME_INDEX"] )
                    {
                        $sitemapId = $ar['ID'];
                    }
                }

                if(is_null($sitemapId))
                {
                    throw new Exception(sprintf('Для основной карты [ID:%s] сайта %s не найдены настройки в модуле Сотбит: SEO умного фильтра...', $arMainSitemap['ID'], $arMainSitemap["SITE_ID"]));
                }


                $requestData['ID'] = $sitemapId;
                $requestData['limit'] = 10000;
                $requestData['offset'] = 0;
                $requestData['sitemap_index'] = 1;
            }

            if (isset($requestData['data'])) {
                $requestData = json_decode($requestData['data'], true);
            }

            if (!CModule::IncludeModule('sotbit.seometa')) {
                $percent = 100;
            } else {
                $arSitemap = \Sotbit\Seometa\SitemapTable::getById($requestData['ID'])->fetch();
                if ($arSitemap['SITE_ID']) {
                    $optionCountLinksForOperation = \Bitrix\Main\Config\Option::get(
                        \CSeoMeta::MODULE_ID,
                        'SEOMETA_SITEMAP_COUNT_LINKS_FOR_OPERATION',
                        '10000',
                        $arSitemap['SITE_ID']
                    );

                    $optionCountLinks = \Bitrix\Main\Config\Option::get(
                        \CSeoMeta::MODULE_ID,
                        'SEOMETA_SITEMAP_COUNT_LINKS',
                        '50000',
                        $arSitemap['SITE_ID']
                    );

                    $requestData['limit'] = ($optionCountLinksForOperation < $optionCountLinks ? $optionCountLinksForOperation : $optionCountLinks);
                }

                $seometaSitemap = new \CSeoMetaSitemapLight();
                $sitePaths = $seometaSitemap->pathMainSitemap($requestData['ID']);
                $requestData['SITE_ID'] = $sitePaths['site_id'];

                foreach($requestData as $key => $value)
                {
                    $seometaSitemap->setRequestData($key, $value);
                }

                if (!is_array($arSitemap) || $sitePaths['TYPE'] === 'ERROR') {
                    throw new Exception('Не найдена карта сайт');
                }

                $arSitemap['SETTINGS'] = unserialize($arSitemap['SETTINGS']);


                if (!$sitePaths['domain_dir']) {
                    throw new Exception('Не удалось определить корневую директорию сайта для карты');
                }

                $SiteUrl = $sitePaths['domain_dir'];

                //делаем бэкап
                if (!isset($requestData['progressbar'])
                    && (new \Sotbit\Seometa\Helper\BackupMethods)->makeBackup(
                        $sitePaths['abs_path']
                    ) == '') {
                    $seometaSitemap->deleteOldSeometaSitemaps($sitePaths['abs_path']);
                }


                $arrConditionsParams = \Sotbit\Seometa\ConditionTable::getConditionBySiteId($sitePaths['site_id']);

                $filter['ACTIVE'] = 'Y';

                if ($arSitemap['SETTINGS']['EXCLUDE_NOT_SEF'] == 'Y') {
                    $filter['CONDITION_ID'] = [];

                    foreach ($arrConditionsParams as $conditionParam) {
                        $filter['CONDITION_ID'] = array_merge(
                            $filter['CONDITION_ID'],
                            [$conditionParam['ID']]
                        );
                    }
                }

                $arrUrls = \Sotbit\Seometa\SeometaUrlTable::getList(
                    array(
                        'select' => array(
                            'ID',
                            'NEW_URL',
                            'REAL_URL',
                            'DATE_CHANGE',
                            'CONDITION_ID'
                        ),
                        'filter' => $filter,
                        'order' => array('ID'),
                        'limit' => $requestData['limit'],
                        'offset' => $requestData['offset'] !== 0 ? $requestData['limit'] * $requestData['offset'] : 0
                    )
                )->fetchAll();

                if ($arrUrls !== false && count($arrUrls) > 0) {
                    $_REQUEST = array_merge($_REQUEST, $requestData);

                    $requestData['data'] = $seometaSitemap->generateSitemap(
                        $arrUrls,
                        $SiteUrl
                    );

                    $return = json_decode($requestData['data'], true);
                    if (preg_match('/([\d]+%)/', $return['progressbar'], $match)) {
                        $percent = min(99, (int)$match[1]);
                    }
                } else {
                    \Sotbit\Seometa\SitemapTable::update(
                        $requestData['ID'],
                        array('DATE_RUN' => new Bitrix\Main\Type\DateTime())
                    );

                    if (!isset($NS['XML_FILES'])) {
                        $NS['XML_FILES'] = [];
                    }


                    $i = 1;
                    while ($i <= $requestData['sitemap_index']) {
                        $xmlFile = 'sitemap_seometa_' . $requestData['ID'] . '_' . $i . '.xml';
                        if (!in_array($xmlFile, $NS['XML_FILES'])) {
                            $NS['XML_FILES'][] = $xmlFile;
                        }

                        $i++;
                    }
                    $percent = 100;
                }
            }
        } catch (\Throwable $ex) {
            $percent = 100;

            \CEventLog::Add(array(
                "SEVERITY" => "ERROR",
                "AUDIT_TYPE_ID" => "ERROR_PREPARE",
                "MODULE_ID" => "bxmaker.sitemap",
                "ITEM_ID" => '',
                "DESCRIPTION" => "Ошибка при подготовке дополнительной краты через sotbit.seometa - ".$ex->getMessage().' | '.$ex->getTraceAsString(),
            ));
        }


        $arReturn = [
            'NS' => $NS,
            'COMPLETE' => $percent >= 100,
            'STATUS' => isset($ex) ? $ex->getMessage() . ' | ' . $ex->getTraceAsString() : sprintf(
                'Подготовка карты для SEO умного фильтра, выполнено на %d %%',
                $percent
            ),
            'PROGRESS' => $percent,
        ];

        $result = new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS, $arReturn);
        return $result;
    }

}

Результат

В итоге должно получиться примерно такое содержимое файла sitemap. В нем будут перечислены ссылки на карты с ссылками на страницы сайта.

2022-04-28_20-30.png

Временные файлы

В процессе генерации карты, текущее состояние, статус - хранятся во временных файлах в диретории /upload/bxmaker.autositemap/. Файлы имеют название sitemap_{идентификатор сайта}.tmp