plain = $this->Application->makeClass('kPlainUrlProcessor', Array (&$this)); } /** * Delay initialization of rewrite processor, since it uses site domains & http query * * @return void * @access public */ public function initRewrite() { if ( $this->rewriteReady ) { return; } $this->rewrite = $this->Application->recallObject('kRewriteUrlProcessor', null, Array (), Array (&$this)); $this->rewriteReady = true; } /** * Return href for template * * @param string $t Template path * @param string $prefix index.php prefix - could be blank, 'admin' * @param Array $params * @param string $index_file * @return string */ public function HREF($t, $prefix = '', $params = Array (), $index_file = null) { 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 ) { $theme_id = isset($params['m_theme']) ? $params['m_theme'] : null; $t = $this->getSectionTemplate($t, $theme_id); } if ( preg_match('/external:(.*)/', $t, $regs) ) { // external url return $regs[1]; } if ( $this->Application->isAdmin && $prefix == '' ) { $prefix = ADMIN_DIRECTORY; } if ( $this->Application->isAdmin && $prefix == '_FRONT_END_' ) { $prefix = ''; } 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 ) { /** @var Session $session */ $session = $this->Application->recallObject('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' ) { $ret = $this->processPopupClose($prefix, $params); if ( $ret !== false ) { 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']); } $rewrite = true; if ( isset($params['__NO_REWRITE__']) ) { $rewrite = false; 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); $session = $this->Application->recallObject('Session'); if ( $session->NeedQueryString() && !$force_no_sid ) { $params['sid'] = $this->Application->GetSID(); } if ( $force_rewrite || ($this->Application->RewriteURLs($ssl) && $rewrite) ) { if ( !$this->rewriteReady ) { $this->initRewrite(); } $url = $this->rewrite->build($t, $params, $pass, $pass_events); } else { unset($params['pass_category']); // we don't need to pass it when mod_rewrite is off $index_file = $this->getIndexFile($prefix, $index_file, $params); $url = $index_file . '?' . $this->plain->build($t, $params, $pass, $pass_events); } return $this->Application->BaseURL($prefix, $ssl) . $url . $map_link; } /** * Returns popup's parent window url and optionally removes it from opener stack * * @param string $prefix * @param Array $params * @return bool|string * @access protected */ protected function processPopupClose($prefix = '', $params = Array ()) { /** @var kOpenerStack $opener_stack */ $opener_stack = $this->Application->makeClass('kOpenerStack'); if ( $opener_stack->isEmpty() ) { return false; } $ssl = isset($params['__SSL__']) ? $params['__SSL__'] : null; list($index_file, $env) = explode('|', $opener_stack->get(kOpenerStack::LAST_ELEMENT, true)); $ret = $this->Application->BaseURL($prefix, $ssl) . $index_file . '?' . ENV_VAR_NAME . '=' . $env; if ( isset($params['m_opener']) && $params['m_opener'] == 'u' ) { $opener_stack->pop(); $opener_stack->save(true); if ( $opener_stack->isEmpty() ) { // remove popups last templates, because popup is closing now $this->Application->RemoveVar('last_template_' . $opener_stack->getWindowID()); $this->Application->RemoveVar('last_template_popup_' . $opener_stack->getWindowID()); // don't save popups last templates again :) $this->Application->SetVar('skip_last_template', 1); } // 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; } /** * Returns variables with values that should be passed through with this link + variable list * * @param Array $params * @return Array * @access public */ public 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; } /** * 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 * @access protected */ protected function getIndexFile($prefix, $index_file = null, &$params) { static $cache = Array (); 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; } // detect index file only once for given script and $cut_prefix $php_self = $_SERVER['PHP_SELF']; $cut_prefix = BASE_PATH . '/' . trim($prefix, '/'); if ( isset($cache[$php_self . ':' . $cut_prefix]) ) { return $cache[$php_self . ':' . $cut_prefix]; } $cache[$php_self . ':' . $cut_prefix] = trim(preg_replace('/' . preg_quote($cut_prefix, '/') . '(.*)/', '\\1', $php_self), '/'); return $cache[$php_self . ':' . $cut_prefix]; } /** * Returns theme template filename and it's corresponding page_id based on given seo template * * @param string $seo_template * @return string * @access public */ public function getPhysicalTemplate($seo_template) { $physical_template = false; $found_templates = array_keys($this->structureTemplateMapping, $seo_template); foreach ($found_templates as $found_template) { if ( substr($found_template, 0, 3) == 'id:' ) { // exclude virtual templates continue; } // several templates matched (physical and sym-linked to it) $physical_template = $found_template; } if ( $physical_template === false ) { // physical template from ".smsignore" file return $seo_template; } list ($physical_template,) = explode(':', $physical_template, 2); // template_path:theme_id => seo_template return $physical_template; } /** * Returns template name, that corresponds with given virtual (not physical) page id * * @param int $page_id * @return string|bool * @access public */ public function getVirtualPageTemplate($page_id) { return isset($this->structureTemplateMapping['id:' . $page_id]) ? $this->structureTemplateMapping['id:' . $page_id] : false; } /** * Returns section template for given physical/virtual template * * @param string $template * @param int $theme_id * @return string * @access public */ public function getSectionTemplate($template, $theme_id = null) { static $current_theme_id = null; if ( !isset($current_theme_id) ) { $current_theme_id = $this->Application->GetVar('m_theme'); } if ( !isset($theme_id) ) { $theme_id = $current_theme_id; } if ( array_key_exists($template . ':' . $theme_id, $this->structureTemplateMapping) ) { // structure template corresponding to given physical template return $this->structureTemplateMapping[$template . ':' . $theme_id]; } return $template; } /** * Loads template mapping for Front-End * * @return void * @access public */ public function LoadStructureTemplateMapping() { if (!$this->Application->isAdmin) { /** @var CategoryHelper $category_helper */ $category_helper = $this->Application->recallObject('CategoryHelper'); $this->structureTemplateMapping = $category_helper->getTemplateMapping(); } } /** * Removes tpl part from template name + resolved template ID to name * * @param string $default_template * @return string * @access public */ public function getTemplateName($default_template = '') { if ( $this->Application->GetVarDirect('t', 'Get') !== false ) { // template name is passed directly in url (GET method) $t = $this->Application->GetVarDirect('t', 'Get'); } elseif ( $this->Application->GetVar('env') && $this->Application->RewriteURLs() && $this->Application->GetVar('t') ) { // if t was set through env, even in mod_rewrite mode! $t = $this->Application->GetVar('t'); } else { $t = trim($default_template ? $default_template : 'index', '/'); } return trim(preg_replace('/\.tpl$/', '', $t), '/'); } /** * Show 404 page and exit * * @return void * @access public */ public function show404() { header('HTTP/1.0 404 Not Found'); $not_found = $this->Application->ConfigValue('ErrorTemplate'); $template = $not_found ? $not_found : 'error_notfound'; $this->Application->QuickRun($template); $this->Application->Done(); exit; } }