HTTPQuery =& $this->Application->recallObject('HTTPQuery'); } function SetDefaultValues(&$vars) { $defaults = Array('m_cat_id' => 0, 'm_cat_page' => 1, 'm_opener' => 's'); foreach ($defaults as $default_key => $default_value) { if ($this->HTTPQuery->Get($default_key) == null) { $vars[$default_key] = $default_value; } } } function ProcessLanguage(&$url_parts, &$vars) { if (!isset($url_parts[0])) return false; $res = false; $url_part = array_shift($url_parts); $sql = 'SELECT LanguageId FROM '.TABLE_PREFIX.'Language WHERE LOWER(PackName) = '.$this->Conn->qstr($url_part).' AND Enabled = 1'; $language_id = $this->Conn->GetOne($sql); $this->Application->Phrases = new PhrasesCache(); if($language_id) { $vars['m_lang'] = $language_id; $res = true; } // $this->Application->VerifyLanguageId(); if (!$res) { array_unshift($url_parts, $url_part); } return $res; } function ProcessTheme(&$url_parts, &$vars) { if (!isset($url_parts[0])) return false; $res = false; $url_part = array_shift($url_parts); $sql = 'SELECT ThemeId FROM '.TABLE_PREFIX.'Theme WHERE LOWER(Name) = '.$this->Conn->qstr($url_part).' AND Enabled = 1'; $theme_id = $this->Conn->GetOne($sql); if($theme_id) { $vars['m_theme'] = $theme_id; $res = true; } // $this->Application->VerifyThemeId(); // verify anyway - will set default if not found!!! if (!$res) { array_unshift($url_parts, $url_part); } return $res; } function ProcessCategory(&$url_parts, &$vars) { if (!isset($url_parts[0])) { 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__ -> forums/bb__2 OR forums/bb_2_6 if( !preg_match('/^bb_([\d]+)*_[\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) . ')'; $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'; $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 } else { $vars['m_cat_id'] = 0; } if ($url_part) { array_unshift($url_parts, $url_part); } return $res; } function ProcessPage(&$url_parts, &$vars) { if (!is_numeric($url_parts[0]) || count($url_parts) > 1) return false; // set module pages for all modules, since we don't know which module will need it foreach ($this->Application->ModuleInfo as $module_name => $module_data) { $vars[ $module_data['Var'].'_id'] = 0; $vars[ $module_data['Var'].'_Page'] = $url_parts[0]; $vars[ $module_data['Var'].'_Reviews_Page'] = 0; } return true; } /** * Set's 1st page for all modules (will be used when not passed in url) * * @param Array $vars * @todo this is temporary fix, until mod-rewrite helper will become category-independend */ function SetDefaultPages(&$vars) { // set module pages for all modules, since we don't know which module will need it foreach ($this->Application->ModuleInfo as $module_name => $module_data) { $vars[ $module_data['Var'].'_Page'] = 1; } } function ProcessModuleIndex(&$url_parts, &$vars) { if ( count($url_parts) > 1) return false; // if no more parts or only 1 part left if ( $url_parts && $url_parts[0] == 'index') { // treat index same as no parts array_shift($url_parts); } if( $url_parts ) { // if parts are left, it can only be module page if (preg_match('/^bb_(.*)/', $url_parts[0], $regs)) { list ($topic_id, $topic_page) = explode('_', $regs[1], 2); if (!$topic_id) { $url_parts[0] = $topic_page; } } if (!is_numeric($url_parts[0])) return false; $this->ProcessPage($url_parts, $vars); } /*$sql = 'SELECT CachedTemplate FROM ' . TABLE_PREFIX . 'Category WHERE CategoryId = ' . $vars['m_cat_id']; $vars['t'] = $this->Conn->GetOne($sql);*/ if (!$vars['t']) { $vars['t'] = 'index'; } return true; } function ProcessModuleItem(&$url_parts, &$vars, $set_t=true) { if (preg_match('/^bb_.*/', $url_parts[0])) { $sql = 'SELECT c.ParentPath, c.CategoryId FROM '.TABLE_PREFIX.'Category AS c WHERE c.CategoryId = '.$vars['m_cat_id']; $cat_item = $this->Conn->GetRow($sql); if ($set_t) { $item_template = $this->GetItemTemplate($cat_item, 'bb'); $vars['t'] = $item_template; } $this->Application->HandleEvent($bb_event, 'bb:ParseEnv', Array('url_parts' => $url_parts, 'vars' => $vars)); $vars = $bb_event->getEventParam('vars'); return 'bb'; } if (!isset($url_parts[0])) return false; if ( count($url_parts) != 1 ) return false; $url_part = array_shift($url_parts); // match module reviews page $page = 1; if( preg_match('/(.*)_([\d]+)$/', $url_part, $rets) ) { $url_part = $rets[1]; $page = $rets[2]; } // locating the item in CategoryItems by filename to detect its ItemPrefix and its category ParentPath $cat_item = $this->Conn->GetRow(' 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 = '.$vars['m_cat_id'].' AND ci.Filename = '.$this->Conn->qstr($url_part)); 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); $item_id = $this->Conn->GetOne( 'SELECT '.$module_config['IDField'].' FROM '.$module_config['TableName'].' WHERE ResourceId = '.$cat_item['ItemResourceId'] ); if ((!$set_t || $item_template) && $item_id) { if ($set_t) { $vars['t'] = $item_template; } $vars[ $module_prefix.'_id' ] = $item_id; $vars[ $module_prefix.'_Reviews_Page' ] = $page; return $module_prefix; } } array_unshift($url_parts, $url_part); return false; } 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; } 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; } function ProcessPhisycalTemplate(&$url_parts, &$vars) { if (!isset($url_parts[0])) return false; $remaining = array(); 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 (FilePath = '.$this->Conn->qstr($t_parts['path']).') AND (FileName = '.$this->Conn->qstr($t_parts['file'].'.tpl').')'; // $sql = 'SELECT FileId FROM '.TABLE_PREFIX.'ThemeFiles WHERE CONCAT(FilePath, "/", FileName) = '.$this->Conn->qstr('/'.$template_path.'.tpl'); $template_found = $this->Conn->GetOne($sql); if(!$template_found) { array_unshift($remaining, array_pop($url_parts)); } } while (!$template_found && $url_parts); $url_parts = $remaining; if ($template_found) { $vars['t'] = $template_path; return true; } return false; } /** * Checks if whole url_parts matches a whole In-CMS page * * @param array $url_parts * @return boolean */ function ProcessFriendlyUrl(&$url_parts, &$vars) { if (!isset($url_parts[0])) 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; } 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; $cache = $this->Conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "mod_rw_'.md5($url).'"'); if (false && $cache && $cache['Cached'] > 0) { $cache = unserialize($cache['Data']); $vars = $cache['vars']; $passed = $cache['passed']; $restored = true; } else { $passed = array(); $vars = $this->parseRewriteURL($url,$passed); $cache = array('vars'=>$vars,'passed'=>$passed); $this->Conn->Query('REPLACE '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("mod_rw_'.md5($url).'", '.$this->Conn->qstr(serialize($cache)).', '.adodb_mktime().')'); if (isset($this->HTTPQuery->Post['t']) && $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 InitAll() { // $this->Application->Phrases = new PhrasesCache(); $this->Application->VerifyLanguageId(); $this->Application->Phrases->Init('phrases'); $this->Application->VerifyThemeId(); } function parseRewriteURL($url, &$passed) { $vars = $this->Conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "mod_rw_'.md5($url).'"'); if (false && $vars && $vars['Cached'] > 0) { $vars = unserialize($menu['Data']); return $vars; } $vars = array(); $url_parts = $url ? explode('/', trim($url, '/')) : Array(); $process_module = true; if($this->HTTPQuery->Get('rewrite') == 'on' || !$url_parts) { $this->SetDefaultValues($vars); } if(!$url_parts) { $this->InitAll(); $vars['t'] = $this->HTTPQuery->getDefaultTemplate(''); $passed[] = 'm'; return $vars; } else { $vars['t'] = ''; } $passed = Array('m'); $this->ProcessLanguage($url_parts, $vars); $this->ProcessTheme($url_parts, $vars); // bug #1: cancells all other processing in case, when cms page is found // bug #2: doesn't match template partially, e.g. "test/case/other" will not match to page "test/case" with "other" left for future processing if ( $this->ProcessFriendlyUrl($url_parts, $vars) ) { return $vars; } $this->ProcessCategory($url_parts, $vars); $this->SetDefaultPages($vars); if ( $this->ProcessModuleIndex($url_parts, $vars) ) { foreach ($this->Application->ModuleInfo as $module_name => $info) { $passed[] = $info['Var']; } return $vars; } if ( $module_prefix = $this->ProcessModuleItem($url_parts, $vars) ) { $passed[] = $module_prefix; return $vars; } /*// match module $next_template = $this->HTTPQuery->Get('next_template'); if($url_part || $next_template) { if($next_template) { $next_template_parts = explode('/', $next_template); $module_folder = array_shift($next_template_parts); } else { $module_folder = $url_part; } foreach ($this->Application->ModuleInfo as $module_name => $module_data) { if( trim($module_data['TemplatePath'], '/') == $module_folder ) { $module_prefix = $module_data['Var']; break; } } }*/ if ( $this->ProcessPhisycalTemplate($url_parts, $vars) ) { if (!$url_parts) { return $vars; } } if ( $this->ProcessPage($url_parts, $vars) ) { if (count($passed) == 1) {// passed contains only 1 value which is 'm' // this may be search results page, so we need to find out the module, especially for old in-portal foreach ($this->Application->ModuleInfo as $module_name => $module_data) { if (!$module_data['TemplatePath']) continue; if( preg_match('/^'.preg_quote($module_data['TemplatePath'], '/').'/i', $vars['t']) ) { $module_prefix = $module_data['Var']; break; } } $passed[] = $module_prefix; } return $vars; } if ( $module_prefix = $this->ProcessModuleItem($url_parts, $vars, false) ) { $passed[] = $module_prefix; return $vars; } /*if ( $this->Application->isModuleEnabled('In-Edit') && $this->Application->GetVar('admin') == 1) { $adm_ses =& $this->Application->recallObject('Session.admin'); $user = $adm_ses->RecallVar('user_id'); $perm_helper =& $this->Application->recallObject('PermissionsHelper'); if ($perm_helper->CheckUserPermission($user, 'PAGE.ADD', 0)) { $vars['t'] = implode('/', $url_parts); return $vars; } }*/ $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']); header('HTTP/1.0 404 Not Found'); return $vars; // $this->HTTPQuery->finalizeParsing($passed, $module_params); // pass params left to module /*$this->Application->Phrases->Init('phrases'); $passed = Array('m'); $module_params = Array(); if ( isset($module_prefix) ) { $passed[] = $module_prefix; $module_event = new kEvent($module_prefix.':ParseEnv', Array('url_parts' => $url_parts) ); if ($process_module) { $this->Application->HandleEvent($module_event); } $item_id = $this->HTTPQuery->Get($module_prefix.'_id'); $module_params = Array($module_prefix.'_id' => $item_id ? $item_id : '0' ); if ($module_event->status == erFAIL) { $not_found = $this->Application->ConfigValue('ErrorTemplate'); $this->HTTPQuery->Set('t', $not_found ? $not_found : 'error_notfound' ); } } $this->HTTPQuery->finalizeParsing($passed, $module_params);*/ } } ?>