Application->GetVar('m_theme'); } if (!$t) { // when template not specified, use current $t = $this->Application->GetVar('t'); } $t = preg_replace('/^Content\//i', '', $t); if (substr($t, -4) == '.tpl') { // cut template extension (deprecated link format) $t = substr($t, 0, strlen($t) - 4); } if (substr($t, 0, 3) == 'id:') { // link to structure page using it's id $params['m_cat_id'] = substr($t, 3); $t = $this->structureTemplateMapping[$t]; } if (array_key_exists('use_section', $params)) { $use_section = $params['use_section']; unset($params['use_section']); } if (isset($use_section) && $use_section && array_key_exists($t . ':' . $theme_id, $this->structureTemplateMapping)) { // structure template corresponding to given physical template $t = $this->structureTemplateMapping[$t . ':' . $theme_id]; unset($params['use_section']); } if (preg_match('/external:(.*)/', $t, $rets)) { // external url return $rets[1]; } if ($this->Application->isAdmin && $prefix == '') $prefix = ADMIN_DIRECTORY; if ($this->Application->isAdmin && $prefix == '_FRONT_END_') $prefix = ''; $index_file = $this->getIndexFile($prefix, $index_file, $params); if (isset($params['_auto_prefix_'])) { unset($params['_auto_prefix_']); // this is parser-related param, do not need to pass it here } $ssl = isset($params['__SSL__']) ? $params['__SSL__'] : null; if ($ssl !== null) { $session =& $this->Application->recallObject('Session'); /* @var $session Session */ $target_url = rtrim($this->Application->BaseURL('', $ssl, false), '/'); $cookie_url = trim($session->CookieDomain . $session->CookiePath, '/.'); // set session to GET_ONLY, to pass sid only if sid is REAL AND session is set if (!preg_match('#' . preg_quote($cookie_url) . '#', $target_url) && $session->SessionSet) { // when SSL<->NON-SSL redirect to different domain pass SID in url $session->SetMode(Session::smGET_ONLY); } } if (isset($params['opener']) && $params['opener'] == 'u') { $wid = $this->Application->GetVar('m_wid'); $stack_name = rtrim('opener_stack_'.$wid, '_'); $opener_stack = $this->Application->RecallVar($stack_name); if ($opener_stack && $opener_stack != serialize(Array())) { $opener_stack = unserialize($opener_stack); list($index_file, $env) = explode('|', $opener_stack[count($opener_stack) - 1]); $ret = $this->Application->BaseURL($prefix, $ssl).$index_file.'?'.ENV_VAR_NAME.'='.$env; if ( getArrayValue($params,'escape') ) $ret = addslashes($ret); if (isset($params['m_opener']) && $params['m_opener'] == 'u') { array_pop($opener_stack); if (!$opener_stack) { $this->Application->RemoveVar($stack_name); // remove popups last templates, because popup is closing now $this->Application->RemoveVar('last_template_'.$wid); $this->Application->RemoveVar('last_template_popup_'.$wid); // don't save popups last templates again :) $this->Application->SetVar('skip_last_template', 1); } else { $this->Application->StoreVar($stack_name, serialize($opener_stack)); } /*// store window relations $window_relations = $this->Application->RecallVar('window_relations'); $window_relations = $window_relations ? unserialize($window_relations) : Array (); if (array_key_exists($wid, $window_relations)) { unset($window_relations[$wid]); $this->Application->StoreVar('window_relations', serialize($window_relations)); }*/ } return $ret; } else { //define('DBG_REDIRECT', 1); $t = $this->Application->GetVar('t'); } } $pass = isset($params['pass']) ? $params['pass'] : ''; // pass events with url $pass_events = false; if( isset($params['pass_events']) ) { $pass_events = $params['pass_events']; unset($params['pass_events']); } $map_link = ''; if( isset($params['anchor']) ) { $map_link = '#'.$params['anchor']; unset($params['anchor']); } if ( isset($params['no_amp']) ) { $params['__URLENCODE__'] = $params['no_amp']; unset($params['no_amp']); } $no_rewrite = false; if( isset($params['__NO_REWRITE__']) ) { $no_rewrite = true; unset($params['__NO_REWRITE__']); } $force_rewrite = false; if( isset($params['__MOD_REWRITE__']) ) { $force_rewrite = true; unset($params['__MOD_REWRITE__']); } $force_no_sid = false; if( isset($params['__NO_SID__']) ) { $force_no_sid = true; unset($params['__NO_SID__']); } // append pass through variables to each link to be build $params = array_merge($this->getPassThroughVariables($params), $params); if ($force_rewrite || ($this->Application->RewriteURLs($ssl) && !$no_rewrite)) { static $rewrite_listeners_done = false; if (!$rewrite_listeners_done) { $mod_rewrite_helper =& $this->Application->recallObject('ModRewriteHelper'); /* @var $mod_rewrite_helper kModRewriteHelper */ $mod_rewrite_helper->initRewriteListeners(); $rewrite_listeners_done = true; } $session =& $this->Application->recallObject('Session'); if ($session->NeedQueryString() && !$force_no_sid) { $params['sid'] = $this->Application->GetSID(); } $url = $this->BuildEnv_NEW($t, $params, $pass, $pass_events); $ret = $this->Application->BaseURL($prefix, $ssl).$url.$map_link; } else { unset($params['pass_category']); // we don't need to pass it when mod_rewrite is off $env = $this->BuildEnv($t, $params, $pass, $pass_events); $ret = $this->Application->BaseURL($prefix, $ssl).$index_file.'?'.$env.$map_link; } return $ret; } /** * Returns variables with values that should be passed throught with this link + variable list * * @param Array $params * @return Array */ function getPassThroughVariables(&$params) { static $cached_pass_through = null; if (isset($params['no_pass_through']) && $params['no_pass_through']) { unset($params['no_pass_through']); return Array(); } // because pass through is not changed during script run, then we can cache it if (is_null($cached_pass_through)) { $cached_pass_through = Array(); $pass_through = $this->Application->GetVar('pass_through'); if ($pass_through) { // names of variables to pass to each link $cached_pass_through['pass_through'] = $pass_through; $pass_through = explode(',', $pass_through); foreach ($pass_through as $pass_through_var) { $cached_pass_through[$pass_through_var] = $this->Application->GetVar($pass_through_var); } } } return $cached_pass_through; } function BuildEnv($t, $params, $pass='all', $pass_events = false, $env_var = true) { if ($this->Application->GetVar('admin') || (array_key_exists('admin', $params) && $params['admin'])) { $params['admin'] = 1; if (!array_key_exists('editing_mode', $params)) { $params['editing_mode'] = EDITING_MODE; } } $session =& $this->Application->recallObject('Session'); /* @var $session Session */ $ssl = isset($params['__SSL__']) ? $params['__SSL__'] : 0; $sid = $session->NeedQueryString() && !$this->Application->RewriteURLs($ssl) ? $this->Application->GetSID() : ''; // if (getArrayValue($params,'admin') == 1) $sid = $this->Application->GetSID(); $ret = ''; if ($env_var) { $ret = ENV_VAR_NAME.'='; } $ret .= $sid . '-'; // SID-TEMPLATE $encode = false; if (isset($params['__URLENCODE__'])) { $encode = $params['__URLENCODE__']; unset($params['__URLENCODE__']); } if (isset($params['__SSL__'])) { unset($params['__SSL__']); } $env_string = ''; $category_id = isset($params['m_cat_id']) ? $params['m_cat_id'] : $this->Application->GetVar('m_cat_id'); $item_id = false; $pass_info = $this->getPassInfo($pass); if ($pass_info) { if ($pass_info[0] == 'm') array_shift($pass_info); foreach ($pass_info as $pass_element) { list($prefix) = explode('.', $pass_element); $require_rewrite = $this->Application->findModule('Var', $prefix); if ($require_rewrite) { $item_id = isset($params[$pass_element.'_id']) ? $params[$pass_element.'_id'] : $this->Application->GetVar($pass_element.'_id'); } $env_string .= ':'.$this->BuildModuleEnv($pass_element, $params, $pass_events); } } if (strtolower($t) == '__default__') { if (is_numeric($item_id)) { $mod_rw_helper =& $this->Application->recallObject('ModRewriteHelper'); /* @var $mod_rw_helper kModRewriteHelper */ $t = $mod_rw_helper->GetItemTemplate($category_id, $pass_element); // $pass_element should be the last processed element // $t = $this->Application->getCategoryCache($category_id, 'item_templates'); } elseif ($category_id) { $t = strtolower(preg_replace('/^Content\//i', '', $this->Application->getCategoryCache($category_id, 'filenames') )); } else { $t = 'index'; } } $ret .= $t.':'.$this->BuildModuleEnv('m', $params, $pass_events).$env_string; unset($params['pass'], $params['opener'], $params['m_event']); if (array_key_exists('escape', $params) && $params['escape']) { $ret = addslashes($ret); unset($params['escape']); } if ($params) { $params_str = ''; $join_string = $encode ? '&' : '&'; foreach ($params as $param => $value) { $params_str .= $join_string . $param . '=' . $value; } $ret .= $params_str; } if ($encode) { $ret = str_replace('\\', '%5C', $ret); } return $ret; } function BuildEnv_NEW($t, $params, $pass='all', $pass_events = false) { if ($this->Application->GetVar('admin') || (array_key_exists('admin', $params) && $params['admin'])) { $params['admin'] = 1; if (!array_key_exists('editing_mode', $params)) { $params['editing_mode'] = EDITING_MODE; } } $ret = ''; $env = ''; $encode = false; if (isset($params['__URLENCODE__'])) { $encode = $params['__URLENCODE__']; unset($params['__URLENCODE__']); } if (isset($params['__SSL__'])) { unset($params['__SSL__']); } $catalog_item_found = false; $pass_info = $this->getPassInfo($pass); if ($pass_info) { if ($pass_info[0] == 'm') { array_shift($pass_info); } $inject_parts = Array (); // url parts for beginning of url $params['t'] = $t; // make template available for rewrite listeners $params['pass_template'] = true; // by default we keep given template in resulting url if (!array_key_exists('pass_category', $params)) { $params['pass_category'] = false; // by default we don't keep categories in url } foreach ($pass_info as $pass_index => $pass_element) { list ($prefix) = explode('.', $pass_element); $catalog_item = $this->Application->findModule('Var', $prefix) && $this->Application->getUnitOption($prefix, 'CatalogItem'); if (array_key_exists($prefix, $this->Application->RewriteListeners)) { // if next prefix is same as current, but with special => exclude current prefix from url $next_prefix = array_key_exists($pass_index + 1, $pass_info) ? $pass_info[$pass_index + 1] : false; if ($next_prefix) { $next_prefix = substr($next_prefix, 0, strlen($prefix) + 1); if ($prefix . '.' == $next_prefix) { continue; } } // rewrited url part $url_part = $this->BuildModuleEnv_NEW($pass_element, $params, $pass_events); if (is_string($url_part) && $url_part) { $ret .= $url_part . '/'; if ($catalog_item) { // pass category later only for catalog items $catalog_item_found = true; } } elseif (is_array($url_part)) { // rewrite listener want to insert something at the beginning of url too if ($url_part[0]) { $inject_parts[] = $url_part[0]; } if ($url_part[1]) { $ret .= $url_part[1] . '/'; } if ($catalog_item) { // pass category later only for catalog items $catalog_item_found = true; } } elseif ($url_part === false) { // rewrite listener decided not to rewrite given $pass_element $env .= ':' . $this->BuildModuleEnv($pass_element, $params, $pass_events); } } else { $env .= ':' . $this->BuildModuleEnv($pass_element, $params, $pass_events); } } if ($catalog_item_found || preg_match('/c\.[-\d]*/', implode(',', $pass_info))) { // "c" prefix is present -> keep category $params['pass_category'] = true; } $params['inject_parts'] = $inject_parts; $ret = $this->BuildModuleEnv_NEW('m', $params, $pass_events) . '/' . $ret; $cat_processed = array_key_exists('category_processed', $params) && $params['category_processed']; // remove tempporary parameters used by listeners unset($params['t'], $params['inject_parts'], $params['pass_template'], $params['pass_category'], $params['category_processed']); $ret = trim($ret, '/'); if ( isset($params['url_ending']) ) { if ($ret) { $ret .= $params['url_ending']; } unset($params['url_ending']); } elseif ($ret) { $ret .= MOD_REWRITE_URL_ENDING; } if ($env) { $params[ENV_VAR_NAME] = ltrim($env, ':'); } } unset($params['pass'], $params['opener'], $params['m_event']); if (array_key_exists('escape', $params) && $params['escape']) { $ret = addslashes($ret); unset($params['escape']); } $ret = str_replace('%2F', '/', urlencode($ret)); if ($params) { $params_str = ''; $join_string = $encode ? '&' : '&'; foreach ($params as $param => $value) { $params_str .= $join_string . $param . '=' . $value; } $ret .= '?' . substr($params_str, strlen($join_string)); } if ($encode) { $ret = str_replace('\\', '%5C', $ret); } return $ret; } /** * Builds env part that corresponds prefix passed * * @param string $prefix_special item's prefix & [special] * @param Array $params url params * @param bool $pass_events * @return string * @access protected */ protected function BuildModuleEnv($prefix_special, &$params, $pass_events = false) { list($prefix) = explode('.', $prefix_special); $query_vars = $this->Application->getUnitOption($prefix, 'QueryString', Array ()); /* @var $query_vars Array */ //if pass events is off and event is not implicitly passed if ( !$pass_events && !isset($params[$prefix_special . '_event']) ) { $params[$prefix_special . '_event'] = ''; // remove event from url if requested //otherwise it will use value from get_var } if ( !$query_vars ) { return ''; } $tmp_string = Array (0 => $prefix_special); 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; $tmp_string[$index] = isset($params[$var_name]) ? $params[$var_name] : $this->Application->GetVar($var_name); if ( isset($params[$var_name]) ) { unset($params[$var_name]); } } $escaped = array (); foreach ($tmp_string as $tmp_val) { $escaped[] = str_replace(Array ('-', ':'), Array ('\-', '\:'), $tmp_val); } $ret = implode('-', $escaped); if ( $this->Application->getUnitOption($prefix, 'PortalStyleEnv') == true ) { $ret = preg_replace('/^([a-zA-Z]+)-([0-9]+)-(.*)/', '\\1\\2-\\3', $ret); } return $ret; } function BuildModuleEnv_NEW($prefix_special, &$params, $keep_events = false) { list ($prefix) = explode('.', $prefix_special); $url_parts = Array (); $listener = $this->Application->RewriteListeners[$prefix][0]; $ret = $listener[0]->$listener[1](REWRITE_MODE_BUILD, $prefix_special, $params, $url_parts, $keep_events); return $ret; } /** * Returns sorted array of passed prefixes (to build url from) * * @param string $pass * @return Array */ function getPassInfo($pass = 'all') { if (!$pass) $pass = 'all'; $pass = trim( preg_replace( '/(?<=,|\\A)all(?=,|\\z)/', trim($this->Application->GetVar('passed'), ','), trim($pass, ',') ), ','); if (!$pass) { return Array(); } $pass_info = array_unique( explode(',', $pass) ); // array( prefix[.special], prefix[.special] ... // we need to keep that sorting despite the sorting below, because this sorts prefixes with same priority by name sort($pass_info, SORT_STRING); // to be prefix1,prefix1.special1,prefix1.special2,prefix3.specialX foreach ($pass_info as $prefix) { list ($prefix_only, ) = explode('.', $prefix, 2); $sorted[$prefix] = $this->Application->getUnitOption($prefix_only, 'RewritePriority', 0); } asort($sorted, SORT_NUMERIC); $pass_info = array_keys($sorted); // ensure that "m" prefix is at the beginning $main_index = array_search('m', $pass_info); if ($main_index !== false) { unset($pass_info[$main_index]); array_unshift($pass_info, 'm'); } return $pass_info; } /** * Returns index file, that could be passed as parameter to method, as parameter to tag and as constant or not passed at all * * @param string $prefix * @param string $index_file * @param Array $params * @return string */ function getIndexFile($prefix, $index_file, &$params) { if (isset($params['index_file'])) { $index_file = $params['index_file']; unset($params['index_file']); return $index_file; } if (isset($index_file)) { return $index_file; } if (defined('INDEX_FILE')) { return INDEX_FILE; } $cut_prefix = trim(BASE_PATH, '/').'/'.trim($prefix, '/'); return trim(preg_replace('/'.preg_quote($cut_prefix, '/').'(.*)/', '\\1', $_SERVER['PHP_SELF']), '/'); } function getPhysicalTemplate($template) { return array_search($template, $this->structureTemplateMapping); } /** * Loads template mapping for Front-End * */ function LoadStructureTemplateMapping() { if (!$this->Application->isAdmin) { $category_helper =& $this->Application->recallObject('CategoryHelper'); /* @var $category_helper CategoryHelper */ $this->structureTemplateMapping = $category_helper->getTemplateMapping(); } } }