Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Wed, Feb 5, 9:22 PM

in-portal

Index: branches/5.2.x/core/kernel/managers/rewrite_url_processor.php
===================================================================
--- branches/5.2.x/core/kernel/managers/rewrite_url_processor.php (revision 14736)
+++ branches/5.2.x/core/kernel/managers/rewrite_url_processor.php (revision 14737)
@@ -1,980 +1,983 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2011 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 kRewriteUrlProcessor extends kUrlProcessor {
/**
* Holds a reference to httpquery
*
* @var kHttpQuery
* @access protected
*/
protected $HTTPQuery = null;
/**
* Urls parts, that needs to be matched by rewrite listeners
*
* @var Array
* @access protected
*/
protected $_partsToParse = Array ();
/**
* Category item prefix, that was found
*
* @var string|bool
* @access public
*/
public $modulePrefix = false;
/**
* Template aliases for current theme
*
* @var Array
* @access protected
*/
protected $_templateAliases = null;
/**
* Domain-based primary language id
*
* @var int
* @access public
*/
public $primaryLanguageId = false;
/**
* Domain-based primary theme id
*
* @var int
* @access public
*/
public $primaryThemeId = false;
/**
* Possible url endings from ModRewriteUrlEnding configuration variable
*
* @var Array
*/
protected $_urlEndings = Array ('.html', '/', '');
/**
* Constructor of kRewriteUrlProcessor class
*
* @param $manager
* @return kRewriteUrlProcessor
*/
public function __construct(&$manager)
{
parent::__construct($manager);
$this->HTTPQuery =& $this->Application->recallObject('HTTPQuery');
// domain based primary language
$this->primaryLanguageId = $this->Application->siteDomainField('PrimaryLanguageId');
if (!$this->primaryLanguageId) {
// when domain-based language not found -> use site-wide language
$this->primaryLanguageId = $this->Application->GetDefaultLanguageId();
}
// domain based primary theme
$this->primaryThemeId = $this->Application->siteDomainField('PrimaryThemeId');
if (!$this->primaryThemeId) {
// when domain-based theme not found -> use site-wide theme
$this->primaryThemeId = $this->Application->GetDefaultThemeId(true);
}
$this->_initRewriteListeners();
}
/**
* Parses url
*
* @return void
*/
public function parseRewriteURL()
{
$url = $this->Application->GetVar('_mod_rw_url_');
if ($url) {
foreach ($this->_urlEndings as $url_ending) {
if (substr($url, strlen($url) - strlen($url_ending)) == $url_ending) {
$url = substr($url, 0, strlen($url) - strlen($url_ending));
$default_ending = $this->Application->ConfigValue('ModRewriteUrlEnding');
// user manually typed url with different url ending -> redirect to same url with default url ending
if (($url_ending != $default_ending) && $this->Application->ConfigValue('ForceModRewriteUrlEnding')) {
$target_url = $this->Application->BaseURL() . $url . $default_ending;
$this->Application->Redirect('external:' . $target_url, Array ('response_code' => 301));
}
break;
}
}
}
$cached = $this->_getCachedUrl($url);
if ( $cached !== false ) {
$vars = $cached['vars'];
$passed = $cached['passed'];
}
else {
$vars = $this->parse($url);
$passed = $vars['pass']; // also used in bottom of this method
unset($vars['pass']);
- $this->_setCachedUrl($url, Array ('vars' => $vars, 'passed' => $passed));
+ if ( !$this->_partsToParse ) {
+ // don't cache 404 Not Found
+ $this->_setCachedUrl($url, Array ('vars' => $vars, 'passed' => $passed));
+ }
if ( $this->Application->GetVarDirect('t', 'Post') ) {
// template from POST overrides template from URL.
$vars['t'] = $this->Application->GetVarDirect('t', 'Post');
if ( isset($vars['is_virtual']) && $vars['is_virtual'] ) {
$vars['m_cat_id'] = 0; // this is virtual template category (for Proj-CMS)
}
}
unset($vars['is_virtual']);
}
foreach ($vars as $name => $value) {
$this->HTTPQuery->Set($name, $value);
}
$this->_initAll(); // also will use parsed language to load phrases from it
$this->HTTPQuery->finalizeParsing($passed);
}
/**
* Returns url parsing result from cache or false, when not yet parsed
*
* @param $url
* @return Array|bool
* @access protected
*/
protected function _getCachedUrl($url)
{
if (!$url) {
return false;
}
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'CachedUrls
WHERE Hash = ' . crc32($url) . ' AND DomainId = ' . (int)$this->Application->siteDomainField('DomainId');
$data = $this->Conn->GetRow($sql);
if ($data) {
$lifetime = (int)$data['LifeTime']; // in seconds
if (($lifetime > 0) && ($data['Cached'] + $lifetime < adodb_mktime())) {
// delete expired
$sql = 'DELETE FROM ' . TABLE_PREFIX . 'CachedUrls
WHERE UrlId = ' . $data['UrlId'];
$this->Conn->Query($sql);
return false;
}
return unserialize($data['ParsedVars']);
}
return false;
}
/**
* Caches url
*
* @param string $url
* @param Array $data
* @return void
* @access protected
*/
protected function _setCachedUrl($url, $data)
{
if (!$url) {
return ;
}
$vars = $data['vars'];
$passed = $data['passed'];
sort($passed);
// get expiration
if ($vars['m_cat_id'] > 0) {
$sql = 'SELECT PageExpiration
FROM ' . TABLE_PREFIX . 'Category
WHERE CategoryId = ' . $vars['m_cat_id'];
$expiration = $this->Conn->GetOne($sql);
}
// get prefixes
$prefixes = Array ();
$m_index = array_search('m', $passed);
if ($m_index !== false) {
unset($passed[$m_index]);
if ($vars['m_cat_id'] > 0) {
$prefixes[] = 'c:' . $vars['m_cat_id'];
}
$prefixes[] = 'lang:' . $vars['m_lang'];
$prefixes[] = 'theme:' . $vars['m_theme'];
}
foreach ($passed as $prefix) {
if (array_key_exists($prefix . '_id', $vars) && is_numeric($vars[$prefix . '_id'])) {
$prefixes[] = $prefix . ':' . $vars[$prefix . '_id'];
}
else {
$prefixes[] = $prefix;
}
}
$fields_hash = Array (
'Url' => $url,
'Hash' => crc32($url),
'DomainId' => (int)$this->Application->siteDomainField('DomainId'),
'Prefixes' => $prefixes ? '|' . implode('|', $prefixes) . '|' : '',
'ParsedVars' => serialize($data),
'Cached' => adodb_mktime(),
'LifeTime' => isset($expiration) && is_numeric($expiration) ? $expiration : -1
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'CachedUrls');
}
/**
* Loads all registered rewrite listeners, so they could be quickly accessed later
*
* @access protected
*/
protected function _initRewriteListeners()
{
static $init_done = false;
if ($init_done || count($this->Application->RewriteListeners) == 0) {
// not initialized OR mod-rewrite url with missing config cache
return ;
}
foreach ($this->Application->RewriteListeners as $prefix => $listener_data) {
foreach ($listener_data['listener'] as $index => $rewrite_listener) {
list ($listener_prefix, $listener_method) = explode(':', $rewrite_listener);
$listener =& $this->Application->recallObject($listener_prefix);
$this->Application->RewriteListeners[$prefix][$index] = Array (&$listener, $listener_method);
}
}
define('MOD_REWRITE_URL_ENDING', $this->Application->ConfigValue('ModRewriteUrlEnding'));
$init_done = true;
}
/**
* Parses given string into a set of variables (url in this case)
*
* @param string $string
* @param string $pass_name
* @return Array
* @access public
*/
public function parse($string, $pass_name = 'pass')
{
$vars = Array ($pass_name => Array ('m'));
$url_parts = $string ? explode('/', trim(mb_strtolower($string, 'UTF-8'), '/')) : Array ();
$this->_partsToParse = $url_parts;
if ( ($this->HTTPQuery->Get('rewrite') == 'on') || !$url_parts ) {
$this->_setDefaultValues($vars);
}
if ( !$url_parts ) {
$this->_initAll();
$vars['t'] = $this->Application->UrlManager->getDefaultTemplate('');
return $vars;
}
else {
$vars['t'] = '';
}
$this->_parseLanguage($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>]/<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>]/<module_item> (category-based detail template)
// http://site-url/<language>/<theme>/<rl_injections>/<category>[_<category_page>]/<rl_part> (customized url)
if ( $this->_processRewriteListeners($url_parts, $vars) ) {
return $vars;
}
$this->_parsePhysicalTemplate($url_parts, $vars);
if ( ($this->modulePrefix === false) && $vars['m_cat_id'] && !$this->_partsToParse ) {
// no category item found, but category found and all url matched -> module index page
return $vars;
}
if ( $this->_partsToParse ) {
$not_found = $this->Application->ConfigValue('ErrorTemplate');
$vars['t'] = $not_found ? $not_found : 'error_notfound';
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$vars['m_cat_id'] = $themes_helper->getPageByTemplate($vars['t'], $vars['m_theme']);
header('HTTP/1.0 404 Not Found');
}
return $vars;
}
/**
* Initializes theme & language based on parse results
*
* @return void
* @access protected
*/
protected function _initAll()
{
$this->Application->VerifyThemeId();
$this->Application->VerifyLanguageId();
// no need, since we don't have any cached phrase IDs + nobody will use PhrasesCache::LanguageId soon
// $this->Application->Phrases->Init('phrases');
}
/**
* Sets default parsed values before actual url parsing (only, for empty url)
*
* @param Array $vars
* @access protected
*/
protected function _setDefaultValues(&$vars)
{
$defaults = Array (
'm_cat_id' => 0, // no category
'm_cat_page' => 1, // first category page
'm_opener' => 's', // stay on same page
't' => 'index' // main site page
);
if ($this->primaryLanguageId) {
// domain-based primary language
$defaults['m_lang'] = $this->primaryLanguageId;
}
if ($this->primaryThemeId) {
// domain-based primary theme
$defaults['m_theme'] = $this->primaryThemeId;
}
foreach ($defaults as $default_key => $default_value) {
if ($this->HTTPQuery->Get($default_key) === false) {
$vars[$default_key] = $default_value;
}
}
}
/**
* Processes url using rewrite listeners
*
* Pattern: Chain of Command
*
* @param Array $url_parts
* @param Array $vars
* @return bool
* @access protected
*/
protected function _processRewriteListeners(&$url_parts, &$vars)
{
$this->_initRewriteListeners();
$page_number = $this->_parsePage($url_parts, $vars);
foreach ($this->Application->RewriteListeners as $prefix => $listeners) {
// set default page
// $vars[$prefix . '_Page'] = 1; // will override page in session in case, when none is given in url
if ($page_number) {
// page given in url - use it
$vars[$prefix . '_id'] = 0;
$vars[$prefix . '_Page'] = $page_number;
}
// $listeners[1] - listener, used for parsing
$listener_result = $listeners[1][0]->$listeners[1][1](REWRITE_MODE_PARSE, $prefix, $vars, $url_parts);
if ($listener_result === false) {
// will not proceed to other methods
return true;
}
}
// will proceed to other methods
return false;
}
/**
* Set's page (when found) to all modules
*
* @param Array $url_parts
* @param Array $vars
* @return string
* @access protected
*
* @todo Should find a way, how to determine what rewrite listerner page is it
*/
protected function _parsePage(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$page_number = end($url_parts);
if (!is_numeric($page_number)) {
return false;
}
array_pop($url_parts);
$this->partParsed($page_number, 'rtl');
return $page_number;
}
/**
* Gets language part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
* @access protected
*/
protected function _parseLanguage(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$url_part = reset($url_parts);
$sql = 'SELECT LanguageId, IF(LOWER(PackName) = ' . $this->Conn->qstr($url_part) . ', 2, PrimaryLang) AS SortKey
FROM ' . TABLE_PREFIX . 'Language
WHERE Enabled = 1
ORDER BY SortKey DESC';
$language_info = $this->Conn->GetRow($sql);
if ($language_info && $language_info['LanguageId'] && $language_info['SortKey']) {
// primary language will be selected in case, when $url_part doesn't match to other's language pack name
// don't use next enabled language, when primary language is disabled
$vars['m_lang'] = $language_info['LanguageId'];
if ($language_info['SortKey'] == 2) {
// language was found by pack name
array_shift($url_parts);
$this->partParsed($url_part);
}
elseif ($this->primaryLanguageId) {
// use domain-based primary language instead of site-wide primary language
$vars['m_lang'] = $this->primaryLanguageId;
}
return true;
}
return false;
}
/**
* Gets theme part from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
protected function _parseTheme(&$url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
$url_part = reset($url_parts);
$sql = 'SELECT ThemeId, IF(LOWER(Name) = ' . $this->Conn->qstr($url_part) . ', 2, PrimaryTheme) AS SortKey, TemplateAliases
FROM ' . TABLE_PREFIX . 'Theme
WHERE Enabled = 1
ORDER BY SortKey DESC';
$theme_info = $this->Conn->GetRow($sql);
if ($theme_info && $theme_info['ThemeId'] && $theme_info['SortKey']) {
// primary theme will be selected in case, when $url_part doesn't match to other's theme name
// don't use next enabled theme, when primary theme is disabled
$vars['m_theme'] = $theme_info['ThemeId'];
if ($theme_info['TemplateAliases']) {
$this->_templateAliases = unserialize($theme_info['TemplateAliases']);
}
else {
$this->_templateAliases = Array ();
}
if ($theme_info['SortKey'] == 2) {
// theme was found by name
array_shift($url_parts);
$this->partParsed($url_part);
}
elseif ($this->primaryThemeId) {
// use domain-based primary theme instead of site-wide primary theme
$vars['m_theme'] = $this->primaryThemeId;
}
return true;
}
$vars['m_theme'] = 0; // required, because used later for category/template detection
return false;
}
/**
* Parses real template name from url
*
* @param Array $url_parts
* @param Array $vars
* @return bool
*/
protected function _parsePhysicalTemplate($url_parts, &$vars)
{
if (!$url_parts) {
return false;
}
do {
$template_path = implode('/', $url_parts);
$physical_template = $this->Application->getPhysicalTemplate($template_path);
if (($physical_template !== false) && (substr($physical_template, 0, 3) != 'id:')) {
// replace menu template name with it's actual template name on disk
list ($template_path) = explode(':', $physical_template, 2);
}
$t_parts['path'] = dirname($template_path) == '.' ? '' : '/' . dirname($template_path);
$t_parts['file'] = basename($template_path);
$sql = 'SELECT FileId
FROM ' . TABLE_PREFIX . 'ThemeFiles
WHERE (ThemeId = ' . $vars['m_theme'] . ') AND (FilePath = ' . $this->Conn->qstr($t_parts['path']) . ') AND (FileName = ' . $this->Conn->qstr($t_parts['file'] . '.tpl') . ')';
$template_found = $this->Conn->GetOne($sql);
if (!$template_found) {
array_shift($url_parts);
}
} while (!$template_found && $url_parts);
if ($template_found) {
$vars['t'] = $template_path;
$template_parts = explode('/', $template_path);
while ( $template_parts ) {
$this->partParsed( array_pop($template_parts), 'rtl' );
}
// 1. will damage actual category during category item review add process
// 2. will use "use_section" parameter of "m_Link" tag to gain same effect
// $themes_helper =& $this->Application->recallObject('ThemesHelper');
// /* @var $themes_helper kThemesHelper */
//
// $vars['m_cat_id'] = $themes_helper->getPageByTemplate($template_path, $vars['m_theme']);
return true;
}
return false;
}
/**
* Returns environment variable values for given prefix (uses directly given params, when available)
*
* @param string $prefix_special
* @param Array $params
* @param bool $keep_events
* @return Array
* @access public
*/
public function getProcessedParams($prefix_special, &$params, $keep_events)
{
list ($prefix) = explode('.', $prefix_special);
$query_vars = $this->Application->getUnitOption($prefix, 'QueryString', Array ());
/* @var $query_vars Array */
if ( !$query_vars ) {
// given prefix doesn't use "env" variable to pass it's data
return false;
}
$event_key = array_search('event', $query_vars);
if ( $event_key ) {
// pass through event of this prefix
unset($query_vars[$event_key]);
}
if ( array_key_exists($prefix_special . '_event', $params) && !$params[$prefix_special . '_event'] ) {
// if empty event, then remove it from url
unset($params[$prefix_special . '_event']);
}
// if pass events is off and event is not implicity passed
if ( !$keep_events && !array_key_exists($prefix_special . '_event', $params) ) {
unset($params[$prefix_special . '_event']); // remove event from url if requested
//otherwise it will use value from get_var
}
$processed_params = Array ();
foreach ($query_vars as $var_name) {
// if value passed in params use it, otherwise use current from application
$var_name = $prefix_special . '_' . $var_name;
$processed_params[$var_name] = array_key_exists($var_name, $params) ? $params[$var_name] : $this->Application->GetVar($var_name);
if ( array_key_exists($var_name, $params) ) {
unset($params[$var_name]);
}
}
return $processed_params;
}
/**
* Returns module item details template specified in given category custom field for given module prefix
*
* @param int|Array $category
* @param string $module_prefix
* @return string
* @access public
* @todo Move to kPlainUrlProcessor
*/
public function GetItemTemplate($category, $module_prefix)
{
$category_id = is_array($category) ? $category['CategoryId'] : $category;
$cache_key = __CLASS__ . '::' . __FUNCTION__ . '[%CIDSerial:' . $category_id . '%]:' . $module_prefix;
$cached_value = $this->Application->getCache($cache_key);
if ($cached_value !== false) {
return $cached_value;
}
if (!is_array($category)) {
if ($category == 0) {
$category = $this->Application->findModule('Var', $module_prefix, 'RootCat');
}
$sql = 'SELECT c.ParentPath, c.CategoryId
FROM ' . TABLE_PREFIX . 'Category AS c
WHERE c.CategoryId = ' . $category;
$category = $this->Conn->GetRow($sql);
}
$parent_path = implode(',',explode('|', substr($category['ParentPath'], 1, -1)));
// item template is stored in module' system custom field - need to get that field Id
$primary_lang = $this->Application->GetDefaultLanguageId();
$item_template_field_id = $this->getItemTemplateCustomField($module_prefix);
// looking for item template through cats hierarchy sorted by parent path
$query = ' SELECT ccd.l' . $primary_lang . '_cust_' . $item_template_field_id . ',
FIND_IN_SET(c.CategoryId, ' . $this->Conn->qstr($parent_path) . ') AS Ord1,
c.CategoryId, c.Name, ccd.l' . $primary_lang . '_cust_' . $item_template_field_id . '
FROM ' . TABLE_PREFIX . 'Category AS c
LEFT JOIN ' . TABLE_PREFIX . 'CategoryCustomData AS ccd
ON ccd.ResourceId = c.ResourceId
WHERE c.CategoryId IN (' . $parent_path . ') AND ccd.l' . $primary_lang . '_cust_' . $item_template_field_id . ' != \'\'
ORDER BY FIND_IN_SET(c.CategoryId, ' . $this->Conn->qstr($parent_path) . ') DESC';
$item_template = $this->Conn->GetOne($query);
if (!isset($this->_templateAliases)) {
// when empty url OR mod-rewrite disabled
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$sql = 'SELECT TemplateAliases
FROM ' . TABLE_PREFIX . 'Theme
WHERE ThemeId = ' . (int)$themes_helper->getCurrentThemeId();
$template_aliases = $this->Conn->GetOne($sql);
$this->_templateAliases = $template_aliases ? unserialize($template_aliases) : Array ();
}
if ($item_template && array_key_exists($item_template, $this->_templateAliases)) {
$item_template = $this->_templateAliases[$item_template];
}
$this->Application->setCache($cache_key, $item_template);
return $item_template;
}
/**
* Returns category custom field id, where given module prefix item template name is stored
*
* @param string $module_prefix
* @return int
* @access public
* @todo Move to kPlainUrlProcessor; decrease visibility, since used only during upgrade
*/
public function getItemTemplateCustomField($module_prefix)
{
$cache_key = __CLASS__ . '::' . __FUNCTION__ . '[%CfSerial%]:' . $module_prefix;
$cached_value = $this->Application->getCache($cache_key);
if ($cached_value !== false) {
return $cached_value;
}
$sql = 'SELECT CustomFieldId
FROM ' . TABLE_PREFIX . 'CustomField
WHERE FieldName = ' . $this->Conn->qstr($module_prefix . '_ItemTemplate');
$item_template_field_id = $this->Conn->GetOne($sql);
$this->Application->setCache($cache_key, $item_template_field_id);
return $item_template_field_id;
}
/**
* Marks url part as parsed
*
* @param string $url_part
* @param string $parse_direction
* @access public
*/
public function partParsed($url_part, $parse_direction = 'ltr')
{
if ( !$this->_partsToParse ) {
return ;
}
if ( $parse_direction == 'ltr' ) {
$expected_url_part = reset($this->_partsToParse);
if ( $url_part == $expected_url_part ) {
array_shift($this->_partsToParse);
}
}
else {
$expected_url_part = end($this->_partsToParse);
if ( $url_part == $expected_url_part ) {
array_pop($this->_partsToParse);
}
}
if ( $url_part != $expected_url_part ) {
trigger_error('partParsed: expected URL part "<strong>' . $expected_url_part . '</strong>", received URL part "<strong>' . $url_part . '</strong>"', E_USER_NOTICE);
}
}
/**
* Builds url
*
* @param string $t
* @param Array $params
* @param string $pass
* @param bool $pass_events
* @param bool $env_var
* @return string
* @access public
*/
public function build($t, $params, $pass = 'all', $pass_events = false, $env_var = 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;
}
}
// rewritten url part
$url_part = $this->BuildModuleEnv($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->manager->plain->BuildModuleEnv($pass_element, $params, $pass_events);
}
}
else {
$env .= ':' . $this->manager->plain->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('m', $params, $pass_events) . '/' . $ret;
$cat_processed = array_key_exists('category_processed', $params) && $params['category_processed'];
// remove temporary 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 ? '&' : '&amp;';
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);
$url_parts = Array ();
$listener = $this->Application->RewriteListeners[$prefix][0];
$ret = $listener[0]->$listener[1](REWRITE_MODE_BUILD, $prefix_special, $params, $url_parts, $pass_events);
return $ret;
}
}
\ No newline at end of file

Event Timeline