debugMode = $this->Application->isDebugMode();
$this->superAdminMode = $this->Application->RecallVar('super_admin');
}
/**
* Set's prefix and special
*
* @param string $prefix
* @param string $special
* @access public
*/
public function Init($prefix, $special)
{
parent::Init($prefix, $special);
$this->BuildTree();
}
/**
* Builds xml for tree in left frame in admin
*
* @return void
* @access public
*/
public function BuildTree()
{
if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) {
$data = $this->Application->getCache('master:sections_parsed', false, CacheSettings::$sectionsParsedRebuildTime);
}
else {
$data = $this->Application->getDBCache('sections_parsed', CacheSettings::$sectionsParsedRebuildTime);
}
if ( $data ) {
$this->Tree = unserialize($data);
return ;
}
if ( !defined('IS_INSTALL') || !IS_INSTALL ) {
// don't reread all configs during install, because they are reread on every install step
$this->Application->UnitConfigReader->ReReadConfigs();
}
$this->Tree = Array ();
// 1. build base tree (don't update parent with children list yet)
foreach ( $this->Application->UnitConfigReader->getUnitConfigsWithoutPriority() as $prefix ) {
$this->_processPrefixSections($prefix);
}
foreach ( $this->Application->UnitConfigReader->getUnitConfigsWithPriority() as $prefix ) {
$this->_processPrefixSections($prefix);
}
// 2. apply section adjustments
foreach ( $this->Application->UnitConfigReader->getPrefixes() as $prefix ) {
$config = $this->Application->getUnitConfig($prefix);
$section_adjustments = $config->getSectionAdjustments();
if ( !$section_adjustments ) {
continue;
}
foreach ($section_adjustments as $section_name => $adjustment_params) {
if ( is_array($adjustment_params) ) {
if ( !array_key_exists($section_name, $this->Tree) ) {
// don't process adjustments for non-existing sections
continue;
}
$this->Tree[$section_name] = kUtil::array_merge_recursive($this->Tree[$section_name], $adjustment_params);
}
else {
// then remove section
unset($this->Tree[$section_name]);
}
}
}
// 3.
foreach ($this->Tree as $section_name => $section_params) {
// 3.1. update parent -> children references
$parent_section = $section_params['parent'];
$section_order = "{$section_params['priority']}";
if ( !isset($parent_section) ) {
// don't process parent section of "in-portal:root" section
continue;
}
if ( !array_key_exists('children', $this->Tree[$parent_section]) ) {
$this->Tree[$parent_section]['children'] = Array ();
}
if ( array_key_exists($section_order, $this->Tree[$parent_section]['children']) ) {
trigger_error('Section "' . $section_name . '" has replaced section "' . $this->Tree[$parent_section]['children'][$section_order] . '" (parent section: "' . $parent_section . '"; duplicate priority: ' . $section_order . ')', E_USER_WARNING);
}
$this->Tree[$parent_section]['children'][$section_order] = $section_name;
if ( $section_params['type'] == stTAB ) {
// if this is tab, then mark parent section as TabOnly
$this->Tree[$parent_section]['tabs_only'] = true;
}
// 3.2. process icons here, because they also can be adjusted
if ( isset($section_params['icon']) && preg_match('/([^:]+):(.*)/', $section_params['icon'], $regs) ) {
$this->Tree[$section_name]['icon'] = $regs[2];
$this->Tree[$section_name]['icon_module'] = $regs[1]; // set "icon_module" used in "combined_header" block
$module_folder = trim($this->Application->findModule('Name', $regs[1], 'Path'), '/');
if ( $module_folder == '' ) {
$module_folder = 'core';
}
}
else {
$module_folder = $this->Application->getUnitConfig($section_params['SectionPrefix'])->getModuleFolder();
if ( !array_key_exists('icon_module', $section_params) ) {
// set "icon_module" used in "combined_header" block
$this->Tree[$section_name]['icon_module'] = $this->Application->findModule('Path', $module_folder . '/', 'Name');
}
}
// this is to display HELP icon instead of missing one.. can be replaced with some other icon to draw attention
$icon_file = $module_folder . '/admin_templates/img/icons/icon24_' . $this->Tree[$section_name]['icon'];
/*$core_file = FULL_PATH.'/core/admin_templates/img/icons/icon24_' . $this->Tree[$section_name]['icon'].'.png';
if ($module_folder != 'core' && file_exists($core_file) && file_exists(FULL_PATH.'/'.$icon_file.'.png')) {
if (crc32(file_get_contents($core_file)) == crc32(file_get_contents(FULL_PATH.'/'.$icon_file.'.png'))) {
trigger_error('Section "' . $section_name . '" uses icon copy from "Core" module', E_USER_NOTICE);
}
}*/
if ( !file_exists(FULL_PATH . '/' . $icon_file . '.png') ) {
$this->Tree[$section_name]['icon'] = 'help';
$this->Tree[$section_name]['icon_module'] = 'core';
}
}
$this->Application->HandleEvent(new kEvent('adm:OnAfterBuildTree'));
if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) {
$this->Application->setCache('master:sections_parsed', serialize($this->Tree));
}
else {
$this->Application->setDBCache('sections_parsed', serialize($this->Tree));
}
}
function _processPrefixSections($prefix)
{
$config = $this->Application->getUnitConfig($prefix);
$sections = $config->getSections();
if ( !$sections ) {
return ;
}
foreach ($sections as $section_name => $section_params) {
// we could also skip not allowed sections here in future
if ( isset($section_params['SectionPrefix']) ) {
$section_prefix = $section_params['SectionPrefix'];
}
elseif ( $this->Application->getUnitConfig($prefix)->getSectionPrefix() ) {
$section_prefix = $this->Application->getUnitConfig($prefix)->getSectionPrefix();
}
else {
$section_prefix = $prefix;
}
if ( is_float($section_params['priority']) ) {
$section_params['priority'] = (string)$section_params['priority'];
}
$section_params['SectionPrefix'] = $section_prefix;
$section_params['url']['m_opener'] = 'r';
$section_params['url']['no_pass_through'] = 1;
$pass_section = getArrayValue($section_params, 'url', 'pass_section');
if ( $pass_section ) {
unset($section_params['url']['pass_section']);
$section_params['url']['section'] = $section_name;
if ( !isset($section_params['url']['module']) ) {
$module_name = $this->Application->findModule('Path', $config->getModuleFolder() . '/', 'Name');
$section_params['url']['module'] = $module_name;
}
}
if ( !isset($section_params['url']['t']) ) {
$section_params['url']['t'] = 'index';
}
if ( !isset($section_params['onclick']) ) {
$section_params['onclick'] = 'checkEditMode()';
}
if ( !isset($section_params['container']) ) {
$section_params['container'] = 0; // for js tree printing to xml
}
$current_data = isset($this->Tree[$section_name]) ? $this->Tree[$section_name] : Array ();
if ( $current_data ) {
trigger_error('Section "' . $section_name . '" declaration (originally defined in "' . $current_data['SectionPrefix'] . '") was overwriten from "' . $prefix . '"', E_USER_WARNING);
}
$this->Tree[$section_name] = kUtil::array_merge_recursive($current_data, $section_params);
}
}
/**
* Returns details information about section
*
* @param string $section_name
* @return Array
*/
function &getSectionData($section_name)
{
if (isset($this->Tree[$section_name])) {
$ret =& $this->Tree[$section_name];
}
else {
$ret = Array();
}
return $ret;
}
/**
* Returns first child, that is not a folder
*
* @param string $section_name
* @param bool $check_permission
* @return string
* @access public
*/
public function getFirstChild($section_name, $check_permission = false)
{
$section_data =& $this->getSectionData($section_name);
/** @var Array $children */
$children = isset($section_data['children']) && $section_data['children'] ? $section_data['children'] : false;
if ( $children ) {
// get 1st child
ksort($children, SORT_NUMERIC);
foreach ($children as $child_section) {
if ( !$this->sectionVisible($child_section, $check_permission) ) {
continue;
}
break;
}
return $this->getFirstChild($child_section, $check_permission);
}
return $section_name;
}
/**
* Checks if given section is visible by it's definition and optionally by user permission
*
* @param string $section_name
* @param bool $check_permission
* @return bool
*/
function sectionVisible($section_name, $check_permission = false)
{
$section_data =& $this->getSectionData($section_name);
if (isset($section_data['show_mode']) && is_numeric($section_data['show_mode'])) {
$show_mode = $section_data['show_mode'];
// if super admin section -> show in super admin mode & debug mode
$show_section = $show_mode == smNORMAL || ((($show_mode & smSUPER_ADMIN) == smSUPER_ADMIN) && ($this->superAdminMode || $this->debugMode));
if (!$show_section) {
// if section is in debug mode only && debug mode -> show
$show_section = (($show_mode & smDEBUG) == smDEBUG) && $this->debugMode;
}
if (!$show_section) {
// visibility by section definition
return false;
}
}
// visibility by section permission
if ($check_permission) {
$perm_section = $this->getPermSection($section_name);
return $this->Application->CheckPermission($perm_section.'.view');
}
return true;
}
/**
* Returns section for permission checking based on given section
*
* @param string $section_name
* @return string
*/
function getPermSection($section_name)
{
$ret = $section_name;
$section_data =& $this->getSectionData($section_name);
if ($section_data && isset($section_data['perm_prefix'])) {
// this section uses other section permissions
$ret = $this->Application->getUnitConfig($section_data['perm_prefix'])->getPermSectionByName('main');
}
return $ret;
}
}