Index: branches/5.0.x/core/units/categories/categories_tag_processor.php =================================================================== diff -u -r12872 -r12877 --- branches/5.0.x/core/units/categories/categories_tag_processor.php (.../categories_tag_processor.php) (revision 12872) +++ branches/5.0.x/core/units/categories/categories_tag_processor.php (.../categories_tag_processor.php) (revision 12877) @@ -1,6 +1,6 @@ getObject($params); @@ -227,42 +213,40 @@ return $ml_formatter->LangFieldName('Name'); } + /** + * Returns symlinked category for given category + * + * @param $category_id + */ function getCategorySymLink($category_id) { static $cache = null; + if (!$category_id) { + // don't bother to get symlink for "Home" category + return $category_id; + } + if (!isset($cache)) { $id_field = $this->Application->getUnitOption($this->Prefix, 'IDField'); $table_name = $this->Application->getUnitOption($this->Prefix, 'TableName'); - $sql = 'SELECT SymLinkCategoryId, '.$id_field.' - FROM '.$table_name.' - WHERE SymLinkCategoryId IS NOT NULL'; + // get symlinked categories, that are not yet deleted + $sql = 'SELECT c1.SymLinkCategoryId, c1.' . $id_field . ' + FROM ' . $table_name . ' c1 + JOIN ' . $table_name . ' c2 ON c1.SymLinkCategoryId = c2.' . $id_field; $cache = $this->Conn->GetCol($sql, $id_field); } - if (isset($cache[$category_id])) { - - //check if sym. link category is valid - $id_field = $this->Application->getUnitOption($this->Prefix, 'IDField'); - $table_name = $this->Application->getUnitOption($this->Prefix, 'TableName'); - - $sql = 'SELECT '.$id_field.' - FROM '.$table_name.' - WHERE '.$id_field.' = '.$cache[$category_id]; - - $category_id = $this->Conn->GetOne($sql)? $cache[$category_id] : $category_id; - } - - return $category_id; + return array_key_exists($category_id, $cache) ? $cache[$category_id] : $category_id; } function CategoryLink($params) { $category_id = getArrayValue($params, 'cat_id'); if ($category_id === false) { - $category_id = $this->Application->GetVar($this->getPrefixSpecial().'_id'); + $category_id = $this->Application->GetVar($this->getPrefixSpecial() . '_id'); } if ("$category_id" == 'Root') { @@ -272,7 +256,7 @@ $category_id = $this->Application->GetVar('m_cat_id'); } - $category_id = $this->getCategorySymLink($category_id); + $category_id = $this->getCategorySymLink( (int)$category_id ); unset($params['cat_id'], $params['module']); @@ -1546,197 +1530,20 @@ } /** - * Builds cached menu version - * - * @return Array - */ - function _prepareMenu() - { - static $root_cat = null; - static $root_path = null; - - if (!$root_cat) { - $root_cat = $this->Application->ModuleInfo['Core']['RootCat']; - $root_path = $this->Conn->GetOne('SELECT ParentPath FROM '.TABLE_PREFIX.'Category WHERE CategoryId = '.$root_cat); - } - - if (!$this->Menu) { - $menu = $this->Conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "cms_menu"'); - if ($menu && $menu['Cached'] > 0) { - $menu = unserialize($menu['Data']); - $this->ParentPaths = $menu['ParentPaths']; - } - else { - $menu = $this->_altBuildMenuStructure(array('CategoryId' => $root_cat, 'ParentPath' => $root_path)); - $menu['ParentPaths'] = $this->ParentPaths; - $this->Conn->Query('REPLACE '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("cms_menu", '.$this->Conn->qstr(serialize($menu)).', '.adodb_mktime().')'); - } - unset($menu['ParentPaths']); - $this->Menu = $menu; - } - - return Array ($this->Menu, $root_path); - } - - /** - * Returns category id based tag parameters - * - * @param Array $params - * @return int - */ - function _getCategoryId($params) - { - $cat = isset($params['category_id']) && $params['category_id'] != '' ? $params['category_id'] : $this->Application->GetVar('m_cat_id'); - if ("$cat" == 'parent') { - $this_category =& $this->Application->recallObject('c'); - /* @var $this_category kDBItem */ - - $cat = $this_category->GetDBField('ParentId'); - } - else if ($cat == 0) { - $cat = $this->Application->ModuleInfo['Core']['RootCat']; - } - - return $cat; - } - - /** - * Prepares cms menu item block parameters - * - * @param Array $page - * @param int $real_cat_id - * @param string $root_path - * @return Array - */ - function _prepareMenuItem($page, $real_cat_id, $root_path) - { - static $language_id = null; - static $primary_language_id = null; - - if (!isset($language_id)) { - $language_id = $this->Application->GetVar('m_lang'); - $primary_language_id = $this->Application->GetDefaultLanguageId(); - } - - $title = $page['l'.$language_id.'_ItemName'] ? $page['l'.$language_id.'_ItemName'] : $page['l'.$primary_language_id.'_ItemName']; - $active = false; - $category_active = false; - - if ($page['ItemType'] == 'cat') { - if ( isset($this->ParentPaths[$real_cat_id])) { - $active = strpos($this->ParentPaths[$real_cat_id], $page['ParentPath']) !== false; - } - $category_active = $page['CategoryId'] == $real_cat_id; - } - - if ($page['ItemType'] == 'cat_index') { - $check_path = str_replace($root_path, '', $page['ParentPath']); - $active = strpos($parent_path, $check_path) !== false; - } - - if ($page['ItemType'] == 'page') { - $active = $page['ItemPath'] == preg_replace('/^Content\//i', '', $this->Application->GetVar('t')); - } - - $block_params = Array ( - 'title'=> $title, - 'template'=> preg_replace('/^Content\//i', '', $page['ItemPath']), - 'active'=>$active, - 'category_active' => $category_active, // new - 'parent_path'=>$page['ParentPath'], - 'parent_id'=>$page['ParentId'], - 'cat_id'=>$page['CategoryId'], - 'is_index'=>$page['IsIndex'], - 'item_type'=>$page['ItemType'], - 'page_id'=>$page['ItemId'], - 'has_sub_menu' => isset($page['sub_items']) && count($page['sub_items']) > 0, - 'external_url' => $page['UseExternalUrl'] ? $page['ExternalUrl'] : false, - 'menu_icon' => $page['UseMenuIconUrl'] ? $page['MenuIconUrl'] : false, - - ); - - return $block_params; - } - - /** * Builds site menu * * @param Array $params * @return string */ function CachedMenu($params) { - list ($menu, $root_path) = $this->_prepareMenu(); - $cat = $this->_getCategoryId($params); + $menu_helper =& $this->Application->recallObject('MenuHelper'); + /* @var $menu_helper MenuHelper */ - $parent_path = isset($this->ParentPaths[$cat]) ? $this->ParentPaths[$cat] : ''; - $parent_path = str_replace($root_path, '', $parent_path); //menu starts from module path - $levels = explode('|',trim($parent_path,'|')); - if ($levels[0] === '') $levels = array(); - if (isset($params['level']) && $params['level'] > count($levels)) return ; - - $level = max(isset($params['level']) ? $params['level']-1 : count($levels)-1, 0); - $parent = isset($levels[$level]) ? $levels[$level] : 0; - - $cur_menu =& $menu; - $menu_path = array_slice($levels, 0, $level+1); - foreach ($menu_path as $elem) { - $cur_menu =& $cur_menu['c'.$elem]['sub_items']; - } - - $ret = ''; - $block_params = $this->prepareTagParams($params); - $block_params['name'] = $params['render_as']; - - $this->Application->SetVar('cur_parent_path', $parent_path); - $real_cat_id = $this->Application->GetVar('m_cat_id'); - if (is_array($cur_menu) && $cur_menu) { - $cur_item = 1; - $cur_menu = $this->_removeNonMenuItems($cur_menu); - $block_params['total_items'] = count($cur_menu); - - foreach ($cur_menu as $page) { - $block_params = array_merge_recursive2( - $block_params, - $this->_prepareMenuItem($page, $real_cat_id, $root_path) - ); - - $block_params['is_last'] = $cur_item == $block_params['total_items']; - $block_params['is_first'] = $cur_item == 1; - - // bug #1: this breaks active section highlighting when 2 menu levels are printed on same page (both visible) - // bug #2: people doesn't pass cat_id parameter to m_Link tags in their blocks, so this line helps them; when removed their links will lead to nowhere - $this->Application->SetVar('m_cat_id', $page['CategoryId']); - - $ret .= $this->Application->ParseBlock($block_params, 1); - $cur_item++; - } - - $this->Application->SetVar('m_cat_id', $real_cat_id); - } - - return $ret; + return $menu_helper->menuTag($this->getPrefixSpecial(), $params); } /** - * Returns only items, that are visible in menu - * - * @param Array $menu - * @return Array - */ - function _removeNonMenuItems($menu) - { - foreach ($menu as $menu_index => $menu_item) { - // $menu_index is in "cN" format, where N is category id - if (!$menu_item['IsMenu']) { - unset($menu[$menu_index]); - } - } - - return $menu; - } - - /** * Trick to allow some kind of output formatting when using CachedMenu tag * * @param Array $params @@ -1834,97 +1641,6 @@ } /** - * Builds cache for children of given category (no matter, what menu status is) - * - * @param Array $parent - * @return Array - */ - function _altBuildMenuStructure($parent) - { - static $languages_count = null; - - if (!isset($languages_count)) { - $sql = 'SELECT COUNT(*) - FROM ' . TABLE_PREFIX . 'Language'; - $languages_count = ceil($this->Conn->GetOne($sql) / 5) * 5; - } - - $items = Array (); - - $lang_part = ''; - for ($i = 1; $i <= $languages_count; $i++) { -// $lang_part .= 'c.l' . $i . '_Name AS l' . $i . '_ItemName,' . "\n"; - $lang_part .= 'c.l' . $i . '_MenuTitle AS l' . $i . '_ItemName,' . "\n"; - } - - // Sub-categories from current category - $query = 'SELECT - c.CategoryId AS CategoryId, - CONCAT(\'c\', c.CategoryId) AS ItemId, - c.Priority AS ItemPriority, - ' . $lang_part . ' - LOWER( IF(IsIndex = 2, ( - SELECT cc.NamedParentPath FROM ' . TABLE_PREFIX . 'Category AS cc - WHERE - cc.ParentId = c.CategoryId - AND - cc.Status IN (1,4) - AND - cc.IsIndex = 1 - ), - c.NamedParentPath) ) AS ItemPath, - 0 AS IsIndex, - c.ParentPath AS ParentPath, - c.ParentId As ParentId, - \'cat\' AS ItemType, - c.IsMenu, c.UseExternalUrl, c.ExternalUrl, c.UseMenuIconUrl, c.MenuIconUrl - FROM ' . TABLE_PREFIX . 'Category AS c - WHERE - c.Status IN (1,4) AND - #c.IsMenu = 1 AND - c.ParentId = ' . $parent['CategoryId']; - $items = array_merge($items, $this->Conn->Query($query, 'ItemId')); - - uasort($items, Array (&$this, '_menuSort')); - - $the_items = array(); - foreach ($items as $an_item) { - $the_items[ $an_item['ItemId'] ] = $an_item; - $this->ParentPaths[ $an_item['CategoryId'] ] = $an_item['ParentPath']; - } - - $items = $the_items; - foreach ($items as $key => $menu_item) { - if ($menu_item['CategoryId'] == $parent['CategoryId']) { - continue; - } - - $sub_items = $this->_altBuildMenuStructure($menu_item); - if ($sub_items) { - $items[$key]['sub_items'] = $sub_items; - } - } - - return $items; - } - - /** - * Method for sorting pages by priority in decending order - * - * @param Array $a - * @param Array $b - * @return int - */ - function _menuSort($a, $b) - { - if ($a['ItemPriority'] == $b['ItemPriority']) { - return 0; - } - - return ($a['ItemPriority'] < $b['ItemPriority']) ? 1 : -1; //descending - } - - /** * Prepares cms page description for search result page * * @param Array $params