Перед выполнением этой большой задачи, я разделил ее на несколько более мелких подзадач на основе следующих требований технического задания:
- В файле должны быть указаны все уникальные и каноничные страницы, отдающие 200 код ответа сервера, которые не закрыты в robots.txt, не содержат HTTP-заголовок X-Robots-Tag noindex, не содержат мета-тег robots noindex.
- В файле sitemap.xml приоритет для всех страниц должен быть 0.5 (<priority>0.5</priority>). Частоту обхода при изменениях (changefreq) оставить weekly.
- Ссылка на sitemap.xml должна быть указана в файле robots.txt (Это стандартная возможность Битрикса)
- Файл sitemap.xml должен формироваться автоматически. Обновление должно происходить раз в сутки.
В процессе выполнения этой задачи мне очень помогла статья «Автогенерация карты сайта sitemap.xml с помощью crontab». Спасибо автору за нее.
Шаг 1. Создаем новую карту сайта в админке сайта. Также не забудьте ее настроить – указать какие статические страницы должны в ней присутствовать, а какие – нет. То же касается и динамической информации (инфоблоков и их секций).
Позже нам понадобится ее идентификатор, который в данном случае равен 3.
Шаг 2. Отключаем пересоздание карты сайта в инфоблоках. Это нужно сделать для того, чтобы карта сайта создавалась с минимальной нагрузкой на сервер и не генерировалась при каждом изменении в элементах инфоблоков. Для этого есть полезный скрипт, код которого я нашел в упомянутой выше статье. Вот ссылка на него. Просто загрузите его на сайт и вызовите в браузере. Когда он отработает вы просто увидите надпись «OK» на экране. Скрипт отключает обработчики событий для инфоблоков, которые связаны с обновлением sitemap xml битрикс.
Обращаю внимание, что если вам захочется «откатить» изменения и вернуть все как было просто замените в коде название метода unRegisterEventHandler на registerEventHandler и запустите скрипт.
Шаг 3. Переходим непосредственно к заданиям. Создаем в папке /local/php_interface/ папку crontab и в ней размещаем файл seo_sitemap_run.php. Этот файл мы позже будем запускать по расписанию. Он и будет формировать нашу карту сайта (sitemap). Обращаю ваше внимание, что файл этот в стандартном виде находится в папке /bitrix/modules/seo/admin/. Мы будем использовать файл который вы можете скачать по ссылке. Этот файл я взял из архива, который скачал по ссылке из упомянутой выше статьи и внес небольшие изменения. Вы, конечно, можете скопировать его из ядра системы, но придется вносить много изменений и можно будет легко запутаться и получить неработоспособный код с ошибками.
Содержимое стандартного файла довольно большое – на момент написания статьи в нем содержится чуть больше 1000 строк кода, поэтому размещать его в статье я не буду. В общих чертах в нем происходит следующее:
>
Подключаются все необходимые классы и модули bitrix.seo и bitrix.iblock. Далее берется карта сата по ее идентификатору. Настройки карты сохраняются в массив SETTINGS (в нем сохраняются данные, которые мы указали на вкладках «Файлы» и «Инфоблоки» в админке сайта). На основе него сначала формируется sitemap xml битрикс по файлам затем по инфоблокам. Все карты сайта сохраняются по разным файлам. При формировании sitemap используется таблица b_seo_sitemap_runtime в БД продукта. Также обрабатываются и форумы. Информация из них также добавляется в 1с битрикс sitemap.
Для выполнения наших задач, нужно вносить изменения в файлы модуля bitrix.seo, а это ядро продукта, которое должно быть неизменно, да и при обновлениях все изменения сотрутся. Можно, конечно, создать копию модуля и работать с ним, но это неудобно и сложно. После небольших раздумий был найден способ лучше. Я просто создал классы наследники тех классов, методы которых мне нужно было изменить.
Я разместил их в файле sitemap_custom.php в той же папке /local/php_interface/crontab
Классы, от которых я наследовался для внесения изменений следующие: SitemapFile и SitemapRuntime.
Для выполнения задания из пункта 2 в классе SitemapFileCustom (наследник SitemapFile) я внес изменения в константу ENTRY_TPL. Как оказалось – это было самое простое задание.
Для выполнения пункта 1 пришлось изменить метод addEntry. В нем я добавил проверку входит ли текущая запись в секцию Dissalow файла robots.txt. Если входит, то она не попадает битрикс файл sitemap.
PHP
Также добавить пару вспомогательных методов (getRobotsRulesList и replaceProtoHost):
• getRobotsRulesList - Получаем список url из robots.txt по типу (Disallow / Allow)
PHP
• replaceProtoHost - является просто «оберткой» над PHP функцией str_replace. Она удаляет из url протокол и хост.
PHP
Кроме описанного выше класса я также создал наследника класса SitemapRuntime с именем SitemapRuntimeCustom, но в процессе работы выяснилось, что вносить в него изменения не требуется. Я не стал от него отказываться, оставил на всякий случай.
Переходим к файлу seo_sitemap_run.php, который мы разместили в /local/php_interface/crontab. Если воспользовались ссылкой на этой файл, указанной выше в статье, то никаких изменений вносить не нужно.
Давайте рассмотрим основные моменты этого скрипта, на которые нужно обратить внимание:
• в самом начале $_SERVER['DOCUMENT_ROOT'] переопределена - это нужно для корректного запуска скрипта через cron.
• далее устанавливаем значение служебных констант Битрикса и настроек PHP для этого скрипта:
PHP
• файл с кастомизированными классами SitemapFileCustom и SitemapRuntimeCustom должен быть подключен
PHP
• Проверка прав пользователя на использование модуля bitrix.seo не должна проводится, также не должна использоваться в скрипте функция check_bitrix_sessid(). Причина в том, что при запуске по cron он производится от неавторизованного пользователя, которого не будет прав на совершение операции seo_tools. В стандартном варианте скрипт запускается из админки и у пользователя права есть. Функция check_bitrix_sessid() используется при отправке формы, а при запуске по расписанию никакая форма не отправляется.
PHP
Чтобы проверять результат в процессе работы можно вызывать файл в браузере с параметрами action=sitemap_run и идентификатором карты сайта ID (в нашем случае ID=3). Пример вызова: /local/php_interface/crontab/seo_sitemap_run.php?action=sitemap_run&ID=3&lang=ru
Это будет работать, если в указанных папках отсутствует файл .htaccess с запретом доступа (Deny From All). Обращаю внимание, что отсутствие подобного файла на боевом сайте является угрозой безопасности.
По требованиям технического задания ссылка на sitemap.xml должна быть указана в файле robots.txt. Как я уже упоминал выше – это стандартная возможность модуля bitrix.seo, поэтому нам делать ничего для этого не нужно.
После проведения операций, описанных в шаге 3 можно сказать, что задача почти выполнена. Осталось только настроить расписание запуска скрипта seo_sitemap_run.php. Предположим, что нужно генерировать карту сайта каждый день в 00:00.
Шаг 4. Если вы используете виртуальный хостинг, то добавить запуск скрипта по расписанию (cron), вы сможете в личном кабинете хостинга.
Если же у вас выделенный сервер по управлением Unix-системы, вы можете добавить задание через консоль следующим образом:
$ crontab –e
При этом запустится редактор по-умолчанию Например, в Битрикс ВМ это Vim. Чтобы перейти в режим вставки нажимаем 'i', вводим команду:
0 0 * * * /usr/bin/php -f /home/bitrix/www/local/php_interface/crontab/seo_sitemap_run.php action=sitemap_run ID=3 lang=ru
нажимаем «Esc», для сохранения вводим команду «:wa», для выхода «:q».
Для проверки списка установленных задач можно выполнить команду в консоли:
$ crontab -l
После проведения действий, описанных выше, можно утверждать, что наша задача выполнена. Мы кастомизировали в битрикс автогенерацию sitemap и настроили расписание для ее запуска.