Меню из списка инфоблоков и их разделов для базового шаблона

Привелось мне тут на базовом шаблоне интернет-магазина делать меню, состоящее не только из разделов определенного инфоблока, но и из списка инфоблоков. 

Иными словами, есть инфоблок «Одежда» со своими плюшками, и он отнесен в отдельную папку на сайте, а в нем есть свои разделы…
И есть раздел «Игрушки», где все также свое.

Но базовый компонент Битрикса menu.section строит структуру разделов только для 1 инфоблока, что мне не удобно.

Как видно, что одежды тут и вовсе нет.

Изменив .left.menu_ext.php в строке

if ($arIBlock = $dbIBlock->GetNext())

заменив IF на While

while ($arIBlock = $dbIBlock->GetNext())

И перенеся array_merge в тело цикла

while ($arIBlock = $dbIBlock->GetNext())
{
   if(defined("BX_COMP_MANAGED_CACHE"))
      $GLOBALS["CACHE_MANAGER"]->RegisterTag("iblock_id_".$arIBlock["ID"]);

   if($arIBlock["ACTIVE"] == "Y")
   {
      $aMenuLinksExt = $APPLICATION->IncludeComponent("bitrix:menu.sections", "", array(
         "IS_SEF" => "Y",
         "SEF_BASE_URL" => "",
         "SECTION_PAGE_URL" => $arIBlock['SECTION_PAGE_URL'],
         "DETAIL_PAGE_URL" => $arIBlock['DETAIL_PAGE_URL'],
         "IBLOCK_TYPE" => $arIBlock['IBLOCK_TYPE_ID'],
         "IBLOCK_ID" => $arIBlock['ID'],
         "DEPTH_LEVEL" => "1",
         "CACHE_TYPE" => "N",
      ), false, Array('HIDE_ICONS' => 'Y'));
   }
   $aMenuLinks = array_merge($aMenuLinks, $aMenuLinksExt);
}

Тогда получаем меню тупо из разделов

Видим, что одежда появилась, но такое меню уже займет половину экрана, а если подключить все, что есть в магазине?!

Сохраняем изменения .left.menu_ext.php и делаем свой компонент menu.sections.

Я его отнес в свое пространство компонентов и чуть модифицировал.

<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
/** @var CBitrixComponent $this */
/** @var array $arParams */
/** @var array $arResult */
/** @var string $componentPath */
/** @var string $componentName */
/** @var string $componentTemplate */
/** @global CDatabase $DB */
/** @global CUser $USER */
/** @global CMain $APPLICATION */


if(!isset($arParams["CACHE_TIME"]))
   $arParams["CACHE_TIME"] = 36000000;

$arParams["ID"] = intval($arParams["ID"]);
$arParams["IBLOCK_ID"] = intval($arParams["IBLOCK_ID"]);

$arParams["DEPTH_LEVEL"] = intval($arParams["DEPTH_LEVEL"]);
if($arParams["DEPTH_LEVEL"]<=0)
   $arParams["DEPTH_LEVEL"]=1;

$arResult["SECTIONS"] = array();
$arResult["ELEMENT_LINKS"] = array();

if($this->StartResultCache())
{
   if(!CModule::IncludeModule("iblock"))
   {
      $this->AbortResultCache();
   }
   else
   {
      $arFilter = array(
         IBLOCK_ID"=>$arParams["IBLOCK_ID"],
         "GLOBAL_ACTIVE"=>"Y",
         "IBLOCK_ACTIVE"=>"Y",
         "<="."DEPTH_LEVEL" => $arParams["DEPTH_LEVEL"],
      );
      $arOrder = array(
         "left_margin"=>"asc",
      );

      $rsSections = CIBlockSection::GetList($arOrder, $arFilter, false, array(
         "ID",
         "DEPTH_LEVEL",
         "NAME",
         "SECTION_PAGE_URL",
         "IBLOCK_ID",
      ));
      if($arParams["IS_SEF"] !== "Y")
         $rsSections->SetUrlTemplates("", $arParams["SECTION_URL"]);
      else
         $rsSections->SetUrlTemplates("", $arParams["SEF_BASE_URL"].$arParams["SECTION_PAGE_URL"]);
      while($arSection = $rsSections->GetNext())
      {
         //******* САМОЕ ИНТЕРЕСНОЕ
         $IBLOCK=GetIBlock($arSection["IBLOCK_ID"]);
         if ($prevIBLID!==$IBLOCK["ID"]){
            $arResult["SECTIONS"][] = array(
               "ID" => $IBLOCK["ID"],
               "DEPTH_LEVEL" => 0,
               "~NAME" => $IBLOCK["NAME"],
               "~SECTION_PAGE_URL" => $IBLOCK["LIST_PAGE_URL"],
            );
            $arResult["ELEMENT_LINKS"][0] = array($IBLOCK["LIST_PAGE_URL"]);
            $prevIBLID=$IBLOCK["ID"];
         }
         //******* САМОЕ ИНТЕРЕСНОЕ ЗАКОНЧИЛОСЬ, но ниже есть плюшки
         $arResult["SECTIONS"][] = array(
            "ID" => $arSection["ID"],
            "DEPTH_LEVEL" => $arSection["DEPTH_LEVEL"],
            "~NAME" => $arSection["~NAME"],
            "~SECTION_PAGE_URL" => $arSection["~SECTION_PAGE_URL"],
         );
         $arResult["ELEMENT_LINKS"][$arSection["ID"]] = array();
      }
      $this->EndResultCache();
   }
}

//In "SEF" mode we'll try to parse URL and get ELEMENT_ID from it
if($arParams["IS_SEF"] === "Y")
{
   $engine = new CComponentEngine($this);
   if (CModule::IncludeModule('iblock'))
   {
      $engine->addGreedyPart("#SECTION_CODE_PATH#");
      $engine->setResolveCallback(array("CIBlockFindTools", "resolveComponentEngine"));
   }
   $componentPage = $engine->guessComponentPath(
      $arParams["SEF_BASE_URL"],
      array(
         "section" => $arParams["SECTION_PAGE_URL"],
         "detail" => $arParams["DETAIL_PAGE_URL"],
      ),
      $arVariables
   );
   if($componentPage === "detail")
   {
      CComponentEngine::InitComponentVariables(
         $componentPage,
         array("SECTION_ID", "ELEMENT_ID"),
         array(
            "section" => array("SECTION_ID" => "SECTION_ID"),
            "detail" => array("SECTION_ID" => "SECTION_ID", "ELEMENT_ID" => "ELEMENT_ID"),
         ),
         $arVariables
      );
      $arParams["ID"] = intval($arVariables["ELEMENT_ID"]);
   }
}

if(($arParams["ID"] > 0) && (intval($arVariables["SECTION_ID"]) <= 0) && CModule::IncludeModule("iblock"))
{
   $arSelect = array("ID", "IBLOCK_ID", "DETAIL_PAGE_URL", "IBLOCK_SECTION_ID");
   $arFilter = array(
      "ID" => $arParams["ID"],
      "ACTIVE" => "Y",
      "IBLOCK_ID" => $arParams["IBLOCK_ID"],
   );
   $rsElements = CIBlockElement::GetList(array(), $arFilter, false, false, $arSelect);
   if(($arParams["IS_SEF"] === "Y") && (strlen($arParams["DETAIL_PAGE_URL"]) > 0))
      $rsElements->SetUrlTemplates($arParams["SEF_BASE_URL"].$arParams["DETAIL_PAGE_URL"]);

   while($arElement = $rsElements->GetNext())
   {
      $arResult["ELEMENT_LINKS"][$arElement["IBLOCK_SECTION_ID"]][] = $arElement["~DETAIL_PAGE_URL"];
   }
}

$aMenuLinksNew = array();
$menuIndex = 0;
$previousDepthLevel = 1;
// далее везде $arSection["DEPTH_LEVEL"]+1, чтобы компенсировать нулевой уровень

foreach($arResult["SECTIONS"] as $arSection)
{
   if ($menuIndex > 0)
      $aMenuLinksNew[$menuIndex - 1][3]["IS_PARENT"] = $arSection["DEPTH_LEVEL"]+1 > $previousDepthLevel;
   $previousDepthLevel = $arSection["DEPTH_LEVEL"]+1;

   $arResult["ELEMENT_LINKS"][$arSection["ID"]][] = urldecode($arSection["~SECTION_PAGE_URL"]);
   $aMenuLinksNew[$menuIndex++] = array(
      htmlspecialcharsbx($arSection["~NAME"]),
      $arSection["~SECTION_PAGE_URL"],
      $arResult["ELEMENT_LINKS"][$arSection["ID"]],
      array(
         "FROM_IBLOCK" => true,
         "IS_PARENT" => false,
         "DEPTH_LEVEL" => $arSection["DEPTH_LEVEL"]+1,
      ),
   );
}

return $aMenuLinksNew;
?>

Красным выделено то, что изменилось. И, конечно, в .left.menu_ext.php меняем вызов компонента в строке

$aMenuLinksExt = $APPLICATION->IncludeComponent("bitrix:menu.sections", "", array(

на

$aMenuLinksExt = $APPLICATION->IncludeComponent("spl:menu.sections", "", array(

Где «spl» — это мое пространство имен.

Тогда получаем такое

Живой просмотр на сайте http://чегохотят.дети/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *