Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Sun, Feb 2, 5:32 AM

in-portal

Index: branches/5.2.x/core/kernel/managers/url_manager.php
===================================================================
--- branches/5.2.x/core/kernel/managers/url_manager.php (revision 16805)
+++ branches/5.2.x/core/kernel/managers/url_manager.php (revision 16806)
@@ -1,471 +1,476 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2010 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kUrlManager extends kBase {
/**
* Processor of plain urls (initialized always)
*
* @var kPlainUrlProcessor
* @access public
*/
public $plain = null;
/**
* Processor of rewritten urls (initialized on demand only)
*
* @var kRewriteUrlProcessor
* @access public
*/
public $rewrite = null;
/**
* Tells, that rewrite system is ready
*
* @var bool
* @access protected
*/
protected $rewriteReady = false;
/**
* Physical template name mapping to their template names based in "Structure & Data" section
*
* @var Array
*/
protected $structureTemplateMapping = Array ();
/**
* Creates instead of kUrlManager class
*/
public function __construct()
{
parent::__construct();
// don't use kApplication::recallObject, since it will call kApplication::EventManager, which isn't ready yet
$this->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';
+ // Avoid recursion, when attempt is made to show 404 page while on the 404 page.
+ if ( $this->Application->GetVar('t') === $template ) {
+ return;
+ }
+
$this->Application->QuickRun($template);
$this->Application->Done();
exit;
}
}

Event Timeline