getUrlProcessor(); $build_params = $this->extractBuildParams(); if ( $build_params === false ) { return ''; } // Add language. if ( $build_params['m_lang'] && ($build_params['m_lang'] != $rewrite_processor->primaryLanguageId) ) { $cache_key = 'language_names[%LangIDSerial:' . $build_params['m_lang'] . '%]'; $language_name = $this->Application->getCache($cache_key); if ( $language_name === false ) { $sql = 'SELECT PackName FROM ' . TABLE_PREFIX . 'Languages WHERE LanguageId = ' . $build_params['m_lang']; $language_name = $this->Conn->GetOne($sql); $this->Application->setCache($cache_key, $language_name); } $ret .= $language_name . '/'; } // Add theme. if ( $build_params['m_theme'] && ($build_params['m_theme'] != $rewrite_processor->primaryThemeId) ) { $cache_key = 'theme_names[%ThemeIDSerial:' . $build_params['m_theme'] . '%]'; $theme_name = $this->Application->getCache($cache_key); if ( $theme_name === false ) { $sql = 'SELECT Name FROM ' . TABLE_PREFIX . 'Themes WHERE ThemeId = ' . $build_params['m_theme']; $theme_name = $this->Conn->GetOne($sql); $this->Application->setCache($cache_key, $theme_name); } $ret .= $theme_name . '/'; } // Inject custom url parts made by other routers just after language/theme url parts. $inject_parts = $this->getBuildParam('inject_parts', false); if ( $inject_parts ) { $ret .= implode('/', $inject_parts) . '/'; } // Add category. if ( $build_params['m_cat_id'] > 0 && $this->getBuildParam('pass_category', false) ) { $category_filename = $this->Application->getCategoryCache($build_params['m_cat_id'], 'filenames'); preg_match('/^Content\/(.*)/i', $category_filename, $regs); if ( $regs ) { $template = $this->getBuildParam('t', false); if ( strtolower($regs[1]) == strtolower($template) ) { // We could have category path like "Content/" in this case remove template. $this->setBuildParam('pass_template', false); } $ret .= $regs[1] . '/'; } $this->setBuildParam('category_processed', true); } // Reset category page. $force_page_adding = false; $reset_category_page = $this->getBuildParam('reset', false); if ( $reset_category_page ) { $this->setBuildParam('reset'); if ( $build_params['m_cat_id'] ) { $build_params['m_cat_page'] = 1; $force_page_adding = true; } } $category_processed = $this->getBuildParam('category_processed', false); if ( ($category_processed && ($build_params['m_cat_page'] > 1)) || $force_page_adding ) { // Category name was added before AND category page number found. $ret = rtrim($ret, '/') . '_' . $build_params['m_cat_page'] . '/'; } $template = $this->getBuildParam('t', false); if ( ($build_params['m_cat_id'] > 0) && $this->getBuildParam('pass_category', false) ) { $category_template = $this->Application->getCategoryCache($build_params['m_cat_id'], 'category_designs'); } else { $category_template = ''; } if ( (strtolower($template) == '__default__') && ($build_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. $this->setBuildParam('pass_template', false); } // Remove template from url if it is site homepage on primary language & theme. if ( $template == 'index' && $build_params['m_lang'] == $rewrite_processor->primaryLanguageId && $build_params['m_theme'] == $rewrite_processor->primaryThemeId ) { // Given template is site homepage on primary language & theme. $this->setBuildParam('pass_template', false); } if ( $template && $this->getBuildParam('pass_template', false) ) { $ret .= $template . '/'; } return mb_strtolower(rtrim($ret, '/')); } /** * Parses url part. * * @param array $url_parts Url parts to parse. * @param array $params Parameters, that are used for url building or created during url parsing. * * @return boolean Return true to continue to next router; return false to stop processing at this router. */ public function parse(array &$url_parts, array &$params) { if ( $this->parseFriendlyUrl($url_parts, $params) ) { // Friendly urls work like exact match only! return false; } $this->parseCategory($url_parts, $params); return true; } /** * Checks if whole url_parts matches a whole In-CMS page * * @param array $url_parts Url parts. * @param array $params Params. * * @return boolean */ protected function parseFriendlyUrl(array $url_parts, array &$params) { if ( !$url_parts ) { return false; } $sql = 'SELECT CategoryId, NamedParentPath FROM ' . TABLE_PREFIX . 'Categories WHERE FriendlyURL = ' . $this->Conn->qstr(implode('/', $url_parts)); $friendly = $this->Conn->GetRow($sql); if ( $friendly ) { $params['m_cat_id'] = $friendly['CategoryId']; $params['t'] = preg_replace('/^Content\//i', '', $friendly['NamedParentPath']); while ( $url_parts ) { $this->partParsed(array_shift($url_parts)); } return true; } return false; } /** * Extracts category part from url * * @param array $url_parts Url parts. * @param array $params Params. * * @return boolean */ protected function parseCategory(array $url_parts, array &$params) { 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'; $rewrite_processor = $this->getUrlProcessor(); do { $category_path = trim($category_path . '/' . $url_part, '/'); // Part: "bb_" matches "forums/bb_2". if ( !preg_match('/^bb_[\d]+$/', $url_part) && preg_match('/(.*)_([\d]+)$/', $category_path, $regs) ) { $category_path = $regs[1]; $params['m_cat_page'] = $regs[2]; } $sql = 'SELECT CategoryId, SymLinkCategoryId, NamedParentPath FROM ' . TABLE_PREFIX . 'Categories WHERE (LOWER(NamedParentPath) = ' . $this->Conn->qstr($category_path) . ') AND (ThemeId = ' . $params['m_theme'] . ' OR ThemeId = 0)'; $category_info = $this->Conn->GetRow($sql); if ( $category_info !== false ) { $last_category_info = $category_info; $rewrite_processor->partParsed($url_part); $url_part = array_shift($url_parts); $res = true; } } while ( $category_info !== false && $url_part ); if ( $last_category_info ) { // This category is symlink to other category, so use it's url instead // (used in case if url prior to symlink adding was indexed by spider or was bookmarked). if ( $last_category_info['SymLinkCategoryId'] ) { $sql = 'SELECT CategoryId, NamedParentPath FROM ' . TABLE_PREFIX . 'Categories WHERE (CategoryId = ' . $last_category_info['SymLinkCategoryId'] . ')'; $category_info = $this->Conn->GetRow($sql); if ( $category_info ) { // Web symlinked category was found use it. // TODO: maybe 302 redirect should be made to symlinked category url // (all other url parts should stay). $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! $params['t'] = mb_strtolower(preg_replace('/^Content\//i', '', $last_category_info['NamedParentPath'])); $params['m_cat_id'] = $last_category_info['CategoryId']; $params['is_virtual'] = true; // For template from POST, strange code there! } return $res; } }