Index: branches/5.0.x/core/units/helpers/mod_rewrite_helper.php =================================================================== --- branches/5.0.x/core/units/helpers/mod_rewrite_helper.php (revision 12783) +++ branches/5.0.x/core/units/helpers/mod_rewrite_helper.php (revision 12784) @@ -1,960 +1,951 @@ <?php /** * @version $Id$ * @package In-Portal * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license GNU/GPL * In-Portal is Open Source software. * This means that this software may have been modified pursuant * the GNU General Public License, and as distributed it includes * or is derivative of works licensed under the GNU General Public License * or other free or open source software licenses. * See http://www.in-portal.org/license for copyright notices and details. */ defined('FULL_PATH') or die('restricted access!'); class kModRewriteHelper extends kHelper { /** * Holds a refererence to httpquery * * @var kHttpQuery */ var $HTTPQuery = null; /** * Parts found during url parsing * * @var Array */ var $_partsFound = Array (); /** * Category item prefix, that was found * * @var string */ var $_modulePrefix = false; /** * Constructor of kModRewriteHelper class * * @return kModRewriteHelper */ function kModRewriteHelper() { parent::kHelper(); $this->HTTPQuery =& $this->Application->recallObject('HTTPQuery'); } function processRewriteURL() { $passed = Array (); $url = $this->HTTPQuery->Get('_mod_rw_url_'); if (substr($url, -5) == '.html') { $url = substr($url, 0, strlen($url) - 5); } $restored = false; $sql = 'SELECT Data, Cached FROM ' . TABLE_PREFIX . 'Cache WHERE VarName = "mod_rw_' . md5($url) . '"'; $cache = $this->Conn->GetRow($sql); if (false && $cache && $cache['Cached'] > 0) { // not used for now $cache = unserialize($cache['Data']); $vars = $cache['vars']; $passed = $cache['passed']; $restored = true; } else { $vars = $this->parseRewriteURL($url); $passed = $vars['pass']; // also used in bottom of this method unset($vars['pass']); $cache = Array ('vars' => $vars, 'passed' => $passed); $fields_hash = Array ( 'VarName' => 'mod_rw_' . md5($url), 'Data' => serialize($cache), 'Cached' => adodb_mktime(), ); $this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'Cache', 'REPLACE'); if (array_key_exists('t', $this->HTTPQuery->Post) && $this->HTTPQuery->Post['t']) { // template from POST overrides template from URL. $vars['t'] = $this->HTTPQuery->Post['t']; if (isset($vars['is_virtual']) && $vars['is_virtual']) { $vars['m_cat_id'] = 0; // this is virtual template category (for Proj-CMS) } } unset($vars['is_virtual']); } foreach ($vars as $name => $value) { $this->HTTPQuery->Set($name,$value); } // if ($restored) { $this->InitAll(); // } $this->HTTPQuery->finalizeParsing($passed); } function parseRewriteURL($url) { $sql = 'SELECT Data, Cached FROM ' . TABLE_PREFIX . 'Cache WHERE VarName = "mod_rw_' . md5($url) . '"'; $vars = $this->Conn->GetRow($sql); if (false && $vars && $vars['Cached'] > 0) { // not used for now $vars = unserialize($menu['Data']); return $vars; } $vars = Array ('pass' => Array ('m')); $url_parts = $url ? explode('/', trim(mb_strtolower($url), '/')) : Array (); if (($this->HTTPQuery->Get('rewrite') == 'on') || !$url_parts) { $this->_setDefaultValues($vars); } if (!$url_parts) { $this->InitAll(); $vars['t'] = $this->HTTPQuery->getDefaultTemplate(''); return $vars; } else { $vars['t'] = ''; } $this->_parseLanguage($url_parts, $vars); $this->_parseTheme($url_parts, $vars); - $this->_setDefaultPages($vars); - - if ($this->_parsePage($url_parts, $vars)) { - $this->_partsFound[] = 'parsePage'; - } // http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_page> // http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_page> (category-based section template) // http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_item> // http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_item> (category-based detail template) // http://site-url/<language>/<theme>/<rl_injections>/<category>[_<category_page>]/<rl_part> (customized url) if ( $this->processRewriteListeners($url_parts, $vars) ) { return $vars; } if ($this->_parsePhisycalTemplate($url_parts, $vars)) { $this->_partsFound[] = 'parsePhisycalTemplate'; } if (($this->_modulePrefix === false) && in_array('parseCategory', $this->_partsFound)) { // no item found, but category found -> module index page foreach ($this->Application->RewriteListeners as $prefix => $listener) { // no idea what module we are talking about, so pass info form all modules $vars['pass'][] = $prefix; } return $vars; } if (!$this->_partsFound) { $not_found = $this->Application->ConfigValue('ErrorTemplate'); $vars['t'] = $not_found ? $not_found : 'error_notfound'; $themes_helper =& $this->Application->recallObject('ThemesHelper'); /* @var $themes_helper kThemesHelper */ $vars['m_cat_id'] = $themes_helper->getPageByTemplate($vars['t'], $vars['m_theme']); header('HTTP/1.0 404 Not Found'); } return $vars; } function InitAll() { $this->Application->VerifyLanguageId(); $this->Application->Phrases->Init('phrases'); $this->Application->VerifyThemeId(); } /** * Processes url using rewrite listeners * * @param Array $url_parts * @param Array $vars * @return bool */ function processRewriteListeners(&$url_parts, &$vars) { $this->initRewriteListeners(); + $page_number = $this->_parsePage($url_parts, $vars); + + if ($page_number) { + $this->_partsFound[] = 'parsePage'; + } + foreach ($this->Application->RewriteListeners as $prefix => $listener) { + // set default page + $vars[$prefix . '_Page'] = 1; // will override page in session in case, when none is given in url + + if ($page_number) { + // page given in url - use it + $vars[$prefix . '_id'] = 0; + $vars[$prefix . '_Page'] = $page_number; + } + $listener_result = $listener[0]->$listener[1](REWRITE_MODE_PARSE, $prefix, $vars, $url_parts); if ($listener_result === false) { // will not proceed to other methods return true; } } // will proceed to other methods return false; } /** * Parses real template name from url * * @param Array $url_parts * @param Array $vars * @return bool */ function _parsePhisycalTemplate($url_parts, &$vars) { if (!$url_parts) { return false; } do { $template_path = implode('/', $url_parts); $t_parts['path'] = dirname($template_path) == '.' ? '' : '/' . dirname($template_path); $t_parts['file'] = basename($template_path); $sql = 'SELECT FileId FROM ' . TABLE_PREFIX . 'ThemeFiles WHERE (ThemeId = ' . $vars['m_theme'] . ') AND (FilePath = ' . $this->Conn->qstr($t_parts['path']) . ') AND (FileName = ' . $this->Conn->qstr($t_parts['file'] . '.tpl') . ')'; $template_found = $this->Conn->GetOne($sql); if (!$template_found) { array_shift($url_parts); } } while (!$template_found && $url_parts); if ($template_found) { $vars['t'] = $template_path; $themes_helper =& $this->Application->recallObject('ThemesHelper'); /* @var $themes_helper kThemesHelper */ $vars['m_cat_id'] = $themes_helper->getPageByTemplate($template_path, $vars['m_theme']); return true; } return false; } /** * Parses category part of url, build main part of url * * @param int $rewrite_mode Mode in what rewrite listener was called. Possbile two modes: REWRITE_MODE_BUILD, REWRITE_MODE_PARSE. * @param string $prefix Prefix, that listener uses for system integration * @param Array $params Params, that are used for url building or created during url parsing. * @param Array $url_parts Url parts to parse (only for parsing). * @param bool $keep_events Keep event names in resulting url (only for building). * @return bool|string|Array Return true to continue to next listener; return false (when building) not to rewrite given prefix; return false (when parsing) to stop processing at this listener. */ function MainRewriteListener($rewrite_mode = REWRITE_MODE_BUILD, $prefix, &$params, &$url_parts, $keep_events = false) { if ($rewrite_mode == REWRITE_MODE_BUILD) { return $this->_buildMainUrl($prefix, $params, $keep_events); } if ( $this->_parseFriendlyUrl($url_parts, $params) ) { // friendly urls work like exact match only! return false; } if ($this->_parseCategory($url_parts, $params)) { $this->_partsFound[] = 'parseCategory'; } return true; } /** * Build main part of every url * * @param string $prefix_special * @param Array $params * @param bool $keep_events * @return string */ function _buildMainUrl($prefix_special, &$params, $keep_events) { $ret = ''; list ($prefix) = explode('.', $prefix_special); $processed_params = $this->getProcessedParams($prefix_special, $params, $keep_events); if ($processed_params === false) { return ''; } // add language $default_language_id = $this->Application->GetDefaultLanguageId(); if ($processed_params['m_lang'] && ($processed_params['m_lang'] != $default_language_id)) { $language_name = $this->Application->getCache('language_names', $processed_params['m_lang']); if ($language_name === false) { $sql = 'SELECT PackName FROM ' . TABLE_PREFIX . 'Language WHERE LanguageId = ' . $processed_params['m_lang']; $language_name = $this->Conn->GetOne($sql); $this->Application->setCache('language_names', $processed_params['m_lang'], $language_name); } $ret .= $language_name . '/'; } // add theme $default_theme_id = $this->Application->GetDefaultThemeId(); if ($processed_params['m_theme'] && ($processed_params['m_theme'] != $default_theme_id)) { $theme_name = $this->Application->getCache('theme_names', $processed_params['m_theme']); if ($theme_name === false) { $sql = 'SELECT Name FROM ' . TABLE_PREFIX . 'Theme WHERE ThemeId = ' . $processed_params['m_theme']; $theme_name = $this->Conn->GetOne($sql); $this->Application->setCache('theme_names', $processed_params['m_theme'], $theme_name); } $ret .= $theme_name . '/'; } // inject custom url parts made by other rewrite listeners just after language/theme url parts if ($params['inject_parts']) { $ret .= implode('/', $params['inject_parts']) . '/'; } // add category if ($processed_params['m_cat_id'] > 0 && $params['pass_category']) { $category_filename = $this->Application->getFilename('c', $processed_params['m_cat_id']); preg_match('/^Content\/(.*)/i', $category_filename, $regs); if ($regs) { $template = array_key_exists('t', $params) ? $params['t'] : false; if (strtolower($regs[1]) == strtolower($template)) { // we could have category path like "Content/<template_path>" in this case remove template $params['pass_template'] = false; } $ret .= $regs[1] . '/'; } $params['category_processed'] = true; } // reset category page $force_page_adding = false; if (array_key_exists('reset', $params) && $params['reset']) { unset($params['reset']); if ($processed_params['m_cat_id']) { $processed_params['m_cat_page'] = 1; $force_page_adding = true; } } if ((array_key_exists('category_processed', $params) && $params['category_processed'] && ($processed_params['m_cat_page'] > 1)) || $force_page_adding) { // category name was added before AND category page number found $ret = rtrim($ret, '/') . '_' . $processed_params['m_cat_page'] . '/'; } $template = array_key_exists('t', $params) ? $params['t'] : false; $category_template = ($processed_params['m_cat_id'] > 0) && $params['pass_category'] ? $this->Application->getCache('category_designs', $processed_params['m_cat_id']) : ''; if ((strtolower($template) == '__default__') && ($processed_params['m_cat_id'] == 0)) { // for "Home" category set template to index when not set $template = 'index'; } // remove template from url if it is category index cached template if (($template == $category_template) || (mb_strtolower($template) == '__default__')) { // given template is also default template for this category or '__default__' given $params['pass_template'] = false; } if ($template && $params['pass_template']) { $ret .= $template . '/'; } return mb_strtolower( rtrim($ret, '/') ); } /** * Gets language part from url * * @param Array $url_parts * @param Array $vars * @return bool */ function _parseLanguage(&$url_parts, &$vars) { if (!$url_parts) { return false; } $url_part = reset($url_parts); $sql = 'SELECT LanguageId, IF(LOWER(PackName) = ' . $this->Conn->qstr($url_part) . ', 2, PrimaryLang) AS SortKey FROM ' . TABLE_PREFIX . 'Language WHERE Enabled = 1 ORDER BY SortKey DESC'; $language_info = $this->Conn->GetRow($sql); $this->Application->Phrases = new PhrasesCache(); if ($language_info && $language_info['LanguageId'] && $language_info['SortKey']) { // primary language will be selected in case, when $url_part doesn't match to other's language pack name // don't use next enabled language, when primary language is disabled $vars['m_lang'] = $language_info['LanguageId']; if ($language_info['SortKey'] == 2) { // language was found by pack name array_shift($url_parts); } return true; } return false; } /** * Gets theme part from url * * @param Array $url_parts * @param Array $vars * @return bool */ function _parseTheme(&$url_parts, &$vars) { if (!$url_parts) { return false; } $url_part = reset($url_parts); $sql = 'SELECT ThemeId, IF(LOWER(Name) = ' . $this->Conn->qstr($url_part) . ', 2, PrimaryTheme) AS SortKey FROM ' . TABLE_PREFIX . 'Theme WHERE Enabled = 1 ORDER BY SortKey DESC'; $theme_info = $this->Conn->GetRow($sql); if ($theme_info && $theme_info['ThemeId'] && $theme_info['SortKey']) { // primary theme will be selected in case, when $url_part doesn't match to other's theme name // don't use next enabled theme, when primary theme is disabled $vars['m_theme'] = $theme_info['ThemeId']; if ($theme_info['SortKey'] == 2) { // theme was found by name array_shift($url_parts); } return true; } $vars['m_theme'] = 0; // required, because used later for category/template detection return false; } /** * Checks if whole url_parts matches a whole In-CMS page * * @param array $url_parts * @return boolean */ function _parseFriendlyUrl($url_parts, &$vars) { if (!$url_parts) { return false; } $sql = 'SELECT CategoryId, NamedParentPath FROM ' . TABLE_PREFIX . 'Category WHERE FriendlyURL = ' . $this->Conn->qstr(implode('/', $url_parts)); $friendly = $this->Conn->GetRow($sql); if ($friendly) { $vars['m_cat_id'] = $friendly['CategoryId']; $vars['t'] = preg_replace('/^Content\//i', '', $friendly['NamedParentPath']); return true; } return false; } /** - * Set's 1st page for all modules (will be used when not passed in url) - * - * @param Array $vars - */ - function _setDefaultPages(&$vars) - { - // set 1st page for all rewrite listeners, since we don't know which of them will need it - foreach ($this->Application->RewriteListeners as $prefix => $listener) { - $vars[$prefix . '_Page'] = 1; - } - } - - /** * Set's page (when found) to all modules * * @param Array $url_parts * @param Array $vars * @return string * * @todo Should find a way, how to determine what rewrite listerner page is it */ function _parsePage(&$url_parts, &$vars) { if (!$url_parts) { return false; } $page_number = end($url_parts); if (!is_numeric($page_number)) { return false; } - // set module pages for all modules, since we don't know which module will need it - foreach ($this->Application->RewriteListeners as $prefix => $listener) { - $vars[$prefix . '_id'] = 0; - $vars[$prefix . '_Page'] = $page_number; - } - array_pop($url_parts); - return true; + return $page_number; } /** * Remove page numbers for all rewrite listeners * * @todo Should find a way, how to determine what rewrite listerner page is it */ function removePages() { foreach ($this->Application->RewriteListeners as $prefix => $listener) { $this->Application->DeleteVar($prefix . '_Page'); } } /** * Extracts category part from url * * @param Array $url_parts * @param Array $vars * @return bool */ function _parseCategory($url_parts, &$vars) { if (!$url_parts) { return false; } $res = false; $url_part = array_shift($url_parts); $category_id = 0; $last_category_info = false; $category_path = $url_part == 'content' ? '' : 'content'; do { $category_path = trim($category_path . '/' . $url_part, '/'); // bb_<topic_id> -> forums/bb_2 if ( !preg_match('/^bb_[\d]+$/', $url_part) && preg_match('/(.*)_([\d]+)$/', $category_path, $rets) ) { $category_path = $rets[1]; $vars['m_cat_page'] = $rets[2]; } $sql = 'SELECT CategoryId, IsIndex, NamedParentPath FROM ' . TABLE_PREFIX . 'Category WHERE Status IN (1,4) AND (LOWER(NamedParentPath) = ' . $this->Conn->qstr($category_path) . ') AND (ThemeId = ' . $vars['m_theme'] . ' OR ThemeId = 0)'; $category_info = $this->Conn->GetRow($sql); if ($category_info !== false) { $last_category_info = $category_info; $url_part = array_shift($url_parts); $res = true; } } while ($category_info !== false && $url_part); if ($last_category_info) { // IsIndex = 2 is a Container-only page, meaning it should go to index-page child if ($last_category_info['IsIndex'] == 2) { $sql = 'SELECT CategoryId, NamedParentPath FROM ' . TABLE_PREFIX . 'Category WHERE (ParentId = ' . $last_category_info['CategoryId'] . ') AND (IsIndex = 1) AND (ThemeId = ' . $vars['m_theme'] . ' OR ThemeId = 0)'; $category_info = $this->Conn->GetRow($sql); if ($category_info) { // when index sub-page is found use it, otherwise use container page $last_category_info = $category_info; } } // 1. Set virtual page as template, this will be replaced to physical template later in kApplication::Run. // 2. Don't set CachedTemplate field as template here, because we will loose original page associated with it's cms blocks! $vars['t'] = strtolower( preg_replace('/^Content\//i', '', $last_category_info['NamedParentPath']) ); $vars['m_cat_id'] = $last_category_info['CategoryId']; $vars['is_virtual'] = true; // for template from POST, strange code there! } else { $vars['m_cat_id'] = 0; } return $res; } /** * Builds/parses category item part of url * * @param int $rewrite_mode Mode in what rewrite listener was called. Possbile two modes: REWRITE_MODE_BUILD, REWRITE_MODE_PARSE. * @param string $prefix Prefix, that listener uses for system integration * @param Array $params Params, that are used for url building or created during url parsing. * @param Array $url_parts Url parts to parse (only for parsing). * @param bool $keep_events Keep event names in resulting url (only for building). * @return bool Return true to continue to next listener; return false (when building) not to rewrite given prefix; return false (when parsing) to stop processing at this listener. */ function CategoryItemRewriteListener($rewrite_mode = REWRITE_MODE_BUILD, $prefix, &$params, &$url_parts, $keep_events = false) { static $parsed = false; if ($rewrite_mode == REWRITE_MODE_BUILD) { return $this->_buildCategoryItemUrl($prefix, $params, $keep_events); } if (!$parsed) { $this->_modulePrefix = $this->_parseCategoryItemUrl($url_parts, $params); if ($this->_modulePrefix !== false) { $params['pass'][] = $this->_modulePrefix; $this->_partsFound[] = 'parseCategoryItemUrl'; } $parsed = true; } return true; } /** * Build category teim part of url * * @param string $prefix_special * @param Array $params * @param bool $keep_events * @return string */ function _buildCategoryItemUrl($prefix_special, &$params, $keep_events) { $ret = ''; list ($prefix) = explode('.', $prefix_special); $processed_params = $this->getProcessedParams($prefix_special, $params, $keep_events); if ($processed_params === false) { return ''; } if ($processed_params[$prefix_special . '_id']) { // this allows to fill 3 cache records with one query (see this method for details) $category_id = array_key_exists('m_cat_id', $params) ? $params['m_cat_id'] : $this->Application->GetVar('m_cat_id'); $category_filename = $this->Application->getFilename('c', $category_id); // if template is also item template of category, then remove template $template = array_key_exists('t', $params) ? $params['t'] : false; $item_template = $this->GetItemTemplate($category_id, $prefix); if ($template == $item_template || strtolower($template) == '__default__') { // given template is also default template for this category item or '__default__' given $params['pass_template'] = false; } // get item's filename if ($prefix == 'bb') { $ret .= 'bb_' . $processed_params[$prefix_special . '_id'] . '/'; } else { $filename = $this->Application->getFilename($prefix, $processed_params[$prefix_special . '_id'], $category_id); if ($filename !== false) { $ret .= $filename . '/'; } } } else { if ($processed_params[$prefix_special . '_Page'] == 1) { // when printing category items and we are on the 1st page -> there is no information about // category item prefix and $params['pass_category'] will not be added automatically $params['pass_category'] = true; } else { $ret .= $processed_params[$prefix_special . '_Page'] . '/'; } } return mb_strtolower( rtrim($ret, '/') ); } /** * Sets template and id, corresponding to category item given in url * * @param Array $url_parts * @param Array $vars * @return bool|string */ function _parseCategoryItemUrl(&$url_parts, &$vars) { if (!$url_parts) { return false; } $item_filename = end($url_parts); if (is_numeric($item_filename)) { // this page, don't process here return false; } if (preg_match('/^bb_([\d]+)/', $item_filename, $regs)) { // process topics separatly, because they don't use item filenames array_pop($url_parts); return $this->_parseTopicUrl($regs[1], $vars); } // locating the item in CategoryItems by filename to detect its ItemPrefix and its category ParentPath $sql = 'SELECT ci.ItemResourceId, ci.ItemPrefix, c.ParentPath, ci.CategoryId FROM ' . TABLE_PREFIX . 'CategoryItems AS ci LEFT JOIN ' . TABLE_PREFIX . 'Category AS c ON c.CategoryId = ci.CategoryId WHERE (ci.CategoryId = ' . (int)$vars['m_cat_id'] . ') AND (ci.Filename = ' . $this->Conn->qstr($item_filename) . ')'; $cat_item = $this->Conn->GetRow($sql); if ($cat_item !== false) { // item found $module_prefix = $cat_item['ItemPrefix']; $item_template = $this->GetItemTemplate($cat_item, $module_prefix); // converting ResourceId to correpsonding Item id $module_config = $this->Application->getUnitOptions($module_prefix); $sql = 'SELECT ' . $module_config['IDField'] . ' FROM ' . $module_config['TableName'] . ' WHERE ResourceId = ' . $cat_item['ItemResourceId']; $item_id = $this->Conn->GetOne($sql); array_pop($url_parts); if ($item_id) { if ($item_template) { // when template is found in category -> set it $vars['t'] = $item_template; } // we have category item id $vars[$module_prefix . '_id'] = $item_id; return $module_prefix; } } return false; } /** * Set's template and topic id corresponding to topic given in url * * @param int $topic_id * @param Array $vars * @return string */ function _parseTopicUrl($topic_id, &$vars) { $sql = 'SELECT c.ParentPath, c.CategoryId FROM ' . TABLE_PREFIX . 'Category AS c WHERE c.CategoryId = ' . (int)$vars['m_cat_id']; $cat_item = $this->Conn->GetRow($sql); $item_template = $this->GetItemTemplate($cat_item, 'bb'); if ($item_template) { $vars['t'] = $item_template; } $vars['bb_id'] = $topic_id; return 'bb'; } /** * Returns enviroment variable values for given prefix (uses directly given params, when available) * * @param string $prefix_special * @param Array $params * @param bool $keep_events * @return Array */ function getProcessedParams($prefix_special, &$params, $keep_events) { list ($prefix) = explode('.', $prefix_special); $query_vars = $this->Application->getUnitOption($prefix, 'QueryString'); if (!$query_vars) { // given prefix doesn't use "env" variable to pass it's data return false; } $event_key = array_search('event', $query_vars); if ($event_key) { // pass through event of this prefix unset($query_vars[$event_key]); } if (array_key_exists($prefix_special . '_event', $params) && !$params[$prefix_special . '_event']) { // if empty event, then remove it from url unset( $params[$prefix_special . '_event'] ); } // if pass events is off and event is not implicity passed if (!$keep_events && !array_key_exists($prefix_special . '_event', $params)) { unset($params[$prefix_special . '_event']); // remove event from url if requested //otherwise it will use value from get_var } $processed_params = Array (); foreach ($query_vars as $index => $var_name) { // if value passed in params use it, otherwise use current from application $var_name = $prefix_special . '_' . $var_name; $processed_params[$var_name] = array_key_exists($var_name, $params) ? $params[$var_name] : $this->Application->GetVar($var_name); if (array_key_exists($var_name, $params)) { unset($params[$var_name]); } } return $processed_params; } /** * Returns module item details template specified in given category custom field for given module prefix * * @param int|Array $category * @param string $module_prefix * @return string */ function GetItemTemplate($category, $module_prefix) { $cache_key = serialize($category) . '_' . $module_prefix; $cached_value = $this->Application->getCache(__CLASS__ . __FUNCTION__, $cache_key); if ($cached_value !== false) { return $cached_value; } if (!is_array($category)) { if ($category == 0) { $category = $this->Application->findModule('Var', $module_prefix, 'RootCat'); } $sql = 'SELECT c.ParentPath, c.CategoryId FROM ' . TABLE_PREFIX . 'Category AS c WHERE c.CategoryId = ' . $category; $category = $this->Conn->GetRow($sql); } $parent_path = implode(',',explode('|', substr($category['ParentPath'], 1, -1))); // item template is stored in module' system custom field - need to get that field Id $item_template_field_id = $this->_getItemTemplateCustomField($module_prefix); // looking for item template through cats hierarchy sorted by parent path $query = ' SELECT ccd.l1_cust_' . $item_template_field_id . ', FIND_IN_SET(c.CategoryId, ' . $this->Conn->qstr($parent_path) . ') AS Ord1, c.CategoryId, c.Name, ccd.l1_cust_' . $item_template_field_id . ' FROM ' . TABLE_PREFIX . 'Category AS c LEFT JOIN ' . TABLE_PREFIX . 'CategoryCustomData AS ccd ON ccd.ResourceId = c.ResourceId WHERE c.CategoryId IN (' . $parent_path . ') AND ccd.l1_cust_' . $item_template_field_id . ' != \'\' ORDER BY FIND_IN_SET(c.CategoryId, ' . $this->Conn->qstr($parent_path) . ') DESC'; $item_template = $this->Conn->GetOne($query); $this->Application->setCache(__CLASS__ . __FUNCTION__, $cache_key, $item_template); return $item_template; } /** * Loads all registered rewrite listeners, so they could be quickly accessed later * */ function initRewriteListeners() { static $init_done = false; if ($init_done) { return ; } foreach ($this->Application->RewriteListeners as $prefix => $listener_data) { list ($listener_prefix, $listener_method) = explode(':', $listener_data['listener']); $listener =& $this->Application->recallObject($listener_prefix); $this->Application->RewriteListeners[$prefix] = Array (&$listener, $listener_method); } $init_done = true; } /** * Returns category custom field id, where given module prefix item template name is stored * * @param string $module_prefix * @return int */ function _getItemTemplateCustomField($module_prefix) { $cached_value = $this->Application->getCache(__CLASS__ . __FUNCTION__, $module_prefix); if ($cached_value !== false) { return $cached_value; } $sql = 'SELECT CustomFieldId FROM ' . TABLE_PREFIX . 'CustomField WHERE FieldName = ' . $this->Conn->qstr($module_prefix . '_ItemTemplate'); $item_template_field_id = $this->Conn->GetOne($sql); $this->Application->setCache(__CLASS__ . __FUNCTION__, $module_prefix, $item_template_field_id); return $item_template_field_id; } /** * Sets default parsed values before actual url parsing * * @param Array $vars */ function _setDefaultValues(&$vars) { $defaults = Array ('m_cat_id' => 0, 'm_cat_page' => 1, 'm_opener' => 's', 't' => 'index'); foreach ($defaults as $default_key => $default_value) { // bug: null is never returned if ($this->HTTPQuery->Get($default_key) == null) { $vars[$default_key] = $default_value; } } } } ?> \ No newline at end of file