Index: branches/5.0.x/core/kernel/application.php =================================================================== diff -u -r12277 -r12294 --- branches/5.0.x/core/kernel/application.php (.../application.php) (revision 12277) +++ branches/5.0.x/core/kernel/application.php (.../application.php) (revision 12294) @@ -1,6 +1,6 @@ +* This class is a Facade for any other class which needs to deal with Kernel4 framework.
* The class incapsulates the main run-cycle of the script, provide access to all other objects in the framework.
*
-* The class is a singleton, which means that there could be only one instance of KernelApplication in the script.
-* This could be guranteed by NOT calling the class constuctor directly, but rather calling KernelApplication::Instance() method, +* The class is a singleton, which means that there could be only one instance of kApplication in the script.
+* This could be guranteed by NOT calling the class constuctor directly, but rather calling kApplication::Instance() method, * which returns an instance of the application. The method gurantees that it will return exactly the same instance for any call.
* See singleton pattern by GOF. * @package kernel4 @@ -98,6 +98,13 @@ var $ReplacementTemplates = Array (); /** + * Mod-Rewrite listeners used during url building and parsing + * + * @var Array + */ + var $RewriteListeners = Array (); + + /** * Reference to debugger * * @var Debugger @@ -1466,15 +1473,28 @@ // $params = array_merge_recursive2($this->getPassThroughVariables($params), $params); $params = array_merge($this->getPassThroughVariables($params), $params); - if ($force_rewrite || ($this->RewriteURLs($ssl) && !$no_rewrite)) - { + if ($force_rewrite || ($this->RewriteURLs($ssl) && !$no_rewrite)) { + static $rewrite_listeners_done = false; + + if (!$rewrite_listeners_done) { + $mod_rewrite_helper =& $this->recallObject('ModRewriteHelper'); + /* @var $mod_rewrite_helper kModRewriteHelper */ + + $mod_rewrite_helper->initRewriteListeners(); + + $rewrite_listeners_done = true; + } + $session =& $this->recallObject('Session'); - if( $session->NeedQueryString() && !$force_no_sid ) $params['sid'] = $this->GetSID(); + + if ($session->NeedQueryString() && !$force_no_sid) { + $params['sid'] = $this->GetSID(); + } + $url = $this->BuildEnv_NEW($t, $params, $pass, $pass_events); $ret = $this->BaseURL($prefix, $ssl).$url.$map_link; } - else - { + 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->BaseURL($prefix, $ssl).$index_file.'?'.$env.$map_link; @@ -1547,7 +1567,7 @@ foreach ($pass_info as $prefix) { list($prefix_only) = explode('.', $prefix, 1); - $sorted[$prefix] = $this->getUnitOption($prefix_only, 'PassPriority', 0); + $sorted[$prefix] = $this->getUnitOption($prefix_only, 'RewritePriority', 0); } arsort($sorted); @@ -1573,8 +1593,8 @@ $env = ''; $encode = false; - if (isset($params['__URLENCODE__'])) - { + + if (isset($params['__URLENCODE__'])) { $encode = $params['__URLENCODE__']; unset($params['__URLENCODE__']); } @@ -1583,59 +1603,104 @@ unset($params['__SSL__']); } - $m_only = true; + $catalog_item_found = false; $pass_info = $this->getPassInfo($pass); + if ($pass_info) { - if ($pass_info[0] == 'm') array_shift($pass_info); - $params['t'] = $t; - foreach($pass_info as $pass_index => $pass_element) - { - list($prefix) = explode('.', $pass_element); - $require_rewrite = $this->findModule('Var', $prefix) && $this->getUnitOption($prefix, 'CatalogItem'); - if ($require_rewrite) { + 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->findModule('Var', $prefix) && $this->getUnitOption($prefix, 'CatalogItem'); + + if (array_key_exists($prefix, $this->RewriteListeners)) { // if next prefix is same as current, but with special => exclude current prefix from url - $next_prefix = getArrayValue($pass_info, $pass_index + 1); + $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; + if ($prefix . '.' == $next_prefix) { + continue; + } } - $a = $this->BuildModuleEnv_NEW($pass_element, $params, $pass_events); - if ($a) { - $ret .= '/'.$a; - $m_only = false; + + // 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); + else { + $env .= ':' . $this->BuildModuleEnv($pass_element, $params, $pass_events); } } - if (!$m_only || preg_match('/c\.[-\d]*/', implode(',', $pass_info))) { - $params['pass_category'] = 1; + if ($catalog_item_found || preg_match('/c\.[-\d]*/', implode(',', $pass_info))) { + // "c" prefix is present -> keep category + $params['pass_category'] = true; } - $ret = $this->BuildModuleEnv_NEW('m', $params, $pass_events).$ret; - $cat_processed = isset($params['category_processed']) && $params['category_processed']; - if ($cat_processed) { - unset($params['category_processed']); - } - if (!$m_only || !$cat_processed || !defined('EXP_DIR_URLS')) { - $ret = trim($ret, '/').'.html'; + $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']); + + if ($catalog_item_found || !$cat_processed || !defined('EXP_DIR_URLS')) { + // this catalog item detail page OR there is no category given + $ret = trim($ret, '/') . '.html'; } else { - $ret .= '/'; + // url ends with "/" and not with ".html" + $ret = trim($ret, '/') . '/'; } -// $ret = trim($ret, '/').'/'; - if($env) $params[ENV_VAR_NAME] = ltrim($env, ':'); + if ($env) { + $params[ENV_VAR_NAME] = ltrim($env, ':'); + } } unset($params['pass'], $params['opener'], $params['m_event']); - if ($force_admin) $params['admin'] = 1; + if ($force_admin) { + $params['admin'] = 1; + } - if( getArrayValue($params,'escape') ) - { + if (array_key_exists('escape', $params) && $params['escape']) { $ret = addslashes($ret); unset($params['escape']); } @@ -1644,30 +1709,31 @@ $params_str = ''; $join_string = $encode ? '&' : '&'; - foreach ($params as $param => $value) - { - $params_str .= $join_string.$param.'='.$value; + + foreach ($params as $param => $value) { + $params_str .= $join_string . $param . '=' . $value; } - $ret .= preg_replace('/^'.$join_string.'(.*)/', '?\\1', $params_str); + if ($params_str) { + $ret .= '?' . substr($params_str, strlen($join_string)); + } + if ($encode) { $ret = str_replace('\\', '%5C', $ret); } + return $ret; } - - function BuildModuleEnv_NEW($prefix_special, &$params, $pass_events = false) + function BuildModuleEnv_NEW($prefix_special, &$params, $keep_events = false) { - $event_params = Array('pass_events' => $pass_events, 'url_params' => $params); - $event = new kEvent($prefix_special.':BuildEnv', $event_params); - $this->HandleEvent($event); - $params = $event->getEventParam('url_params'); // save back unprocessed parameters + list ($prefix) = explode('.', $prefix_special); - $ret = ''; - if ($event->getEventParam('env_string')) { - $ret = trim( $event->getEventParam('env_string'), '/'); - } + $url_parts = Array (); + $listener = $this->RewriteListeners[$prefix]; + + $ret = $listener[0]->$listener[1](REWRITE_MODE_BUILD, $prefix_special, $params, $url_parts, $keep_events); + return $ret; }