Index: branches/5.3.x/core/kernel/utility/unit_config_reader.php =================================================================== --- branches/5.3.x/core/kernel/utility/unit_config_reader.php (revision 16177) +++ branches/5.3.x/core/kernel/utility/unit_config_reader.php (revision 16178) @@ -1,730 +1,735 @@ directorySeparator = preg_quote(DIRECTORY_SEPARATOR); $editor_path = explode('/', trim(EDITOR_PATH, '/')); $this->skipFolders[] = array_pop($editor_path); // last of cmseditor folders $this->moduleFolderRegExp = '#' . $this->directorySeparator . '(core|modules' . $this->directorySeparator . '.*?)' . $this->directorySeparator . '#'; $this->cloner = $this->Application->makeClass('kUnitConfigCloner', array($this)); } /** * Sets data from cache to object * * @param Array $data */ public function setFromCache(&$data) { $this->cloner->setFromCache($data); $this->prefixFiles = $data['ConfigReader.prefixFiles']; } /** * Gets object data for caching * * @return Array */ public function getToCache() { return array_merge( $this->cloner->getToCache(), array( 'ConfigReader.prefixFiles' => $this->prefixFiles, ) ); } public function scanModules($folder_path, $cache = true) { if ( defined('IS_INSTALL') && IS_INSTALL && !defined('FORCE_CONFIG_CACHE') ) { // disable config caching during installation $cache = false; } if ( $cache ) { $restored = $this->Application->cacheManager->LoadUnitCache(); if ( $restored ) { if ( defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode() ) { $this->Application->Debugger->appendHTML('UnitConfigReader: Restoring Cache'); } return; } } if ( defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode() ) { $this->Application->Debugger->appendHTML('UnitConfigReader: Generating Cache'); } // === lines below would only executed on cold start (no unit config cache) === // no cache found -> include all unit configs to create it ! $this->includeConfigFiles($folder_path, $cache); $this->parseConfigs(); $this->sortRouters(); // tell AfterConfigRead to store cache if needed // can't store it here because AfterConfigRead needs ability to change config data $this->storeCache = $cache; if ( !$this->Application->InitDone ) { // scanModules is called multiple times during installation process $this->Application->InitManagers(); } $this->Application->cacheManager->applyDelayedUnitProcessing(); } /** * Locates (recursively) and reads all unit configs at given path. * * @param string $folder_path Folder path. * @param boolean $cache Store information to cache. * * @throws Exception When unit config file is missing a prefix defined inside it. */ protected function includeConfigFiles($folder_path, $cache = true) { $this->Application->refreshModuleInfo(); if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { $data = $this->Application->getCache('master:config_files', false, $cache ? CacheSettings::$unitCacheRebuildTime : 0); } else { $data = $this->Application->getDBCache('config_files', $cache ? CacheSettings::$unitCacheRebuildTime : 0); } if ( $data ) { $this->configFiles = unserialize($data); if ( !(defined('DBG_VALIDATE_CONFIGS') && DBG_VALIDATE_CONFIGS) ) { shuffle($this->configFiles); } } else { $this->findConfigFiles(FULL_PATH . DIRECTORY_SEPARATOR . 'core'); // search from "core" directory $this->findConfigFiles($folder_path); // search from "modules" directory if ( $cache ) { if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { $this->Application->setCache('master:config_files', serialize($this->configFiles)); } else { $this->Application->setDBCache('config_files', serialize($this->configFiles)); } } } foreach ( $this->configFiles as $filename ) { $prefix = $this->PreloadConfigFile($filename); if ( !$prefix ) { throw new Exception('Prefix not defined in config file ' . $filename . ''); } } // TODO: needed? if ( $cache ) { unset($this->configFiles); } } /** * Recursively searches for unit configs in given folder. * * @param string $folder_path Path to the folder. * @param int $level Deep level of the folder. * * @return void */ protected function findConfigFiles($folder_path, $level = 0) { // if FULL_PATH = "/" ensure, that all "/" in $folderPath are not deleted $reg_exp = '/^' . preg_quote(FULL_PATH, '/') . '/'; $folder_path = preg_replace($reg_exp, '', $folder_path, 1); // this make sense, since $folderPath may NOT contain FULL_PATH $base_folder = FULL_PATH . $folder_path . DIRECTORY_SEPARATOR; $sub_folders = glob($base_folder . '*', GLOB_ONLYDIR); if ( !$sub_folders ) { return; } if ( $level == 0 ) { // don't scan Front-End themes because of extensive directory structure $sub_folders = array_diff($sub_folders, array($base_folder . 'themes', $base_folder . 'tools')); } foreach ( $sub_folders as $full_path ) { $sub_folder = substr($full_path, strlen($base_folder)); if ( in_array($sub_folder, $this->skipFolders) || preg_match('/^\./', $sub_folder) ) { // don't scan skipped or hidden folders continue; } $config_name = $this->getConfigName($folder_path . DIRECTORY_SEPARATOR . $sub_folder); if ( file_exists(FULL_PATH . $config_name) ) { $this->configFiles[] = $config_name; } $this->findConfigFiles($full_path, $level + 1); } } /** * Process all read config files - called ONLY when there is no cache! * * @return void */ protected function parseConfigs() { $this->parseUnitConfigs($this->getUnitConfigsWithoutPriority()); $this->parseUnitConfigs($this->getUnitConfigsWithPriority()); } /** * Parses unit config sub-set. * * @param array $prefixes Unit config prefixes. * * @return array */ protected function parseUnitConfigs(array $prefixes) { foreach ( $prefixes as $prefix ) { $this->configData[$prefix]->parse(); } $this->cloner->extrudeAndParse($prefixes); } /** * Returns unit configs prefixes without priority defined. * * @return array */ - protected function getUnitConfigsWithoutPriority() + public function getUnitConfigsWithoutPriority() { $ret = array(); foreach ( $this->configData as $prefix => $config ) { if ( $config->getConfigPriority() === false ) { $ret[] = $prefix; } } return $ret; } /** * Returns unit configs prefixes with priority defined. * * @return array */ - protected function getUnitConfigsWithPriority() + public function getUnitConfigsWithPriority() { $ret = array(); foreach ( $this->configData as $prefix => $config ) { $priority = $config->getConfigPriority(); if ( $priority !== false ) { $ret[$prefix] = $priority; } } asort($ret); return array_keys($ret); } public function AfterConfigRead($store_cache = null) { $this->finalStage = true; foreach ($this->configData as $prefix => $config) { $this->runAfterConfigRead($prefix); } if ( !isset($store_cache) ) { // $store_cache not overridden -> use global setting $store_cache = $this->storeCache; } if ( $store_cache || (defined('IS_INSTALL') && IS_INSTALL) ) { // cache is not stored during install, but dynamic clones should be processed in any case $this->cloner->processDynamicallyAdded(); $this->retrieveCollections(); } if ( $store_cache ) { $this->Application->HandleEvent(new kEvent('adm:OnAfterCacheRebuild')); $this->Application->cacheManager->UpdateUnitCache(); if ( defined('DEBUG_MODE') && DEBUG_MODE && defined('DBG_VALIDATE_CONFIGS') && DBG_VALIDATE_CONFIGS ) { // validate configs here to have changes from OnAfterConfigRead hooks to prefixes foreach ( $this->configData as $config ) { if ( !$config->getTableName() ) { continue; } $config->validate(); } } } } /** * Sort routers according to their weight (non-prioritized routers goes first). * * @return void */ protected function sortRouters() { $sorted_routers = array(); $prioritized_routers = array(); $routers = $this->collectRouters(); // Process non-prioritized routers. foreach ( $routers as $prefix => $router_data ) { if ( $router_data['priority'] === false ) { $sorted_routers[$prefix] = $router_data; } else { $prioritized_routers[$prefix] = $router_data['priority']; } } // Process prioritized routers. asort($prioritized_routers, SORT_NUMERIC); foreach ( $prioritized_routers as $prefix => $priority ) { $sorted_routers[$prefix] = $routers[$prefix]; } $this->Application->routers = $sorted_routers; } /** * Collects routers. * * @return array */ protected function collectRouters() { $routers = array(); $router_classes = $this->Application->getSubClasses('AbstractRouter'); foreach ( $router_classes as $router_class ) { if ( !class_exists($router_class) ) { // This can happen, when: // - router class (coming from cache) was renamed; // - new cache is built based on outdated class map. continue; } /** @var AbstractRouter $router */ $router = new $router_class(); $routers[$router->getPrefix()] = array( 'class' => $router_class, 'priority' => $router->getWeight(), ); } return $routers; } /** * Re-reads all configs. * * @return void */ public function ReReadConfigs() { + if ( $this->storeCache && $this->finalStage ) { + // Building cache right now, so all unit configs are read anyway. + return; + } + // don't reset prefix file, since file scanning could slow down the process $prefix_files_backup = $this->prefixFiles; $this->Application->cacheManager->EmptyUnitCache(); $this->prefixFiles = $prefix_files_backup; // parse all configs $this->afterConfigProcessed = array(); $this->includeConfigFiles(MODULES_PATH, false); $this->parseConfigs(); $this->sortRouters(); $this->AfterConfigRead(false); $this->cloner->processDynamicallyAdded(); $this->retrieveCollections(); } /** * Process all collectible unit config options here to also catch ones, defined from OnAfterConfigRead events * */ protected function retrieveCollections() { foreach ( $this->configData as $prefix => $config ) { // collect replacement templates if ( $config->getReplacementTemplates() ) { $this->Application->ReplacementTemplates = array_merge($this->Application->ReplacementTemplates, $config->getReplacementTemplates()); } } } public function loadConfig($prefix) { $preloaded_prefix = $this->PreloadConfigFile($this->getPrefixFile($prefix)); if ( $this->finalStage ) { // run prefix OnAfterConfigRead so all hooks to it can define their clones $this->runAfterConfigRead($preloaded_prefix); } // Only use cached clones for calls in the middle of initialization (e.g. url parsing). $clones = $this->cloner->extrude($preloaded_prefix, !$this->finalStage); if ( $this->finalStage ) { foreach ( $clones as $a_prefix ) { $this->runAfterConfigRead($a_prefix); } } } /** * Runs OnAfterConfigRead event for given prefix once. * * @param string $prefix Unit config prefix. * * @return void */ public function runAfterConfigRead($prefix) { if ( in_array($prefix, $this->afterConfigProcessed) ) { return; } $this->Application->HandleEvent(new kEvent($prefix . ':OnAfterConfigRead')); if ( !(defined('IS_INSTALL') && IS_INSTALL) ) { // allow to call OnAfterConfigRead multiple times during install array_push($this->afterConfigProcessed, $prefix); } } /** * Loads unit config file contents from disk. * * @param string $filename Unit config filename. * * @return string */ protected function PreloadConfigFile($filename) { $config_found = file_exists(FULL_PATH . $filename) && $this->configAllowed($filename); if ( defined('DEBUG_MODE') && DEBUG_MODE && defined('DBG_PROFILE_INCLUDES') && DBG_PROFILE_INCLUDES ) { if ( in_array($filename, get_included_files()) ) { return ''; } global $debugger; if ( $config_found ) { $file = FULL_PATH . $filename; $file_crc = crc32($file); $debugger->ProfileStart('inc_' . $file_crc, $file); include_once($file); $debugger->ProfileFinish('inc_' . $file_crc); $debugger->profilerAddTotal('includes', 'inc_' . $file_crc); } } elseif ( $config_found ) { include_once(FULL_PATH . $filename); } if ( $config_found ) { /* @var $config kUnitConfig|Array */ if ( isset($config) && $config ) { // config file is included for 1st time -> save it's content for future processing if ( !is_object($config) ) { $prefix = array_key_exists('Prefix', $config) ? $config['Prefix'] : ''; $config = new kUnitConfig($prefix, $config); } else { $prefix = $config->getPrefix(); } preg_match($this->moduleFolderRegExp, $filename, $regs); $config->setModuleFolder(str_replace(DIRECTORY_SEPARATOR, '/', $regs[1])); $config->setBasePath(dirname(FULL_PATH . $filename)); if ( $config->getAdminTemplatePath() !== false ) { // append template base folder for admin templates path of this prefix $module_templates = $regs[1] == 'core' ? '' : substr($regs[1], 8) . '/'; $config->setAdminTemplatePath($module_templates . $config->getAdminTemplatePath()); } if ( array_key_exists($prefix, $this->prefixFiles) && ($this->prefixFiles[$prefix] != $filename) ) { trigger_error( 'Single unit config prefix "' . $prefix . '" ' . 'is used in multiple unit config files: ' . '"' . $this->prefixFiles[$prefix] . '", "' . $filename . '"', E_USER_WARNING ); } $this->add($config, $filename); return $prefix; } else { $prefix = array_search($filename, $this->prefixFiles); if ( $prefix ) { // attempt is made to include config file twice or more, but include_once prevents that, // but file exists on hdd, then it is already saved to all required arrays, just return it's prefix return $prefix; } } } return 'dummy'; } /** * Sets a file, for a given prefix. * * @param kUnitConfig $config Unit config. * @param string $filename File. * * @return void */ public function add(kUnitConfig $config, $filename) { $config->setFilename($filename); $prefix = $config->getPrefix(); $this->configData[$prefix] = $config; $this->prefixFiles[$prefix] = $filename; } /** * Removes unit config. * * @param string $prefix Unit config prefix. * * @return void */ public function remove($prefix) { unset($this->configData[$prefix], $this->prefixFiles[$prefix]); } /** * Returns unit config for given prefix * * @param string $prefix * @return kUnitConfig */ public function getUnitConfig($prefix = null) { if ( !isset($this->configData[$prefix]) ) { $this->loadConfig($prefix); } return $this->configData[$prefix]; } /** * Returns prefixes of unit configs, that were registered * * @return Array */ public function getPrefixes() { return array_keys($this->configData); } /** * Get's config file name based * on folder name supplied * * @param string $folder_path * @return string */ protected function getConfigName($folder_path) { return $folder_path . DIRECTORY_SEPARATOR . basename($folder_path) . '_config.php'; } /** * Checks if config file is allowed for inclusion (if module of config is installed). * * @param string $config_path Relative path from In-Portal directory. * * @return boolean */ protected function configAllowed($config_path) { static $module_paths = null; if ( defined('IS_INSTALL') && IS_INSTALL ) { // at installation start no modules in db and kernel configs could not be read return true; } if ( preg_match('#^' . $this->directorySeparator . 'core#', $config_path) ) { // always allow to include configs from "core" module's folder return true; } if ( !$this->Application->ModuleInfo ) { return false; } if ( !isset($module_paths) ) { $module_paths = array(); foreach ( $this->Application->ModuleInfo as $module_info ) { $module_paths[] = str_replace('/', DIRECTORY_SEPARATOR, rtrim($module_info['Path'], '/')); } $module_paths = array_unique($module_paths); } preg_match($this->moduleFolderRegExp, $config_path, $regs); // config file path starts with module folder path return in_array($regs[1], $module_paths); } /** * Returns true if config exists and is allowed for reading * * @param string $prefix Unit config prefix. * * @return boolean */ public function prefixRegistered($prefix) { return isset($this->prefixFiles[$prefix]); } /** * Returns unit config file location by it's prefix. * * @param string $prefix Unit config prefix. * * @return string * @throws Exception When unit config is not found. */ public function getPrefixFile($prefix) { if ( !isset($this->prefixFiles[$prefix]) ) { throw new Exception('Configuration file for prefix "' . $prefix . '" is unknown'); } return $this->prefixFiles[$prefix]; } } Index: branches/5.3.x/core/units/helpers/sections_helper.php =================================================================== --- branches/5.3.x/core/units/helpers/sections_helper.php (revision 16177) +++ branches/5.3.x/core/units/helpers/sections_helper.php (revision 16178) @@ -1,379 +1,365 @@ 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) - - // 1.1. process prefixes without priority - $prioritized_prefixes = Array (); - $prefixes = $this->Application->UnitConfigReader->getPrefixes(); - - foreach ($prefixes as $prefix) { - $config = $this->Application->getUnitConfig($prefix); - - if ( $config->getConfigPriority() !== false ) { - $prioritized_prefixes[$prefix] = $config->getConfigPriority(); - continue; - } - + foreach ( $this->Application->UnitConfigReader->getUnitConfigsWithoutPriority() as $prefix ) { $this->_processPrefixSections($prefix); } - // 2. process prefixes with priority - asort($prioritized_prefixes); - foreach ($prioritized_prefixes as $prefix => $priority) { + foreach ( $this->Application->UnitConfigReader->getUnitConfigsWithPriority() as $prefix ) { $this->_processPrefixSections($prefix); } // 2. apply section adjustments - foreach ($prefixes as $prefix) { + 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); $children = isset($section_data['children']) && $section_data['children'] ? $section_data['children'] : false; /* @var $children Array */ 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; } - } \ No newline at end of file + }