Application->findModule('Name', $params['module']); } // Get module by category path. if ( $category_path ) { foreach ( array_reverse($category_path) as $module_category_id ) { $module_info = $this->Application->findModule('RootCat', $module_category_id); if ( $module_info && $module_info['Var'] != 'adm' ) { return $module_info; } } } return false; } /** * Converts multi-dimensional category structure in one-dimensional option array (category_id=>category_name) * * @param Array $data * @param int $parent_category_id * @param int $language_id * @param int $theme_id * @param int $level * @return Array * @access protected */ protected function _printChildren(&$data, $parent_category_id, $language_id, $theme_id, $level = 0) { if ( $data['ThemeId'] != $theme_id && $data['ThemeId'] != 0 ) { // don't show system templates from different themes return Array (); } $category_language = $data['l' . $language_id . '_Name'] ? $language_id : $this->_primaryLanguageId; $ret = Array ($parent_category_id => str_repeat('—', $level) . ' ' . $data['l' . $category_language . '_Name']); if ( $data['children'] ) { $level++; foreach ($data['children'] as $category_id => $category_data) { // numeric keys $ret = kUtil::array_merge_recursive($ret, $this->_printChildren($data['children'][$category_id], $category_id, $language_id, $theme_id, $level)); } } return $ret; } /** * Returns information about children under parent path (recursive) * * @param int $parent_category_id * @param Array $languages * @return Array * @access protected */ protected function _getChildren($parent_category_id, $languages) { static $items_by_parent = null, $parent_mapping = null; if ( !isset($items_by_parent) ) { $fields = $items_by_parent = Array (); foreach ($languages as $language_id) { $fields[] = 'l' . $language_id . '_Name'; } $sql = 'SELECT CategoryId AS id, ' . implode(', ', $fields) . ', ParentId, Template, ThemeId FROM ' . TABLE_PREFIX . 'Categories ORDER BY Priority DESC'; $items = $this->Conn->Query($sql, 'id'); foreach ($items as $item_id => $item_data) { $item_parent_id = $item_data['ParentId']; unset($item_data['ParentId']); if ( !array_key_exists($item_parent_id, $items_by_parent) ) { $items_by_parent[$item_parent_id] = Array (); } $item_data['children'] = false; $parent_mapping[$item_id] = $item_parent_id; $items_by_parent[$item_parent_id][$item_id] = $item_data; } $base_category = $this->Application->getBaseCategory(); // "Content" category if ( isset($items_by_parent[$base_category]) ) { $index_category = $this->findIndexCategoryId($items_by_parent[$base_category]); // rename "Content" into "Home" keeping it's ID $items_by_parent[$parent_mapping[$base_category]][$base_category]['l1_Name'] = $this->Application->Phrase('la_rootcategory_name'); if ( $index_category !== false ) { // remove category of "index.tpl" template unset($items_by_parent[$base_category][$index_category]); unset($parent_mapping[$index_category]); } } } $data = $items_by_parent[$parent_mapping[$parent_category_id]][$parent_category_id]; $categories = array_key_exists($parent_category_id, $items_by_parent) ? $items_by_parent[$parent_category_id] : Array (); foreach ($categories as $category_id => $category_data) { if ( $category_id == $parent_category_id ) { // don't process myself - prevents recursion continue; } $data['children'][$category_id] = $this->_getChildren($category_id, $languages); } return $data; } /** * Finds "Home" category among given top level categories * * @param Array $top_categories * @return bool|int * @access protected */ protected function findIndexCategoryId($top_categories) { foreach ($top_categories as $category_id => $category_info) { if ($category_info['Template'] == 'index') { return $category_id; } } return false; } /** * Generates OR retrieves from cache structure tree * * @return Array * @access protected */ protected function &_getStructureTree() { // get cached version of structure tree if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { $data = $this->Application->getCache('master:StructureTree', false, CacheSettings::$structureTreeRebuildTime); } else { $data = $this->Application->getDBCache('StructureTree', CacheSettings::$structureTreeRebuildTime); } if ( $data ) { $data = unserialize($data); return $data; } // generate structure tree from scratch /** @var kMultiLanguageHelper $ml_helper */ $ml_helper = $this->Application->recallObject('kMultiLanguageHelper'); $languages = $ml_helper->getLanguages(); $root_category = $this->Application->getBaseCategory(); $data = $this->_getChildren($root_category, $languages); if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { $this->Application->setCache('master:StructureTree', serialize($data), 0); } else { $this->Application->setDBCache('StructureTree', serialize($data), 0); } return $data; } /** * Returns template mapping (between physical and virtual pages) * * @return Array * @access public */ public function getTemplateMapping() { if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { $data = $this->Application->getCache('master:template_mapping', false, CacheSettings::$templateMappingRebuildTime); } else { $data = $this->Application->getDBCache('template_mapping', CacheSettings::$templateMappingRebuildTime); } if ( $data ) { return unserialize($data); } $sql = 'SELECT IF(c.`Type` = ' . PAGE_TYPE_TEMPLATE . ', CONCAT(c.Template, ":", c.ThemeId), CONCAT("id:", c.CategoryId)) AS SrcTemplate, LOWER( IF( c.SymLinkCategoryId IS NOT NULL, (SELECT cc.NamedParentPath FROM ' . TABLE_PREFIX . 'Categories AS cc WHERE cc.CategoryId = c.SymLinkCategoryId), c.NamedParentPath ) ) AS DstTemplate, c.UseExternalUrl, c.ExternalUrl FROM ' . TABLE_PREFIX . 'Categories 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; } if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { $data = $this->Application->setCache('master:template_mapping', serialize($mapping), 0); } else { $this->Application->setDBCache('template_mapping', serialize($mapping), 0); } return $mapping; } /** * Returns category structure as field option list * * @return Array * @access public */ public function getStructureTreeAsOptions() { if ( (defined('IS_INSTALL') && IS_INSTALL) || !$this->Application->isAdmin ) { // no need to create category structure during install // OR on Front-End, because it's not used there return Array (); } if ( isset($this->_structureTree) ) { return $this->_structureTree; } /** @var kThemesHelper $themes_helper */ $themes_helper = $this->Application->recallObject('ThemesHelper'); $data = $this->_getStructureTree(); $theme_id = (int)$themes_helper->getCurrentThemeId(); $this->_primaryLanguageId = $this->Application->GetDefaultLanguageId(); $this->_structureTree = $this->_printChildren($data, $data['id'], $this->Application->GetVar('m_lang'), $theme_id); return $this->_structureTree; } /** * Replace links like "@@ID@@" to actual template names in given text * * @param string $text * @return string * @access public */ public function replacePageIds($text) { if ( !preg_match_all('/@@(\\d+)@@/', $text, $regs) ) { return $text; } $page_ids = $regs[1]; $sql = 'SELECT NamedParentPath, CategoryId FROM ' . TABLE_PREFIX . 'Categories WHERE CategoryId IN (' . implode(',', $page_ids) . ')'; $templates = $this->Conn->GetCol($sql, 'CategoryId'); $base_category = $this->Application->getBaseCategory(); if ( isset($templates[$base_category]) ) { // "Content" category will act as "Home Page" $templates[$base_category] .= '/Index'; } foreach ($page_ids as $page_id) { if ( !isset($templates[$page_id]) ) { // internal page was deleted, but link to it was found in given content block data continue; } $url_params = Array ('m_cat_id' => $page_id == $base_category ? 0 : $page_id, 'pass' => 'm'); $page_url = $this->Application->HREF(strtolower($templates[$page_id]), '', $url_params); /*if ($this->Application->isAdmin) { $page_url = preg_replace('/&(admin|editing_mode)=[\d]/', '', $page_url); }*/ $text = str_replace('@@' . $page_id . '@@', $page_url, $text); } return $text; } }