Index: core/admin_templates/tools/system_tools.tpl =================================================================== --- core/admin_templates/tools/system_tools.tpl +++ core/admin_templates/tools/system_tools.tpl @@ -47,7 +47,7 @@
- : master:sections_parsed () + : master:sections_parsed, master:sections_by_unit ()
"/> @@ -210,6 +210,7 @@
  • master:configs_parsed
  • master:config_files
  • master:sections_parsed
  • +
  • master:sections_by_unit
  • master:cms_menu
  • master:template_mapping
  • master:StructureTree
  • Index: core/kernel/managers/cache_manager.php =================================================================== --- core/kernel/managers/cache_manager.php +++ core/kernel/managers/cache_manager.php @@ -414,6 +414,17 @@ else { $this->rebuildDBCache('sections_parsed', kCache::REBUILD_LATER, CacheSettings::$sectionsParsedRebuildTime); } + + if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { + $this->Application->rebuildCache( + 'master:sections_by_unit', + kCache::REBUILD_LATER, + CacheSettings::$sectionsParsedRebuildTime + ); + } + else { + $this->rebuildDBCache('sections_by_unit', kCache::REBUILD_LATER, CacheSettings::$sectionsParsedRebuildTime); + } } /** Index: core/kernel/utility/event.php =================================================================== --- core/kernel/utility/event.php +++ core/kernel/utility/event.php @@ -430,9 +430,10 @@ $sections_helper = $this->Application->recallObject('SectionsHelper'); $section_data =& $sections_helper->getSectionData($section); - if ($section_data && isset($section_data['perm_prefix']) && $section_data['perm_prefix'] != $top_prefix) { - $this->setEventParam('top_prefix', $section_data['perm_prefix']); - $section = $this->Application->getUnitOption($section_data['perm_prefix'].'.main', 'PermSection'); + + if ( $section_data && $section_data['SectionPrefix'] != $top_prefix) { + $this->setEventParam('top_prefix', $section_data['SectionPrefix']); + $section = $this->Application->getUnitOption($section_data['SectionPrefix'] . '.main', 'PermSection'); } if (!$section) { Index: core/units/admin/admin_events_handler.php =================================================================== --- core/units/admin/admin_events_handler.php +++ core/units/admin/admin_events_handler.php @@ -143,6 +143,8 @@ $event->status = kEvent::erSTOP; } + $this->Application->DeleteSectionCache(); + if ($this->Application->isCachingType(CACHING_TYPE_MEMORY)) { $this->Application->rebuildCache('master:sections_parsed', kCache::REBUILD_LATER, CacheSettings::$sectionsParsedRebuildTime); } Index: core/units/admin/admin_tag_processor.php =================================================================== --- core/units/admin/admin_tag_processor.php +++ core/units/admin/admin_tag_processor.php @@ -154,7 +154,7 @@ break; case 'perm_section': - $res = $sections_helper->getPermSection($section); + $res = $sections_helper->getPermSection($section, $params['prefix']); break; case 'label': @@ -259,7 +259,7 @@ foreach ($section_data['children'] as $priority => $section_name) { // if only tabs in this section & none of them have permission, then skip section too - $section_name = $sections_helper->getPermSection($section_name); + $section_name = $sections_helper->getPermSection($section_name, $section_data['SectionPrefix']); $perm_status = $this->Application->CheckPermission($section_name.'.view', 1); if ($perm_status) { break; @@ -276,7 +276,7 @@ $section_data['is_tab'] = 1; } else { - $section_name = $sections_helper->getPermSection($section_name); + $section_name = $sections_helper->getPermSection($section_name, $section_data['SectionPrefix']); if (!$this->Application->CheckPermission($section_name.'.view', 1)) continue; } @@ -359,7 +359,7 @@ $block_params = Array('name' => $params['render_as']); ksort($section_data['children'], SORT_NUMERIC); foreach ($section_data['children'] as $priority => $section_name) { - $perm_section = $sections_helper->getPermSection($section_name); + $perm_section = $sections_helper->getPermSection($section_name, $section_data['SectionPrefix']); if ( !$this->Application->CheckPermission($perm_section.'.view') ) { continue; Index: core/units/general/general_config.php =================================================================== --- core/units/general/general_config.php +++ core/units/general/general_config.php @@ -26,6 +26,7 @@ 4 => 'theme', 5 => 'opener', 6 => 'wid', + 7 => 'section', ), 'TitleField' => 'CachedNavbar', Index: core/units/helpers/sections_helper.php =================================================================== --- core/units/helpers/sections_helper.php +++ core/units/helpers/sections_helper.php @@ -41,6 +41,13 @@ */ var $superAdminMode = false; + /** + * Sections, grouped by unit + * + * @var array + */ + protected $sectionsByUnit = array(); + public function __construct() { parent::__construct(); @@ -71,16 +78,11 @@ */ 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); - } + $this->Tree = $this->getFromCache('sections_parsed'); + $this->sectionsByUnit = $this->getFromCache('sections_by_unit'); - if ( $data ) { - $this->Tree = unserialize($data); - return ; + if ( $this->Tree && $this->sectionsByUnit ) { + return; } if ( !defined('IS_INSTALL') || !IS_INSTALL ) { @@ -88,7 +90,8 @@ $this->Application->UnitConfigReader->ReReadConfigs(); } - $this->Tree = Array (); + $this->Tree = array(); + $this->sectionsByUnit = array(); // 1. build base tree (don't update parent with children list yet) @@ -142,6 +145,14 @@ // 3. foreach ($this->Tree as $section_name => $section_params) { + $section_prefix = $section_params['SectionPrefix']; + + if ( !isset($this->sectionsByUnit[$section_prefix]) ) { + $this->sectionsByUnit[$section_prefix] = array(); + } + + $this->sectionsByUnit[$section_prefix][] = $section_name; + // 3.1. update parent -> children references $parent_section = $section_params['parent']; $section_order = "{$section_params['priority']}"; @@ -202,11 +213,60 @@ $this->Application->HandleEvent(new kEvent('adm:OnAfterBuildTree')); + $this->setToCache('sections_parsed', $this->Tree); + $this->setToCache('sections_by_unit', $this->sectionsByUnit); + } + + /** + * Section names, related to prefix + * + * @param string $prefix Prefix. + * + * @return array + */ + public function getSectionNames($prefix) + { + return isset($this->sectionsByUnit[$prefix]) ? $this->sectionsByUnit[$prefix] : array(); + } + + /** + * Returns value from cache + * + * @param string $cache_key Cache key. + * + * @return array|boolean + */ + protected function getFromCache($cache_key) + { + if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { + $data = $this->Application->getCache( + 'master:' . $cache_key, + false, + CacheSettings::$sectionsParsedRebuildTime + ); + } + else { + $data = $this->Application->getDBCache($cache_key, CacheSettings::$sectionsParsedRebuildTime); + } + + return $data ? unserialize($data) : false; + } + + /** + * Sets value to cache + * + * @param string $cache_key Cache key. + * @param array $data Data. + * + * @return void + */ + protected function setToCache($cache_key, array $data) + { if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { - $this->Application->setCache('master:sections_parsed', serialize($this->Tree)); + $this->Application->setCache('master:' . $cache_key, serialize($data)); } else { - $this->Application->setDBCache('sections_parsed', serialize($this->Tree)); + $this->Application->setDBCache($cache_key, serialize($data)); } } @@ -240,16 +300,12 @@ $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'); + unset($section_params['url']['pass_section']); + $section_params['url']['section'] = $section_name; - 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['ModuleFolder'] . '/', 'Name'); - $section_params['url']['module'] = $module_name; - } + if ( !isset($section_params['url']['module']) ) { + $module_name = $this->Application->findModule('Path', $config['ModuleFolder'] . '/', 'Name'); + $section_params['url']['module'] = $module_name; } if ( !isset($section_params['url']['t']) ) { @@ -353,7 +409,7 @@ // visibility by section permission if ($check_permission) { - $perm_section = $this->getPermSection($section_name); + $perm_section = $this->getPermSection($section_name, $section_data['SectionPrefix']); return $this->Application->CheckPermission($perm_section.'.view'); } @@ -364,18 +420,36 @@ /** * Returns section for permission checking based on given section * - * @param string $section_name + * @param string $section_name Section name. + * @param string $prefix Prefix. + * * @return string */ - function getPermSection($section_name) + public function getPermSection($section_name, $prefix = '') { $ret = $section_name; + + if ( $prefix ) { + $request_section = $this->Application->GetVar('m_section'); + + if ( !$request_section ) { + $request_section = $section_name; + } + + if ( isset($this->sectionsByUnit[$prefix]) + && in_array($request_section, $this->sectionsByUnit[$prefix]) + ) { + return $request_section; + } + } + $section_data =& $this->getSectionData($section_name); - if ($section_data && isset($section_data['perm_prefix'])) { - // this section uses other section permissions - $ret = $this->Application->getUnitOption($section_data['perm_prefix'].'.main', 'PermSection'); + if ( $section_data ) { + $ret = $this->Application->getUnitOption($section_data['SectionPrefix'] . '.main', 'PermSection'); } + return $ret; } - } \ No newline at end of file + + } Index: core/units/permissions/permissions_event_handler.php =================================================================== --- core/units/permissions/permissions_event_handler.php +++ core/units/permissions/permissions_event_handler.php @@ -142,8 +142,6 @@ $sections_helper = $this->Application->recallObject('SectionsHelper'); foreach ($permissions as $section_name => $section_permissions) { - $section_name = $sections_helper->getPermSection($section_name); - foreach ($section_permissions as $perm_name => $perm_value) { if ( !$permissions_helper->isOldPermission($section_name, $perm_name) ) { $perm_name = $section_name . '.' . $perm_name; Index: core/units/permissions/permissions_tag_processor.php =================================================================== --- core/units/permissions/permissions_tag_processor.php +++ core/units/permissions/permissions_tag_processor.php @@ -52,11 +52,6 @@ $section_name = $params['section_name']; $perm_name = $params['perm_name']; - /** @var kSectionsHelper $sections_helper */ - $sections_helper = $this->Application->recallObject('SectionsHelper'); - - $section_name = $sections_helper->getPermSection($section_name); - /** @var kPermissionsHelper $permissions_helper */ $permissions_helper = $this->Application->recallObject('PermissionsHelper');