_buildCategoryItemUrl($prefix, $params, $keep_events); } $module_prefix = $this->_parseCategoryItemUrl($url_parts, $params, $prefix); if ($module_prefix !== false) { /** @var kRewriteUrlProcessor $rewrite_processor */ $rewrite_processor = $this->Application->recallObject('kRewriteUrlProcessor'); $params['pass'][] = $module_prefix; $rewrite_processor->setModulePrefix($module_prefix); } return true; } /** * Build category item part of url * * @param string $prefix_special * @param Array $params * @param bool $keep_events * @return string * @access protected */ protected function _buildCategoryItemUrl($prefix_special, &$params, $keep_events) { static $default_per_page = Array (); /** @var kRewriteUrlProcessor $rewrite_processor */ $rewrite_processor = $this->Application->recallObject('kRewriteUrlProcessor'); $ret = ''; list ($prefix) = explode('.', $prefix_special); $processed_params = $rewrite_processor->getProcessedParams($prefix_special, $params, $keep_events); if ($processed_params === false) { return ''; } if ( isset($params[$prefix_special . '_event']) && $params[$prefix_special . '_event'] ) { $params['events[' . $prefix_special . ']'] = $params[$prefix_special . '_event']; unset($params[$prefix_special . '_event']); } if (!array_key_exists($prefix, $default_per_page)) { /** @var ListHelper $list_helper */ $list_helper = $this->Application->recallObject('ListHelper'); $default_per_page[$prefix] = $list_helper->getDefaultPerPage($prefix); } if ($processed_params[$prefix_special . '_id']) { $category_id = array_key_exists('m_cat_id', $params) ? $params['m_cat_id'] : $this->Application->GetVar('m_cat_id'); // if template is also item template of category, then remove template $template = array_key_exists('t', $params) ? $params['t'] : false; $item_template = $rewrite_processor->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->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; } elseif ($processed_params[$prefix_special . '_Page'] > 1) { // $ret .= $processed_params[$prefix_special . '_Page'] . '/'; $params['page'] = $processed_params[$prefix_special . '_Page']; } $per_page = $processed_params[$prefix_special . '_PerPage']; if ($per_page && ($per_page != $default_per_page[$prefix])) { $params['per_page'] = $processed_params[$prefix_special . '_PerPage']; } } return mb_strtolower( rtrim($ret, '/') ); } /** * Builds/parses review 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_special 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. * @access public */ public function ReviewRewriteListener($rewrite_mode = REWRITE_MODE_BUILD, $prefix_special, &$params, &$url_parts, $keep_events = false) { static $default_per_page = Array (); if ( $rewrite_mode != REWRITE_MODE_BUILD ) { // don't parse anything return true; } /** @var kRewriteUrlProcessor $rewrite_processor */ $rewrite_processor = $this->Application->recallObject('kRewriteUrlProcessor'); $ret = ''; list ($prefix) = explode('.', $prefix_special); $processed_params = $rewrite_processor->getProcessedParams($prefix_special, $params, $keep_events); if ($processed_params === false) { return ''; } if (!array_key_exists($prefix, $default_per_page)) { /** @var ListHelper $list_helper */ $list_helper = $this->Application->recallObject('ListHelper'); $default_per_page[$prefix] = $list_helper->getDefaultPerPage($prefix); } if ($processed_params[$prefix_special . '_id']) { return false; } 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; } elseif ($processed_params[$prefix_special . '_Page'] > 1) { // $ret .= $processed_params[$prefix_special . '_Page'] . '/'; $params['page'] = $processed_params[$prefix_special . '_Page']; } $per_page = $processed_params[$prefix_special . '_PerPage']; if ($per_page && ($per_page != $default_per_page[$prefix])) { $params['per_page'] = $processed_params[$prefix_special . '_PerPage']; } } return mb_strtolower( rtrim($ret, '/') ); } /** * Returns item's filename that corresponds id passed. If possible, then get it from cache * * @param string $prefix * @param int $id * @param int $category_id * @return string * @access protected */ protected function getFilename($prefix, $id, $category_id = null) { if ($prefix == 'c') { throw new Exception('Method "' . __FUNCTION__ . '" no longer work with "c" prefix. Please use "getCategoryCache" method instead'); return false; } $category_id = isset($category_id) ? $category_id : $this->Application->GetVar('m_cat_id'); $cache_key = 'filenames[%' . $this->Application->incrementCacheSerial($prefix, $id, false) . '%]:' . (int)$category_id; $filename = $this->Application->getCache($cache_key); if ($filename === false) { $this->Conn->nextQueryCachable = true; $sql = 'SELECT ResourceId FROM ' . $this->Application->getUnitOption($prefix, 'TableName') . ' WHERE ' . $this->Application->getUnitOption($prefix, 'IDField') . ' = ' . $this->Conn->qstr($id); $resource_id = $this->Conn->GetOne($sql); $this->Conn->nextQueryCachable = true; $sql = 'SELECT Filename FROM ' . TABLE_PREFIX . 'CategoryItems WHERE (ItemResourceId = ' . $resource_id . ') AND (CategoryId = ' . (int)$category_id . ')'; $filename = $this->Conn->GetOne($sql); if ($filename !== false) { $this->Application->setCache($cache_key, $filename); } } return $filename; } /** * Sets template and id, corresponding to category item given in url * * @param Array $url_parts * @param Array $vars * @param string $prefix Prefix, that listener uses for system integration * * @return boolean|string * @access protected */ protected function _parseCategoryItemUrl(&$url_parts, &$vars, $prefix) { if ( !$url_parts ) { return false; } $item_filename = end($url_parts); if ( is_numeric($item_filename) ) { // this page, don't process here return false; } /** @var kRewriteUrlProcessor $rewrite_processor */ $rewrite_processor = $this->Application->recallObject('kRewriteUrlProcessor'); if ( $prefix == 'bb' && preg_match('/^bb_([\d]+)/', $item_filename, $regs) ) { // process topics separately, because they don't use item filenames array_pop($url_parts); $rewrite_processor->partParsed($item_filename, 'rtl'); return $this->_parseTopicUrl($regs[1], $vars); } $cat_item = $this->findCategoryItem((int)$vars['m_cat_id'], $item_filename, $prefix); if ( $cat_item !== false ) { // item found $module_prefix = $cat_item['ItemPrefix']; $item_template = $rewrite_processor->GetItemTemplate($cat_item, $module_prefix, $vars['m_theme']); // converting ResourceId to corresponding 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); if ( $item_id ) { array_pop($url_parts); $rewrite_processor->partParsed($item_filename, 'rtl'); 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; } /** * Locating the item in CategoryItems by filename to detect its ItemPrefix and its category ParentPath. * * @param integer $category_id Category. * @param string $filename Filename. * @param string $prefix Prefix, that listener uses for system integration * * @return string */ protected function findCategoryItem($category_id, $filename, $prefix) { static $cache = array(); $cache_key = $category_id . ':' . $filename; if ( !isset($cache[$cache_key]) ) { $sql = 'SELECT ci.ItemResourceId, ci.ItemPrefix, c.ParentPath, ci.CategoryId FROM ' . TABLE_PREFIX . 'CategoryItems AS ci LEFT JOIN ' . TABLE_PREFIX . 'Categories AS c ON c.CategoryId = ci.CategoryId WHERE (ci.CategoryId = ' . $category_id . ') AND (ci.Filename = ' . $this->Conn->qstr($filename) . ')'; $cache[$cache_key] = $this->Conn->GetRow($sql); } $category_item = $cache[$cache_key]; return $category_item && $category_item['ItemPrefix'] == $prefix ? $category_item : false; } /** * Set's template and topic id corresponding to topic given in url * * @param int $topic_id * @param Array $vars * @return string * @access protected */ protected function _parseTopicUrl($topic_id, &$vars) { /** @var kRewriteUrlProcessor $rewrite_processor */ $rewrite_processor = $this->Application->recallObject('kRewriteUrlProcessor'); $sql = 'SELECT c.ParentPath, c.CategoryId FROM ' . TABLE_PREFIX . 'Categories AS c WHERE c.CategoryId = ' . (int)$vars['m_cat_id']; $cat_item = $this->Conn->GetRow($sql); $item_template = $rewrite_processor->GetItemTemplate($cat_item, 'bb', $vars['m_theme']); if ($item_template) { $vars['t'] = $item_template; } $vars['bb_id'] = $topic_id; return 'bb'; } }