Как закалялся код...: 1С Битрикс - дорабатываем компонент bitrix:menu

четверг, 22 августа 2013 г.

1С Битрикс - дорабатываем компонент bitrix:menu

В процессе разработки несложного сайта обнаружил что компонент 1С Битрикс меню (bitrix:menu) некорректно работает при использовании обработки адресов (urlrewrite) для обработки ЧПУ (человеко-понятных адресов).
По задумке в разных разделах сайта лежит своё меню, либо файл формируемый через админку (.<тип меню>.menu.php), либо файл для динамического меню (.<тип меню>.menu_ext.php).
Примерная структура разделов сайта:
  • Section1
  • Section2
  • Section3
В каждом из разделов свое меню битрикс. Если мы будет заходить в каждый раздел отдельно:

http://site.ru/Section1
http://site.ru/Section2
http://site.ru/Section3

То будем видеть нужное нам меню, но в разделах 1 и 2 нам нужно формировать адреса вида:

http://site.ru/Section1/#ELEMENT_CODE#/Section3/
http://site.ru/Section2/#ELEMENT_CODE#/Section3/

Указываем соответствующее правила обработки, либо напрямую в файле urlrewrite.php либо через административную панель: Настройки-Настройки продукта - Обработка адресов.

urlrewrtie.php
$arUrlRewrite = array(
 array(
  "CONDITION" => "#^/Section1/([\\W\\w]+)/Section3/([\\W\\w]+){0,500}#",
  "RULE" => "SECTION1_ELEMENT_CODE=\$1&\$2",
  "ID" => "",
  "PATH" => "/Section3/index.php",
 ),
 array(
  "CONDITION" => "#^/Section2/([\\W\\w]+)/Section3/([\\W\\w]+){0,500}#",
  "RULE" => "SECTION2_ELEMENT_CODE=\$1&\$2",
  "ID" => "",
  "PATH" => "/Section3/index.php",
 ),
);

Данные ссылки будут работать и обработка будет перенаправлена на нужный скрипт находящийся в в разделе 3, к примеру, http://site.ru/Section3/index.php.
Но при переходе по данным ссылкам нам отобразится либо меню из раздела 1 либо меню из раздела 2, но не меню из раздела 3. В принципе все закономерно ведь первым разделом текущего адреса страницы стоит именно Section1 или Section2.
Но как быть если нам нужен физический раздел скрипта который реальной выполняется в данный момент - http://site.ru/Section3/index.php?

В процессе работы заметил что компонент включаемых областей (bitrix:main.include) как то разруливает данную ситуацию, хотя в разных разделах лежат свои файлы включаемых областей и логика работы схожа с подключаемыми файлами компонента меню.

В итоге выяснилось что при использование модуля urlrewrite физический адрес выполняемого скрипта записывается в глобальный массив: $_SERVER и модуль bitrix:main.include знает об этом и умеет обрабатывать такие ситуации, а модуль bitrix:menu пока еще нет. В bitrix:menu использует метод:
$APPLICATION->GetCurDir()
который возвращает пути несуществующие физически:

/Section1/#ELEMENT_CODE#/Section3/
/Section2/#ELEMENT_CODE#/Section3/

А нам нужен физический каталог скрипта - /Section3
Его мы можем получить из значения:
$_SERVER["REAL_FILE_PATH"]
В данном случае оно будет таким: /Section3/index.php

Создаем кастомный компонент, копию bitrix:menu.
Открываем файл component.php.
Ищем вызов метода:
$APPLICATION->GetCurDir()
и после него пишем:
$sRealFilePath = $_SERVER["REAL_FILE_PATH"]; //физический путь скрипта
if (strlen($sRealFilePath) > 0)
{
  //получаем каталог из пути скрипта
 $slash_pos = strrpos($sRealFilePath, "/");
//назначаем полученный каталог нужной переменной
 $curDir = substr($sRealFilePath, 0, $slash_pos+1);
}

Далее по коду именно данный каталог (/Section3) будет использоваться для формирования путей к файлам .<тип меню>.menu.php и .<тип меню>.menu_ext.php.

Удачи в изучении 1С Битрикс!

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

Отправить комментарий