Index: kernel/application.php =================================================================== --- kernel/application.php (revision 12650) +++ kernel/application.php (working copy) @@ -178,6 +178,13 @@ */ var $TemplatesCache = null; + /** + * Physical template name mapping to their template names based on structure + * + * @var Array + */ + var $structureTemplateMapping = Array (); + var $CompilationCache = array(); //used when compiling templates var $CachedProcessors = array(); //used when running compiled templates @@ -1310,11 +1317,29 @@ */ function HREF($t, $prefix='', $params=null, $index_file=null) { - if(!$t) $t = $this->GetVar('t'); // moved from kMainTagProcessor->T() + static $theme_id = null; + if (!$t) { + $t = $this->GetVar('t'); // moved from kMainTagProcessor->T() + } + $t = preg_replace('/^Content\//i', '', $t); + if (!isset($theme_id)) { + $theme_id = $this->GetVar('m_theme'); + } + if (substr($t, 0, 3) == 'id:') { + // link to structure page using it's id + $params['m_cat_id'] = substr($t, 3); + $t = $this->structureTemplateMapping[$t]; + } + + if (array_key_exists($t . ':' . $theme_id, $this->structureTemplateMapping)) { + // structure template corresponding to given physical template + $t = $this->structureTemplateMapping[$t . ':' . $theme_id]; + } + /*if ($this->GetVar('skip_last_template')) { $params['opener'] = 'p'; $this->SetVar('m_opener', 'p'); @@ -2008,6 +2033,17 @@ } $this->Caches['ConfigVariables'] = $config_ids; $this->ConfigCacheIds = $config_ids; + + // get template mapping + $sql = 'SELECT Data + FROM ' . TABLE_PREFIX . 'Cache + WHERE VarName = "template_mapping"'; + $template_mapping = $this->Conn->GetOne($sql); + + if (!$this->Application->IsAdmin() && $template_mapping) { + // template mappings only for Front-End + $this->structureTemplateMapping = unserialize($template_mapping); + } } function UpdateCache() Index: units/categories/categories_event_handler.php =================================================================== --- units/categories/categories_event_handler.php (revision 12650) +++ units/categories/categories_event_handler.php (working copy) @@ -469,6 +469,7 @@ $type_clauses['menu']['include'] = '%1$s.IsMenu = 1'; $type_clauses['menu']['except'] = '%1$s.IsMenu = 0'; + $type_clauses['menu']['having_filter'] = false; $search_helper =& $this->Application->recallObject('SearchHelper'); /* @var $search_helper kSearchHelper */ @@ -563,7 +564,7 @@ $updater->OneStepRun(); } - $event->CallSubEvent('OnResetMenuCache'); + $this->_resetMenuCache(); $this->Application->RemoveVar('PermCache_UpdateRequired'); @@ -760,7 +761,7 @@ } $this->Application->StoreVar('RefreshStructureTree', 1); - $event->CallSubEvent('OnResetMenuCache'); + $this->_resetMenuCache(); if ($is_editing) { // 2. send email event to category owner, when it's status is changed (from admin) @@ -978,7 +979,7 @@ $priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id); $this->Application->StoreVar('RefreshStructureTree', 1); - $event->CallSubEvent('OnResetMenuCache'); + $this->_resetMenuCache(); } /** @@ -1121,7 +1122,7 @@ $event->redirect = 'categories/cache_updater'; } - $event->CallSubEvent('OnResetMenuCache'); + $this->_resetMenuCache(); $this->Application->StoreVar('RefreshStructureTree', 1); } } @@ -1722,9 +1723,62 @@ */ function OnResetMenuCache(&$event) { - $this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName IN ("cms_menu", "StructureTree")'); + $this->_resetMenuCache(); } + function _resetMenuCache() + { + // reset cms menu cache + $sql = 'DELETE FROM ' . TABLE_PREFIX . 'Cache + WHERE VarName IN ("cms_menu", "StructureTree")'; + $this->Conn->Query($sql); + + // build structure template mapping + $sql = 'SELECT + IF(c.IsSystem, CONCAT(c.Template, ":", c.ThemeId), CONCAT("id:", c.CategoryId)) AS SrcTemplate, + LOWER( + IF( + c.SymLinkCategoryId IS NOT NULL, + (SELECT cc.NamedParentPath FROM ' . TABLE_PREFIX . 'Category AS cc WHERE cc.CategoryId = c.SymLinkCategoryId), + c.NamedParentPath + ) + ) AS DstTemplate, + c.UseExternalUrl, c.ExternalUrl + FROM ' . TABLE_PREFIX . 'Category AS c + WHERE c.Status = ' . STATUS_ACTIVE; + $pages = $this->Conn->Query($sql, 'SrcTemplate'); + + $mapping = Array (); + $base_url = $this->Application->BaseURL(); + + foreach ($pages as $src_template => $page) { + // process external url, before placing in cache + if ($page['UseExternalUrl']) { + $external_url = $page['ExternalUrl']; + + if (!preg_match('/^(.*?):\/\/(.*)$/', $external_url)) { + // url without protocol will be relative url to our site + $external_url = $base_url . $external_url; + } + + $dst_template = 'external:' . $external_url; + } + else { + $dst_template = preg_replace('/^Content\//i', '', $page['DstTemplate']); + } + + $mapping[$src_template] = $dst_template; + } + + $fields_hash = Array ( + 'VarName' => 'template_mapping', + 'Data' => serialize($mapping), + 'Cached' => adodb_mktime(), + ); + + $this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'Cache', 'REPLACE'); + } + /** * Updates structure config * @@ -1909,7 +1963,7 @@ $updater->OneStepRun(); } - $event->CallSubEvent('OnResetMenuCache'); + $this->_resetMenuCache(); if ($error_count) { // allow user to review error after structure page creation @@ -1958,7 +2012,7 @@ $this->clearSelectedIDs($event); $this->Application->StoreVar('RefreshStructureTree', 1); - $event->CallSubEvent('OnResetMenuCache'); + $this->_resetMenuCache(); } /** @@ -1973,7 +2027,7 @@ $parent_id = $this->Application->GetVar('m_cat_id'); $priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id); - $event->CallSubEvent('OnResetMenuCache'); + $this->_resetMenuCache(); } /** Index: units/helpers/category_helper.php =================================================================== --- units/helpers/category_helper.php (revision 12650) +++ units/helpers/category_helper.php (working copy) @@ -62,9 +62,16 @@ $block_params['no_editing'] = 1; $block_params['category'] = 0; $block_params['separator'] = $params['separator']; - $current_template = $this->Application->GetVar('t'); $show_category = getArrayValue($params, 'show_category'); + $current_template = $this->Application->GetVar('t'); + $physical_template = array_search($current_template, $this->Application->structureTemplateMapping); + + if ($physical_template !== false) { + // replace menu template name with it's actual template name on disk + list ($current_template) = explode(':', $physical_template, 2); + } + foreach ($navigation_parts as $template => $title) { $block_params['template'] = $template;