Changeset View
Changeset View
Standalone View
Standalone View
branches/5.3.x/core/kernel/managers/rewrite_url_processor.php
Show All 19 Lines | |||||
* Holds a reference to httpquery | * Holds a reference to httpquery | ||||
* | * | ||||
* @var kHttpQuery | * @var kHttpQuery | ||||
* @access protected | * @access protected | ||||
*/ | */ | ||||
protected $HTTPQuery = null; | protected $HTTPQuery = null; | ||||
/** | /** | ||||
* Urls parts, that needs to be matched by rewrite listeners | * Urls parts, that needs to be matched by routers. | ||||
* | * | ||||
* @var Array | * @var array | ||||
* @access protected | |||||
*/ | */ | ||||
protected $_partsToParse = Array (); | protected $_partsToParse = array(); | ||||
/** | /** | ||||
* Category item prefix, that was found | * Category item prefix, that was found | ||||
* | * | ||||
* @var string|boolean | * @var string|boolean | ||||
* @access protected | * @access protected | ||||
*/ | */ | ||||
protected $modulePrefix = false; | protected $modulePrefix = false; | ||||
Show All 26 Lines | |||||
* Possible url endings from ModRewriteUrlEnding configuration variable | * Possible url endings from ModRewriteUrlEnding configuration variable | ||||
* | * | ||||
* @var Array | * @var Array | ||||
* @access protected | * @access protected | ||||
*/ | */ | ||||
protected $_urlEndings = Array ('.html', '/', ''); | protected $_urlEndings = Array ('.html', '/', ''); | ||||
/** | /** | ||||
* Factory storage sub-set, containing mod-rewrite listeners, used during url building and parsing | * Factory storage sub-set, containing routers, used during url building and parsing. | ||||
* | * | ||||
* @var Array | * @var array | ||||
* @access protected | |||||
*/ | */ | ||||
protected $rewriteListeners = Array (); | protected $routers = array(); | ||||
/** | /** | ||||
* Constructor of kRewriteUrlProcessor class | * Constructor of kRewriteUrlProcessor class | ||||
* | * | ||||
* @param $manager | * @param $manager | ||||
* @return kRewriteUrlProcessor | * @return kRewriteUrlProcessor | ||||
*/ | */ | ||||
public function __construct(&$manager) | public function __construct(&$manager) | ||||
Show All 13 Lines | |||||
// domain based primary theme | // domain based primary theme | ||||
$this->primaryThemeId = $this->Application->siteDomainField('PrimaryThemeId'); | $this->primaryThemeId = $this->Application->siteDomainField('PrimaryThemeId'); | ||||
if (!$this->primaryThemeId) { | if (!$this->primaryThemeId) { | ||||
// when domain-based theme not found -> use site-wide theme | // when domain-based theme not found -> use site-wide theme | ||||
$this->primaryThemeId = $this->Application->GetDefaultThemeId(true); | $this->primaryThemeId = $this->Application->GetDefaultThemeId(true); | ||||
} | } | ||||
$this->_initRewriteListeners(); | $this->initRouters(); | ||||
} | } | ||||
/** | /** | ||||
* Sets module prefix. | * Sets module prefix. | ||||
* | * | ||||
* @param string $prefix Unit config prefix. | * @param string $prefix Unit config prefix. | ||||
* | * | ||||
* @return void | * @return void | ||||
▲ Show 20 Lines • Show All 210 Lines • ▼ Show 20 Line(s) | |||||
'Cached' => time(), | 'Cached' => time(), | ||||
'LifeTime' => isset($expiration) && is_numeric($expiration) ? $expiration : -1 | 'LifeTime' => isset($expiration) && is_numeric($expiration) ? $expiration : -1 | ||||
); | ); | ||||
$this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'CachedUrls'); | $this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'CachedUrls'); | ||||
} | } | ||||
/** | /** | ||||
* Loads all registered rewrite listeners, so they could be quickly accessed later | * Loads all registered routers, so they could be quickly accessed later. | ||||
* | * | ||||
* @access protected | * @return void | ||||
*/ | */ | ||||
protected function _initRewriteListeners() | protected function initRouters() | ||||
{ | { | ||||
static $init_done = false; | static $init_done = false; | ||||
if ($init_done || count($this->Application->RewriteListeners) == 0) { | // Not initialized OR mod-rewrite url with missing config cache. | ||||
// not initialized OR mod-rewrite url with missing config cache | if ( $init_done || count($this->Application->routers) == 0 ) { | ||||
return ; | return; | ||||
} | } | ||||
foreach ($this->Application->RewriteListeners as $prefix => $listener_data) { | foreach ( $this->Application->routers as $prefix => $router_data ) { | ||||
foreach ($listener_data['listener'] as $index => $rewrite_listener) { | $this->routers[$prefix] = $this->Application->makeClass($router_data['class']); | ||||
list ($listener_prefix, $listener_method) = explode(':', $rewrite_listener); | |||||
// don't use temp variable, since it will swap objects in Factory in PHP5 | |||||
$this->rewriteListeners[$prefix][$index] = Array (); | |||||
$this->rewriteListeners[$prefix][$index][0] = $this->Application->recallObject($listener_prefix); | |||||
$this->rewriteListeners[$prefix][$index][1] = $listener_method; | |||||
} | |||||
} | } | ||||
define('MOD_REWRITE_URL_ENDING', $this->Application->ConfigValue('ModRewriteUrlEnding')); | define('MOD_REWRITE_URL_ENDING', $this->Application->ConfigValue('ModRewriteUrlEnding')); | ||||
$init_done = true; | $init_done = true; | ||||
} | } | ||||
/** | /** | ||||
* Parses given string into a set of variables (url in this case) | * Parses given string into a set of variables (url in this case) | ||||
* | * | ||||
* @param string $string | * @param string $string | ||||
* @param string $pass_name | * @param string $pass_name | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Line(s) | |||||
$this->_parseTheme($url_parts, $vars); | $this->_parseTheme($url_parts, $vars); | ||||
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_page> | // http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_page> | ||||
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_page> (category-based section template) | // http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_page> (category-based section template) | ||||
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_item> | // http://site-url/<language>/<theme>/<category>[_<category_page>]/<template>/<module_item> | ||||
// http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_item> (category-based detail template) | // http://site-url/<language>/<theme>/<category>[_<category_page>]/<module_item> (category-based detail template) | ||||
// http://site-url/<language>/<theme>/<rl_injections>/<category>[_<category_page>]/<rl_part> (customized url) | // http://site-url/<language>/<theme>/<rl_injections>/<category>[_<category_page>]/<rl_part> (customized url) | ||||
if ( !$this->_processRewriteListeners($url_parts, $vars) ) { | if ( !$this->processRouters($url_parts, $vars) ) { | ||||
// rewrite listener wasn't able to determine template | // Routers weren't able to determine template. | ||||
$this->_parsePhysicalTemplate($url_parts, $vars); | $this->_parsePhysicalTemplate($url_parts, $vars); | ||||
if ( ($this->modulePrefix === false) && $vars['m_cat_id'] && !$this->_partsToParse ) { | if ( ($this->modulePrefix === false) && $vars['m_cat_id'] && !$this->_partsToParse ) { | ||||
// no category item found, but category found and all url matched -> module index page | // no category item found, but category found and all url matched -> module index page | ||||
return $vars; | return $vars; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Line(s) | |||||
foreach ($defaults as $default_key => $default_value) { | foreach ($defaults as $default_key => $default_value) { | ||||
if ($this->HTTPQuery->Get($default_key) === false) { | if ($this->HTTPQuery->Get($default_key) === false) { | ||||
$vars[$default_key] = $default_value; | $vars[$default_key] = $default_value; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Processes url using rewrite listeners | * Processes url using routers. | ||||
* | * | ||||
* Pattern: Chain of Command | * Pattern: Chain of Command | ||||
* | * | ||||
* @param Array $url_parts | * @param array $url_parts Url parts. | ||||
* @param Array $vars | * @param array $vars Vars. | ||||
* @return bool | * | ||||
* @access protected | * @return boolean | ||||
*/ | */ | ||||
protected function _processRewriteListeners(&$url_parts, &$vars) | protected function processRouters(array &$url_parts, array &$vars) | ||||
{ | { | ||||
$this->_initRewriteListeners(); | $this->initRouters(); | ||||
$page_number = $this->_parsePage($url_parts, $vars); | $page_number = $this->_parsePage($url_parts, $vars); | ||||
foreach ($this->rewriteListeners as $prefix => $listeners) { | foreach ( $this->routers as $prefix => $router ) { | ||||
// set default page | |||||
// $vars[$prefix . '_Page'] = 1; // will override page in session in case, when none is given in url | |||||
if ($page_number) { | if ( $page_number ) { | ||||
// page given in url - use it | // Page given in url - use it. | ||||
$vars[$prefix . '_id'] = 0; | $vars[$prefix . '_id'] = 0; | ||||
$vars[$prefix . '_Page'] = $page_number; | $vars[$prefix . '_Page'] = $page_number; | ||||
} | } | ||||
// $listeners[1] - listener, used for parsing | if ( $router->parse($url_parts, $vars) === false ) { | ||||
$listener_result = $listeners[1][0]->$listeners[1][1](REWRITE_MODE_PARSE, $prefix, $vars, $url_parts); | // Will not proceed to other methods. | ||||
if ($listener_result === false) { | |||||
// will not proceed to other methods | |||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
// will proceed to other methods | // Will proceed to other methods. | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* Set's page (when found) to all modules | * Set's page (when found) to all modules | ||||
* | * | ||||
* @param Array $url_parts | * @param Array $url_parts | ||||
* @param Array $vars | * @param Array $vars | ||||
* @return string | * @return string | ||||
* @access protected | * @access protected | ||||
* | * | ||||
* @todo Should find a way, how to determine what rewrite listener page is it | * @todo Should find a way, how to determine what router page is it. | ||||
*/ | */ | ||||
protected function _parsePage(&$url_parts, &$vars) | protected function _parsePage(&$url_parts, &$vars) | ||||
{ | { | ||||
if (!$url_parts) { | if (!$url_parts) { | ||||
return false; | return false; | ||||
} | } | ||||
$page_number = end($url_parts); | $page_number = end($url_parts); | ||||
▲ Show 20 Lines • Show All 377 Lines • ▼ Show 20 Line(s) | |||||
$catalog_item_found = false; | $catalog_item_found = false; | ||||
$pass_info = $this->getPassInfo($pass); | $pass_info = $this->getPassInfo($pass); | ||||
if ( $pass_info ) { | if ( $pass_info ) { | ||||
if ( $pass_info[0] == 'm' ) { | if ( $pass_info[0] == 'm' ) { | ||||
array_shift($pass_info); | array_shift($pass_info); | ||||
} | } | ||||
$inject_parts = Array (); // url parts for beginning of url | $inject_parts = array(); // Url parts for beginning of url. | ||||
$params['t'] = $t; // make template available for rewrite listeners | $params['t'] = $t; // Make template available for routers. | ||||
$params['pass_template'] = true; // by default we keep given template in resulting url | $params['pass_template'] = true; // By default we keep given template in resulting url. | ||||
if ( !array_key_exists('pass_category', $params) ) { | if ( !array_key_exists('pass_category', $params) ) { | ||||
$params['pass_category'] = false; // by default we don't keep categories in url | $params['pass_category'] = false; // by default we don't keep categories in url | ||||
} | } | ||||
foreach ($pass_info as $pass_index => $pass_element) { | foreach ($pass_info as $pass_index => $pass_element) { | ||||
list ($prefix) = explode('.', $pass_element); | list ($prefix) = explode('.', $pass_element); | ||||
$catalog_item = $this->Application->findModule('Var', $prefix) && $this->Application->getUnitConfig($prefix)->getCatalogItem(); | $catalog_item = $this->Application->findModule('Var', $prefix) && $this->Application->getUnitConfig($prefix)->getCatalogItem(); | ||||
if ( array_key_exists($prefix, $this->rewriteListeners) ) { | if ( array_key_exists($prefix, $this->routers) ) { | ||||
// if next prefix is same as current, but with special => exclude current prefix from url | // 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; | $next_prefix = array_key_exists($pass_index + 1, $pass_info) ? $pass_info[$pass_index + 1] : false; | ||||
if ( $next_prefix ) { | if ( $next_prefix ) { | ||||
$next_prefix = substr($next_prefix, 0, strlen($prefix) + 1); | $next_prefix = substr($next_prefix, 0, strlen($prefix) + 1); | ||||
if ( $prefix . '.' == $next_prefix ) { | if ( $prefix . '.' == $next_prefix ) { | ||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
// rewritten url part | // rewritten url part | ||||
$url_part = $this->BuildModuleEnv($pass_element, $params, $pass_events); | $url_part = $this->BuildModuleEnv($pass_element, $params, $pass_events); | ||||
if ( is_string($url_part) && $url_part ) { | if ( is_string($url_part) && $url_part ) { | ||||
$ret .= $url_part . '/'; | $ret .= $url_part . '/'; | ||||
if ( $catalog_item ) { | if ( $catalog_item ) { | ||||
// pass category later only for catalog items | // pass category later only for catalog items | ||||
$catalog_item_found = true; | $catalog_item_found = true; | ||||
} | } | ||||
} | } | ||||
elseif ( is_array($url_part) ) { | elseif ( is_array($url_part) ) { | ||||
// rewrite listener want to insert something at the beginning of url too | // Router want to insert something at the beginning of url too. | ||||
if ( $url_part[0] ) { | if ( $url_part[0] ) { | ||||
$inject_parts[] = $url_part[0]; | $inject_parts[] = $url_part[0]; | ||||
} | } | ||||
if ( $url_part[1] ) { | if ( $url_part[1] ) { | ||||
$ret .= $url_part[1] . '/'; | $ret .= $url_part[1] . '/'; | ||||
} | } | ||||
if ( $catalog_item ) { | if ( $catalog_item ) { | ||||
// pass category later only for catalog items | // pass category later only for catalog items | ||||
$catalog_item_found = true; | $catalog_item_found = true; | ||||
} | } | ||||
} | } | ||||
elseif ( $url_part === false ) { | elseif ( $url_part === false ) { | ||||
// rewrite listener decided not to rewrite given $pass_element | // Router decided not to rewrite given $pass_element. | ||||
$env .= ':' . $this->manager->plain->BuildModuleEnv($pass_element, $params, $pass_events); | $env .= ':' . $this->manager->plain->BuildModuleEnv($pass_element, $params, $pass_events); | ||||
} | } | ||||
} | } | ||||
else { | else { | ||||
$env .= ':' . $this->manager->plain->BuildModuleEnv($pass_element, $params, $pass_events); | $env .= ':' . $this->manager->plain->BuildModuleEnv($pass_element, $params, $pass_events); | ||||
} | } | ||||
} | } | ||||
if ( $catalog_item_found || preg_match('/c\.[-\d]*/', implode(',', $pass_info)) ) { | if ( $catalog_item_found || preg_match('/c\.[-\d]*/', implode(',', $pass_info)) ) { | ||||
// "c" prefix is present -> keep category | // "c" prefix is present -> keep category | ||||
$params['pass_category'] = true; | $params['pass_category'] = true; | ||||
} | } | ||||
$params['inject_parts'] = $inject_parts; | $params['inject_parts'] = $inject_parts; | ||||
$ret = $this->BuildModuleEnv('m', $params, $pass_events) . '/' . $ret; | $ret = $this->BuildModuleEnv('m', $params, $pass_events) . '/' . $ret; | ||||
$cat_processed = array_key_exists('category_processed', $params) && $params['category_processed']; | $cat_processed = array_key_exists('category_processed', $params) && $params['category_processed']; | ||||
// remove temporary parameters used by listeners | // Remove temporary parameters used by routers. | ||||
unset($params['t'], $params['inject_parts'], $params['pass_template'], $params['pass_category'], $params['category_processed']); | unset($params['t'], $params['inject_parts'], $params['pass_template'], $params['pass_category'], $params['category_processed']); | ||||
$ret = trim($ret, '/'); | $ret = trim($ret, '/'); | ||||
if ( isset($params['url_ending']) ) { | if ( isset($params['url_ending']) ) { | ||||
if ( $ret ) { | if ( $ret ) { | ||||
$ret .= $params['url_ending']; | $ret .= $params['url_ending']; | ||||
} | } | ||||
Show All 30 Lines | |||||
* @param bool $pass_events | * @param bool $pass_events | ||||
* @return string | * @return string | ||||
* @access protected | * @access protected | ||||
*/ | */ | ||||
protected function BuildModuleEnv($prefix_special, &$params, $pass_events = false) | protected function BuildModuleEnv($prefix_special, &$params, $pass_events = false) | ||||
{ | { | ||||
list ($prefix) = explode('.', $prefix_special); | list ($prefix) = explode('.', $prefix_special); | ||||
$url_parts = Array (); | return $this->routers[$prefix]->buildWrapper($prefix_special, $params, $pass_events); | ||||
$listener = $this->rewriteListeners[$prefix][0]; | |||||
$ret = $listener[0]->$listener[1](REWRITE_MODE_BUILD, $prefix_special, $params, $url_parts, $pass_events); | |||||
return $ret; | |||||
} | } | ||||
} | } |