- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/classes/general/menu.php
- Класс: CMenu
- Вызов: CMenu::RecalcMenu
function RecalcMenu($bMultiSelect = false, $bCheckSelected = true)
{
if($this->bMenuCalc !== false)
return true;
/**
* @global CMain $APPLICATION
* @global CCacheManager $CACHE_MANAGER
* @noinspection PhpUnusedLocalVariableInspection
*/
global $USER, $DB, $APPLICATION, $CACHE_MANAGER;
$result = array();
$cur_page = $APPLICATION->GetCurPage(true);
$cur_page_no_index = $APPLICATION->GetCurPage(false);
$APPLICATION->_menu_recalc_counter++;
$this->bMenuCalc = true;
if($this->template <> '' && file_exists($_SERVER["DOCUMENT_ROOT"].$this->template))
{
$this->MenuTemplate = $_SERVER["DOCUMENT_ROOT"].$this->template;
}
else
{
if(defined("SITE_TEMPLATE_PATH") && file_exists($_SERVER["DOCUMENT_ROOT"].SITE_TEMPLATE_PATH."/".$this->type.".menu_template.php"))
{
$this->template = SITE_TEMPLATE_PATH."/".$this->type.".menu_template.php";
$this->MenuTemplate = $_SERVER["DOCUMENT_ROOT"].$this->template;
}
elseif(file_exists($_SERVER["DOCUMENT_ROOT"].BX_PERSONAL_ROOT."/php_interface/".LANG."/".$this->type.".menu_template.php"))
{
$this->template = BX_PERSONAL_ROOT."/php_interface/".LANG."/".$this->type.".menu_template.php";
$this->MenuTemplate = $_SERVER["DOCUMENT_ROOT"].$this->template;
}
else
{
$this->template = BX_PERSONAL_ROOT."/templates/.default/".$this->type.".menu_template.php";
$this->MenuTemplate = $_SERVER["DOCUMENT_ROOT"].$this->template;
}
}
if(!file_exists($this->MenuTemplate))
{
$this->LAST_ERROR = "Template ".$this->MenuTemplate." is not found.";
return false;
}
$arMenuCache = [];
$bCached = false;
$bCacheIsAllowed = CACHED_menu!==false && !$USER->IsAuthorized() && $this->MenuExtDir == '';
if($bCacheIsAllowed)
{
$cache_id = $_SERVER["DOCUMENT_ROOT"].",".$this->MenuDir.",,".$this->type;
if($CACHE_MANAGER->Read(CACHED_menu, $cache_id, "menu"))
{
$arMenuCache = $CACHE_MANAGER->Get($cache_id);
$bCached = true;
}
}
$arUserRights = $USER->GetAccessCodes();
$ITEM_INDEX = -1;
$cur_selected = -1;
$cur_selected_len = -1;
$previousDepthLevel = -1;
$arParents = array(); //Stack of menu items
foreach($this->arMenu as $iMenuItem=>$MenuItem)
{
$TEXT = $MenuItem[0];
if($bCached)
{
$LINK = $arMenuCache[$iMenuItem]["LINK"];
}
else
{
//if the link is relative let's transform it to absolute
if(!preg_match("'^(([A-Za-z]+://)|mailto:|javascript:|#)'i", $MenuItem[1]))
{
$LINK = Rel2Abs($this->MenuDir, $MenuItem[1]);
}
else
{
$LINK = $MenuItem[1];
}
$arMenuCache[$iMenuItem]["LINK"] = $LINK;
}
$bSkipMenuItem = false;
$ADDITIONAL_LINKS = $MenuItem[2] ?? [];
$PARAMS = $MenuItem[3] ?? [];
//Calculate menu items stack for iblock items only
if($this->MenuExtDir <> '' && is_array($PARAMS) && isset($PARAMS["FROM_IBLOCK"]))
{
if($previousDepthLevel == -1)
$previousDepthLevel = $PARAMS["DEPTH_LEVEL"];
if($PARAMS["DEPTH_LEVEL"] > $previousDepthLevel)
{
//Deeper into sections tree
if($iMenuItem > 0)
$arParents[] = array("INDEX" => $iMenuItem-1, "DEPTH_LEVEL" => $PARAMS["DEPTH_LEVEL"]);
}
else
{
//Unwind parents stack
while(
!empty($arParents)
&& $arParents[count($arParents)-1]["DEPTH_LEVEL"] > $PARAMS["DEPTH_LEVEL"]
)
{
array_pop($arParents);
}
}
$previousDepthLevel = $PARAMS["DEPTH_LEVEL"];
}
elseif($previousDepthLevel != -1)
{
//End of tree, so reset the stack
$previousDepthLevel = -1;
$arParents = array();
}
if(count($MenuItem)>4)
{
$CONDITION = $MenuItem[4];
if($CONDITION <> '' && (!eval("return ".$CONDITION.";")))
$bSkipMenuItem = true;
}
if(!$bSkipMenuItem)
$ITEM_INDEX++;
if(($pos = mb_strpos($LINK, "?"))!==false)
$ITEM_TYPE = "U";
elseif(mb_substr($LINK, -1) == "/")
$ITEM_TYPE = "D";
else
$ITEM_TYPE = "P";
$SELECTED = false;
if($bCached)
{
$all_links = $arMenuCache[$iMenuItem]["LINKS"];
if(!is_array($all_links))
$all_links = array();
}
else
{
$all_links = array();
if(is_array($ADDITIONAL_LINKS))
{
foreach($ADDITIONAL_LINKS as $link)
{
$tested_link = trim(Rel2Abs($this->MenuDir, $link));
if($tested_link <> '')
$all_links[] = $tested_link;
}
}
$all_links[] = $LINK;
$arMenuCache[$iMenuItem]["LINKS"] = $all_links;
}
if(preg_match("'^(([A-Za-z]+://)|mailto:|javascript:|#)'i", $MenuItem[1]))
{
$PERMISSION = "Z";
}
else
{
if(!$bSkipMenuItem && $bCheckSelected)
{
foreach($all_links as $tested_link)
{
if($tested_link == '')
continue;
$SELECTED = self::IsItemSelected($tested_link, $cur_page, $cur_page_no_index);
if($SELECTED)
break;
}
}
if($bCached)
$PERMISSION = $arMenuCache[$iMenuItem]["PERM"];
else
$arMenuCache[$iMenuItem]["PERM"] = $PERMISSION = $APPLICATION->GetFileAccessPermission(GetFileFromURL($LINK), $arUserRights);
}
if($SELECTED && !$bMultiSelect)
{
/** @noinspection PhpUndefinedVariableInspection */
$new_len = mb_strlen($tested_link);
if($new_len > $cur_selected_len)
{
if($cur_selected !== -1)
$result[$cur_selected]['SELECTED'] = false;
$cur_selected = count($result);
$cur_selected_len = $new_len;
}
else
{
$SELECTED = false;
}
}
//Adjust selection for iblock sections tree
if(
$SELECTED
&& $this->MenuExtDir <> ''
&& is_array($PARAMS)
&& isset($PARAMS["FROM_IBLOCK"])
)
{
foreach($arParents as $parentMenuItem)
{
$parentIndex = $parentMenuItem["INDEX"];
if(
is_array($result[$parentIndex]["PARAMS"])
&& isset($result[$parentIndex]["PARAMS"]["FROM_IBLOCK"])
)
$result[$parentIndex]["SELECTED"] = true;
}
}
if(!$bSkipMenuItem)
{
$r = array(
"TEXT" => $TEXT,
"LINK" => $LINK,
"SELECTED" => $SELECTED,
"PERMISSION" => $PERMISSION,
"ADDITIONAL_LINKS" => $ADDITIONAL_LINKS,
"ITEM_TYPE" => $ITEM_TYPE,
"ITEM_INDEX" => $ITEM_INDEX,
"PARAMS" => $PARAMS
);
$result[] = $r;
}
}
$this->arMenu = $result;
if($bCacheIsAllowed && !$bCached)
{
/** @noinspection PhpUndefinedVariableInspection */
$CACHE_MANAGER->Set($cache_id, $arMenuCache);
}
return true;
}