(customized url)
if ( !$this->_processRewriteListeners($url_parts, $vars) ) {
// rewrite listener wasn't able to determine template
$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 ) {
$vars = array_merge($vars, $this->manager->prepare404($vars['m_theme']));
}
return $vars;
}
/**
* Ensures, that "m" is always in "pass" variable
*
* @param Array $vars
* @param string $pass_name
* @return void
* @access protected
*/
protected function _fixPass(&$vars, $pass_name)
{
if ( isset($vars[$pass_name]) ) {
$vars[$pass_name] = array_unique(explode(',', 'm,' . $vars[$pass_name]));
}
else {
$vars[$pass_name] = Array ('m');
}
}
/**
* 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
+ // No need, since we don't have any cached phrase IDs + nobody will use kPhraseCache::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->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 listener 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 . 'Languages
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 . 'Themes
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;
}
$themes_helper = $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
do {
$index_added = false;
$template_path = implode('/', $url_parts);
$template_found = $themes_helper->getTemplateId($template_path, $vars['m_theme']);
if ( !$template_found ) {
$index_added = true;
$template_found = $themes_helper->getTemplateId($template_path . '/index', $vars['m_theme']);
}
if ( !$template_found ) {
array_shift($url_parts);
}
} while ( !$template_found && $url_parts );
if ( $template_found ) {
$template_parts = explode('/', $template_path);
$vars['t'] = $template_path . ($index_added ? '/index' : '');
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
// $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->getUnitConfig($prefix)->getQueryString(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
* @param int $theme_id
* @return string
* @access public
* @todo Move to kPlainUrlProcessor
*/
public function GetItemTemplate($category, $module_prefix, $theme_id = null)
{
if ( !isset($theme_id) ) {
$theme_id = $this->Application->GetVar('m_theme');
}
$category_id = is_array($category) ? $category['CategoryId'] : $category;
$cache_key = __CLASS__ . '::' . __FUNCTION__ . '[%CIDSerial:' . $category_id . '%][%ThemeIDSerial:' . $theme_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 . 'Categories 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 . 'Categories 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 . 'Themes
WHERE ThemeId = ' . (int)$themes_helper->getCurrentThemeId();
$template_aliases = $this->Conn->GetOne($sql);
$this->_templateAliases = $template_aliases ? unserialize($template_aliases) : Array ();
}
if ( substr($item_template, 0, 1) == '#' ) {
// it's template alias + "#" isn't allowed in filenames
$item_template = (string)getArrayValue($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 . 'CustomFields
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 "' . $expected_url_part . '", received URL part "' . $url_part . '"', E_USER_NOTICE);
}
}
/**
* Determines if there is more to parse in url
*
* @return bool
* @access public
*/
public function moreToParse()
{
return count($this->_partsToParse) > 0;
}
/**
* 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 = '';
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->getUnitConfig($prefix)->getCatalogItem();
if ( array_key_exists($prefix, $this->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']);
// TODO: why?
// $ret = str_replace('%2F', '/', urlencode($ret));
if ( $params ) {
$params_str = http_build_query($params);
$ret .= '?' . str_replace('%23', '#', $params_str);
}
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->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
+}
Index: branches/5.3.x/core/kernel/managers/plain_url_processor.php
===================================================================
--- branches/5.3.x/core/kernel/managers/plain_url_processor.php (revision 16155)
+++ branches/5.3.x/core/kernel/managers/plain_url_processor.php (revision 16156)
@@ -1,263 +1,263 @@
$this->manager->getTemplateName());
}
parse_str(ENV_VAR_NAME . '=' . $env_var, $vars);
$env_var = $vars[ENV_VAR_NAME];
unset($vars[ENV_VAR_NAME]);
// replace escaped ":" symbol not to explode by it
$env_var = str_replace('\:', '_&+$$+&_', $env_var); // replace escaped "=" with spec-chars :)
$parts = explode(':', $env_var);
if ( !$this->Application->RewriteURLs() || ($this->Application->RewriteURLs() && $this->Application->GetVar('rewrite') != 'on') ) {
$vars = array_merge($vars, $this->extractSIDAndTemplate($parts));
}
if ( $parts ) {
$passed = Array ();
foreach ($parts as $mixed_part) {
list ($passed[], $processed_vars) = $this->_parseEnvPart($mixed_part);
$vars = array_merge($vars, $processed_vars);
}
$vars[$pass_name] = implode(',', array_unique($passed));
}
return $vars;
}
/**
* Retrieves SessionID and current template from given ENV parts
*
* @param Array $parts
* @return array
* @access protected
*/
protected function extractSIDAndTemplate(&$parts)
{
$template = '';
$vars = Array ();
if ( preg_match('/^([\d]+|)-(.*)$/', $parts[0], $regs) ) {
// first "env" component matches "sid-template" format
// (will be false, when mod-rewrite url to home page is built)
$sid = $regs[1];
$template = $regs[2];
array_shift($parts);
if ( $sid ) {
// Save Session ID
$this->Application->SetVar('sid', $sid);
$vars['sid'] = $sid;
}
}
// Save Template Name
$vars['t'] = $this->manager->getTemplateName($template);
return $vars;
}
/**
* Converts environment part into variable array (based on query map for given prefix)
*
* @param string $mixed_part
* @return Array
* @access protected
*/
protected function _parseEnvPart($mixed_part)
{
// In-portal old style env conversion - adds '-' between prefix and first var
$mixed_part = str_replace('_&+$$+&_', ':', $mixed_part);
$mixed_part = preg_replace("/^([a-zA-Z]+)([0-9]+)-(.*)/", "$1-$2-$3", $mixed_part);
// replace escaped "-" symbol not to explode by it
$escaped_part = str_replace('\-', '_&+$$+&_', $mixed_part);
$escaped_part = explode('-', $escaped_part);
$mixed_part = Array();
foreach ($escaped_part as $escaped_val) {
$mixed_part[] = str_replace('_&+$$+&_', '-', $escaped_val);
}
$vars = Array ();
$prefix_special = array_shift($mixed_part); // l.pick, l
- $http_query = $this->Application->recallObject('HTTPQuery');
+ $http_query = $this->Application->recallObject('kHTTPQuery');
/* @var $http_query kHTTPQuery */
$query_map = $http_query->discoverUnit($prefix_special); // from $_GET['env']
// if config is not defined for prefix in QueryString, then don't process it
if ($query_map) {
foreach ($query_map as $index => $var_name) {
// l_id, l_page, l_bla-bla-bla
$val = $mixed_part[$index - 1];
if ($val == '') $val = false;
$vars[$prefix_special.'_'.$var_name] = $val;
}
}
return Array ($prefix_special, $vars);
}
/**
* 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 = true)
{
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;
}
}
$ssl = isset($params['__SSL__']) ? $params['__SSL__'] : 0;
$sid = isset($params['sid']) && !$this->Application->RewriteURLs($ssl) ? $params['sid'] : '';
if ( isset($params['__SSL__']) ) {
unset($params['__SSL__']);
}
$env_string = '';
$category_id = isset($params['m_cat_id']) ? $params['m_cat_id'] : $this->Application->GetVar('m_cat_id');
$item_id = false;
$pass_info = $this->getPassInfo($pass);
if ( $pass_info ) {
if ( $pass_info[0] == 'm' ) {
array_shift($pass_info);
}
foreach ($pass_info as $pass_element) {
list($prefix) = explode('.', $pass_element);
$require_rewrite = $this->Application->findModule('Var', $prefix);
if ( $require_rewrite ) {
$item_id = isset($params[$pass_element . '_id']) ? $params[$pass_element . '_id'] : $this->Application->GetVar($pass_element . '_id');
}
$env_string .= ':' . $this->BuildModuleEnv($pass_element, $params, $pass_events);
}
}
if ( strtolower($t) == '__default__' ) {
if ( is_numeric($item_id) ) {
$this->manager->initRewrite();
$t = $this->manager->rewrite->GetItemTemplate($category_id, $pass_element); // $pass_element should be the last processed element
// $t = $this->Application->getCategoryCache($category_id, 'item_templates');
}
elseif ( $category_id ) {
$t = strtolower(preg_replace('/^Content\//i', '', $this->Application->getCategoryCache($category_id, 'filenames')));
}
else {
$t = 'index';
}
}
$env_string = $sid . '-' . $t . ':' . $this->BuildModuleEnv('m', $params, $pass_events) . $env_string;
unset($params['pass'], $params['opener'], $params['m_event']);
$params = array(ENV_VAR_NAME => $env_string) + $params;
$params_str = http_build_query($params);
$ret = str_replace('%23', '#', $params_str);
if ( !$env_var ) {
$ret = substr($ret, strlen(ENV_VAR_NAME) + 1);
}
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 public
*/
public function BuildModuleEnv($prefix_special, &$params, $pass_events = false)
{
list($prefix) = explode('.', $prefix_special);
$config = $this->Application->getUnitConfig($prefix);
$query_vars = $config->getQueryString(Array ());
//if pass events is off and event is not implicitly passed
if ( !$pass_events && !isset($params[$prefix_special . '_event']) ) {
$params[$prefix_special . '_event'] = ''; // remove event from url if requested
//otherwise it will use value from get_var
}
if ( !$query_vars ) {
return '';
}
$tmp_string = Array (0 => $prefix_special);
foreach ($query_vars as $index => $var_name) {
//if value passed in params use it, otherwise use current from application
$var_name = $prefix_special . '_' . $var_name;
$tmp_string[$index] = isset($params[$var_name]) ? $params[$var_name] : $this->Application->GetVar($var_name);
if ( isset($params[$var_name]) ) {
unset($params[$var_name]);
}
}
$escaped = array ();
foreach ($tmp_string as $tmp_val) {
$escaped[] = str_replace(Array ('-', ':'), Array ('\-', '\:'), $tmp_val);
}
$ret = implode('-', $escaped);
if ( $config->getPortalStyleEnv() == true ) {
$ret = preg_replace('/^([a-zA-Z]+)-([0-9]+)-(.*)/', '\\1\\2-\\3', $ret);
}
return $ret;
}
-}
\ No newline at end of file
+}
Index: branches/5.3.x/core/kernel/processors/main_processor.php
===================================================================
--- branches/5.3.x/core/kernel/processors/main_processor.php (revision 16155)
+++ branches/5.3.x/core/kernel/processors/main_processor.php (revision 16156)
@@ -1,1292 +1,1292 @@
Application->recallObject('kActions');
/* @var $actions Params */
$actions->Set('t', $this->Application->GetVar('t'));
$actions->Set('sid', $this->Application->GetSID());
$actions->Set('m_opener', $this->Application->GetVar('m_opener') );
}
/**
* Base folder for all template includes
*
* @param Array $params
* @return string
*/
function TemplatesBase($params)
{
static $cached = Array ();
$cache_key = crc32( serialize($params) );
if (!array_key_exists($cache_key, $cached)) {
$module = array_key_exists('module', $params) ? $params['module'] : 'core';
if ($this->Application->isAdmin) {
if ($module == 'in-portal') {
$module = 'kernel';
}
// remove leading slash + substitute module
$module_path = $this->Application->findModule('Name', $module, 'Path');
if ($module_path !== false) {
$path = $module_path . 'admin_templates';
}
else {
// remove leading slash + substitute module
$path = preg_replace('/\/(.*?)\/(.*)/', $module . '/\\2', THEMES_PATH);
}
}
else {
$path = mb_substr(THEMES_PATH, 1);
if (mb_strtolower($module) == 'in-portal') {
$module_folder = 'platform';
}
else {
$module_folder = $this->Application->findModule('Name', $module, 'TemplatePath');
}
$path .= rtrim('/' . trim($module_folder, '/'), '/') . '/';
}
$cached[$cache_key] = $this->Application->BaseURL() . $path;
}
return $cached[$cache_key];
}
/**
* Creates HTML tag for all templates
* affects future css, js files and href params of links
*
* @param Array $params
* @return string
* @access protected
* @see kMainTagProcessor::TemplatesBase
*/
protected function Base_Ref($params)
{
// tag TemplatesBase adds trailing "/" but only on Front-End
$base_href = rtrim($this->TemplatesBase($params), '/');
return '';
}
/**
* Returns base url for web-site
*
* @return string
* @access public
*/
function BaseURL()
{
return $this->Application->BaseURL();
}
//for compatability with K3 tags
function Base($params)
{
return $this->TemplatesBase($params).'/';
}
function ProjectBase($params)
{
return $this->Application->BaseURL();
}
/*function Base($params)
{
return $this->Application->BaseURL().$params['add'];
}*/
/**
* Used to create link to any template.
* use "pass" paramter if "t" tag to specify
* prefix & special of object to be represented
* in resulting url
*
* @param Array $params
* @return string
* @access public
*/
function T($params)
{
// by default link to current template
$template = $this->SelectParam($params, 't,template');
$prefix = array_key_exists('prefix', $params) ? $params['prefix'] : '';
unset($params['t'], $params['template'], $params['prefix']);
$no_html_escape = false;
if ( isset($params['no_amp']) ) {
$no_html_escape = $params['no_amp'];
unset($params['no_amp']);
}
$ret = $this->Application->HREF($template, $prefix, $params);
if ( !$no_html_escape ) {
// most of the time links are placed into HTML document
// TODO: in future always do escaping according to current "escape context"
$ret = kUtil::escape($ret, kUtil::ESCAPE_HTML);
}
return $ret;
}
function Link($params)
{
// pass "m" prefix, instead of "all", that is by default on Front-End
if (!array_key_exists('pass', $params)) {
$params['pass'] = 'm';
}
return $this->T($params);
}
/**
* Performs redirect to provided template/url
*
* @param Array $params
* @return string
*/
function Redirect($params)
{
$this->Application->Redirect('external:' . $this->Link($params));
return '';
}
/*function Env($params)
{
$t = $params['template'];
unset($params['template']);
return $this->Application->BuildEnv($t, $params, 'm', false, false);
}*/
function FormAction($params)
{
if (!array_key_exists('pass', $params)) {
$params['pass'] = 'all,m';
}
$params['pass_category'] = 1;
return $this->Application->HREF('', '', $params);
}
/*// NEEDS TEST
function Config($params)
{
return $this->Application->ConfigOption($params['var']);
}
function Object($params)
{
$name = $params['name'];
$method = $params['method'];
$tmp = $this->Application->recallObject($name);
if ($tmp != null) {
if (method_exists($tmp, $method))
return $tmp->$method($params);
else
echo "Method $method does not exist in object ".get_class($tmp)." named $name
";
}
else
echo "Object $name does not exist in the appliaction
";
}*/
/**
* Tag, that always returns true.
* For parser testing purposes
*
* @param Array $params
* @return bool
* @access public
*/
function True($params)
{
return true;
}
/**
* Tag, that always returns false.
* For parser testing purposes
*
* @param Array $params
* @return bool
* @access public
*/
function False($params)
{
return false;
}
/**
* Returns block parameter by name (used only as "check" parameter value for "m_if" tag!)
*
* @param Array $params
* @return stirng
* @access public
*/
function Param($params)
{
$name = $params['name'];
if (array_key_exists($name, $this->Application->Parser->Captures)) {
$capture_params = $params;
$capture_params['name'] = '__capture_' . $name;
$this->Application->Parser->SetParam($name, $this->Application->ParseBlock($capture_params));
}
$res = $this->Application->Parser->GetParam($name);
if ($res === false) {
$res = '';
}
if (array_key_exists('plus', $params)) {
$res += $params['plus'];
}
return $res;
}
/**
* Compares block parameter with value specified
*
* @param Array $params
* @return bool
* @access public
*/
function ParamEquals($params)
{
$name = $this->SelectParam($params, 'name,var,param');
$value = $params['value'];
return ($this->Application->Parser->GetParam($name) == $value);
}
/*function PHP_Self($params)
{
return $HTTP_SERVER_VARS['PHP_SELF'];
}
*/
/**
* Returns session variable value by name
*
* @param Array $params
* @return string
* @access public
*/
function Recall($params)
{
$var_name = $this->SelectParam($params,'name,var,param');
if (isset($params['persistent']) && $params['persistent']) {
$ret = $this->Application->RecallPersistentVar($var_name);
}
else {
$ret = $this->Application->RecallVar($var_name);
}
$ret = ($ret === false && isset($params['no_null'])) ? '' : $ret;
if (getArrayValue($params, 'special') || getArrayValue($params, 'htmlchars')) {
$ret = kUtil::escape($ret, kUtil::ESCAPE_HTML);
}
if (getArrayValue($params, 'urlencode')) {
$ret = kUtil::escape($ret, kUtil::ESCAPE_URL);
}
return $ret;
}
function RemoveVar($params)
{
$this->Application->RemoveVar( $this->SelectParam($params,'name,var,param') );
}
// bad style to store something from template to session !!! (by Alex)
// Used here only to test how session works, nothing more
function Store($params)
{
//echo"Store $params[name]
";
$name = $params['name'];
$value = $params['value'];
$this->Application->StoreVar($name,$value);
}
/**
* Links variable from request with variable from session
*
* @param Array $params
* @return string
* @access protected
*/
protected function LinkVar($params)
{
$var_name = $params['name'];
$session_var_name = isset($params['session_name']) ? $params['session_name'] : $var_name;
$default_value = isset($params['default']) ? $params['default'] : '';
$this->Application->LinkVar($var_name, $session_var_name, $default_value);
return '';
}
/**
* Links variable from request with variable from session and returns it's value
*
* @param Array $params
* @return string
* @access protected
*/
protected function GetLinkedVar($params)
{
$this->LinkVar($params);
return $this->Application->GetVar( $params['name'] );
}
/**
* Sets application variable value(-s)
*
* @param Array $params
* @access public
*/
function Set($params)
{
foreach ($params as $param => $value) {
$this->Application->SetVar($param, $value);
}
}
/**
* Increment application variable
* specified by number specified
*
* @param Array $params
* @access public
*/
function Inc($params)
{
$this->Application->SetVar($params['param'], $this->Application->GetVar($params['param']) + $params['by']);
}
/**
* Retrieves application variable
* value by name
*
* @param Array $params
* @return string
* @access public
*/
function Get($params)
{
$name = $this->SelectParam($params, 'name,var,param');
if ( strpos($name, '[') !== false ) {
preg_match('/([^\[\]]+)\[(.*)\]/', $name, $regs);
$function_params = explode('][', $regs[2]);
$ret = $this->Application->GetVar($regs[1], array());
kUtil::array_unshift_ref($function_params, $ret);
$ret = call_user_func_array('getArrayValue', $function_params);
}
else {
$ret = $this->Application->GetVar($name, '');
}
if ( array_key_exists('no_html_escape', $params) && $params['no_html_escape'] ) {
return $this->Application->isAdmin ? $ret : kUtil::unescape($ret, kUtil::ESCAPE_HTML);
}
return kUtil::escape($ret, kUtil::ESCAPE_HTML);
}
/**
* Retrieves application constant
* value by name
*
* @param Array $params
* @return string
* @access public
*/
function GetConst($params)
{
$constant_name = $this->SelectParam($params, 'name,const');
return defined($constant_name) ? constant($constant_name) : '';
}
/**
* Retrieves configuration variable value by name
*
* @param Array $params
* @return string
* @access public
*/
function GetConfig($params)
{
$config_name = $this->SelectParam($params, 'name,var');
$ret = $this->Application->ConfigValue($config_name);
if ( isset($params['formatted']) && $params['formatted'] ) {
$sql = 'SELECT ValueList
FROM ' . TABLE_PREFIX . 'SystemSettings
WHERE VariableName = ' . $this->Conn->qstr($config_name) . ' AND ElementType IN ("select", "radio")';
$value_list = $this->Conn->GetOne($sql);
if ( $value_list ) {
$helper = $this->Application->recallObject('InpCustomFieldsHelper');
/* @var $helper InpCustomFieldsHelper */
$options = $helper->GetValuesHash($value_list);
$ret = isset($options[$ret]) ? $options[$ret] : $ret;
}
}
if ( isset($params['as_label']) && $params['as_label'] ) {
$ret = $this->Application->Phrase($ret);
}
return $ret;
}
/**
* Compares configuration variable to a given value
*
* @param Array $params
* @return bool
* @deprecated
* @access protected
*/
protected function ConfigEquals($params)
{
$option = $this->SelectParam($params, 'name,option,var');
return $this->Application->ConfigValue($option) == $params['value'];
}
/**
* Creates all hidden fields
* needed for kernel_form
*
* @param Array $params
* @return string
* @access protected
*/
protected function DumpSystemInfo($params)
{
$actions = $this->Application->recallObject('kActions');
/* @var $actions Params */
$actions->Set('t', $this->Application->GetVar('t'));
$o = '';
$params = $actions->GetParams();
foreach ($params AS $name => $val) {
$o .= "\n";
}
return $o;
}
/**
* Used for search sidebox on front-end only
*
* @param Array $params
* @return string
* @access protected
*/
protected function GetFormHiddens($params)
{
$t = $this->SelectParam($params, 'template,t');
unset($params['template']);
$form_fields = Array ();
if ( $this->Application->RewriteURLs() ) {
$session = $this->Application->recallObject('Session');
/* @var $session Session */
if ( $session->NeedQueryString() ) {
$form_fields['sid'] = $this->Application->GetSID();
}
}
else {
$form_fields['env'] = $this->Application->BuildEnv($t, $params, 'm', false, false);
}
if ( $this->Application->GetVar('admin') == 1 ) {
$form_fields['admin'] = 1;
}
$ret = '';
$field_tpl = '' . "\n";
foreach ($form_fields as $form_field => $field_value) {
$ret .= sprintf($field_tpl, $form_field, $field_value);
}
return $ret;
}
function Odd_Even($params)
{
$odd = $params['odd'];
$even = $params['even'];
if (!isset($params['var'])) {
$var = 'odd_even';
}
else {
$var = $params['var'];
}
if ($this->Application->GetVar($var) == 'even') {
if (!isset($params['readonly']) || !$params['readonly']) {
$this->Application->SetVar($var, 'odd');
}
return $even;
}
else {
if (!isset($params['readonly']) || !$params['readonly']) {
$this->Application->SetVar($var, 'even');
}
return $odd;
}
}
/**
* Returns phrase translation by name
*
* @param Array $params
* @return string
* @access public
*/
function Phrase($params)
{
$phrase_name = $this->SelectParam($params, 'label,name,title');
$default_translation = $this->SelectParam($params, 'default');
$no_editing = isset($params['no_editing']) && $params['no_editing'];
$translation = $this->Application->Phrase($phrase_name, !$no_editing);
$phrase_key = mb_strtoupper($phrase_name);
if ( $default_translation && strpos($translation, '!' . $phrase_key . '!') !== false ) {
$phrase = $this->Application->recallObject('phrases.autocreate', null, Array ('skip_autoload' => true));
/* @var $phrase kDBItem */
if ( !$phrase->Load($phrase_key, 'PhraseKey') ) {
$phrase->SetDBField('Phrase', $phrase_name);
$ml_helper = $this->Application->recallObject('kMultiLanguageHelper');
/* @var $ml_helper kMultiLanguageHelper */
$languages = $ml_helper->getLanguages();
foreach ($languages AS $language_id) {
$phrase->SetDBField('l' . $language_id . '_Translation', $default_translation);
}
if ( $phrase->Create() ) {
$translation = $default_translation;
}
}
}
if ( isset($params['escape']) && $params['escape'] ) {
// html escaping here is redundant
$translation = kUtil::escape($translation, kUtil::ESCAPE_JS);
}
return $translation;
}
// for tabs
function is_active($params)
{
$test_templ = $this->SelectParam($params, 'templ,template,t');
if ( !getArrayValue($params, 'allow_empty') ) {
$if_true = getArrayValue($params, 'true') ? $params['true'] : 1;
$if_false = getArrayValue($params, 'false') ? $params['false'] : 0;
}
else {
$if_true = $params['true'];
$if_false = $params['false'];
}
$physical_template = $this->Application->getPhysicalTemplate($this->Application->GetVar('t'));
return preg_match('/^' . str_replace('/', '\/', $test_templ) . '/i', $physical_template) ? $if_true : $if_false;
}
function IsNotActive($params)
{
return !$this->is_active($params);
}
function IsActive($params)
{
return $this->is_active($params);
}
function is_t_active($params)
{
return $this->is_active($params);
}
function CurrentTemplate($params)
{
return $this->is_active($params);
}
/**
* Checks if session variable
* specified by name value match
* value passed as parameter
*
* @param Array $params
* @return string
* @access public
*/
function RecallEquals($params)
{
$name = $this->SelectParam($params, 'name,var');
$value = $params['value'];
if (isset($params['persistent']) && $params['persistent']) {
return $this->Application->RecallPersistentVar($name) == $value;
}
return ($this->Application->RecallVar($name) == $value);
}
/**
* Checks if application variable specified by name value match value passed as parameter
*
* @param Array $params
* @return bool
* @access protected
* @deprecated
*/
protected function GetEquals($params)
{
$name = $this->SelectParam($params, 'var,name,param');
return $this->Application->GetVar($name) == $params['value'];
}
function ModuleInclude($params)
{
$ret = '';
$included = Array ();
$block_params = array_merge($params, Array ('is_silent' => 2)); // don't make fatal errors in case if template is missing
$current_template = $this->Application->GetVar('t');
$replace_main = isset($params['replace_m']) && $params['replace_m'];
$skip_prefixes = isset($params['skip_prefixes']) ? explode(',', $params['skip_prefixes']) : Array ();
$cms_mode = $this->Application->GetVar('admin');
foreach ($this->Application->ModuleInfo as $module_name => $module_data) {
$module_key = mb_strtolower($module_name);
if ( $module_name == 'In-Portal' ) {
if ( !$cms_mode && $this->Application->isAdmin ) {
// don't process In-Portal templates in admin
continue;
}
// Front-End still relies on In-Portal module
$module_prefix = $module_data['TemplatePath'];
}
elseif ( $this->Application->isAdmin && $module_data['Path'] != 'core/' ) {
$module_prefix = $module_key . '/'; // was $module_data['Path'];
}
else {
$module_prefix = $module_data['TemplatePath']; // always have trailing "/"
}
if ( in_array($module_prefix, $included) ) {
// template by this path was already included by other module (e.g. in-portal used core's template)
continue;
}
$block_params['t'] = $module_prefix . $this->SelectParam($params, $module_key . '_template,' . $module_key . '_t,template,t');
$check_prefix = $module_data['Var'];
if ( $check_prefix == 'adm' && $replace_main ) {
$check_prefix = 'c';
}
if ( $block_params['t'] == $current_template || in_array($check_prefix, $skip_prefixes) ) {
continue;
}
$no_data = $this->SelectParam($params, $module_key . '_block_no_data,block_no_data');
if ( $no_data ) {
$block_params['block_no_data'] = $module_prefix . '/' . $no_data;
}
$ret .= $this->Application->IncludeTemplate($block_params);
$included[] = $module_prefix;
}
return $ret;
}
function ModuleEnabled($params)
{
return $this->Application->isModuleEnabled( $params['module'] );
}
/**
* Checks if debug mode is on
*
* @param Array $params
* @return bool
* @access public
*/
function IsDebugMode($params)
{
return defined('DEBUG_MODE') && $this->Application->isDebugMode();
}
/*function MassParse($params)
{
$qty = $params['qty'];
$block = $params['block'];
$mode = $params['mode'];
$o = '';
if ($mode == 'func') {
$func = create_function('$params', '
$o = \'\';
$o.= \'a\'.$params[\'param1\'].\' | \';
$o.= \'a\'.$params[\'param2\'].\' | \';
$o.= \'a\'.$params[\'param3\'].\' | \';
$o.= \'a\'.$params[\'param4\'].\' | \';
$o.= \'
\';
return $o;
');
for ($i=1; $i<$qty; $i++) {
$block_params['param1'] = rand(1, 10000);
$block_params['param2'] = rand(1, 10000);
$block_params['param3'] = rand(1, 10000);
$block_params['param4'] = rand(1, 10000);
$o .= $func($block_params);
}
return $o;
}
$block_params['name'] = $block;
for ($i=0; $i<$qty; $i++) {
$block_params['param1'] = rand(1, 10000);
$block_params['param2'] = rand(1, 10000);
$block_params['param3'] = rand(1, 10000);
$block_params['param4'] = rand(1, 10000);
$block_params['passed'] = $params['passed'];
$block_params['prefix'] = 'm';
$o.= $this->Application->ParseBlock($block_params);
}
return $o;
}*/
function LoggedIn($params)
{
return $this->Application->LoggedIn();
}
/**
* Allows to check if permission exists directly in template and perform additional actions if required
*
* @param Array $params
* @return bool
*/
function CheckPermission($params)
{
$perm_helper = $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
return $perm_helper->TagPermissionCheck($params);
}
/**
* Checks if user is logged in and if not redirects it to template passed
*
* @param Array $params
*/
function RequireLogin($params)
{
$t = $this->Application->GetVar('t');
$next_t = getArrayValue($params, 'next_template');
if ( $next_t ) {
$t = $next_t;
}
// check by permissions: begin
if ((isset($params['perm_event']) && $params['perm_event']) ||
(isset($params['perm_prefix']) && $params['perm_prefix']) ||
(isset($params['permissions']) && $params['permissions'])) {
$perm_helper = $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$perm_status = $perm_helper->TagPermissionCheck($params);
if (!$perm_status) {
list($redirect_template, $redirect_params) = $perm_helper->getPermissionTemplate($params);
$this->Application->Redirect($redirect_template, $redirect_params);
}
else {
return ;
}
}
// check by permissions: end
// check by configuration value: begin
$condition = getArrayValue($params, 'condition');
if (!$condition) {
$condition = true;
}
else {
if (substr($condition, 0, 1) == '!') {
$condition = !$this->Application->ConfigValue(substr($condition, 1));
}
else {
$condition = $this->Application->ConfigValue($condition);
}
}
// check by configuration value: end
// check by belonging to group: begin
$group = $this->SelectParam($params, 'group');
$group_access = true;
if ($group) {
$sql = 'SELECT GroupId
FROM '.TABLE_PREFIX.'UserGroups
WHERE Name = '.$this->Conn->qstr($group);
$group_id = $this->Conn->GetOne($sql);
if ($group_id) {
$groups = explode(',', $this->Application->RecallVar('UserGroups'));
$group_access = in_array($group_id, $groups);
}
}
// check by belonging to group: end
if ((!$this->Application->LoggedIn() || !$group_access) && $condition) {
$redirect_params = $this->Application->HttpQuery->getRedirectParams(true);
if (MOD_REWRITE) {
// TODO: $next_t variable is ignored !!! (is anyone using m_RequireLogin tag with "next_template" parameter?)
$redirect_params = Array (
'm_cat_id' => 0,
'next_template' => 'external:' . $_SERVER['REQUEST_URI'],
);
}
else {
$redirect_params['next_template'] = $t;
}
if (array_key_exists('pass_category', $params)) {
$redirect_params['pass_category'] = $params['pass_category'];
}
if (array_key_exists('use_section', $params)) {
$redirect_params['use_section'] = $params['use_section'];
}
if ( $this->Application->LoggedIn() && !$group_access) {
$this->Application->Redirect($params['no_group_perm_template'], $redirect_params);
}
$this->Application->Redirect($params['login_template'], $redirect_params);
}
}
/**
* Checks, that user belongs to a group with a given name
*
* @param Array $params
* @return bool
*/
protected function IsMember($params)
{
$sql = 'SELECT GroupId
FROM ' . TABLE_PREFIX . 'UserGroups
WHERE Name = ' . $this->Conn->qstr($params['group']);
$group_id = $this->Conn->GetOne($sql);
if ( $group_id ) {
$groups = explode(',', $this->Application->RecallVar('UserGroups'));
return in_array($group_id, $groups);
}
return false;
}
/**
* Checks if SSL is enabled and redirects to SSL Domain if needed
* If SSLDomain is not defined in config - the tag does not do anything
* If for_logged_in_only="1" exits if user is not logged in.
* If called without params forces https right away. If called with by_config="1" checks the
* Require SSL setting from General Config and if it is ON forces https
*
* @param Array $params
*/
protected function CheckSSL($params)
{
$ssl_domain = $this->Application->getSecureDomain();
if ( !$ssl_domain || ($this->Application->TemplatesCache->forceThemeName !== false) ) {
// SSL URL is not set - no way to require SSL
// internal parsing (e.g. "TemplateParser::_parseTemplate") -> don't redirect
return;
}
$require = false;
if ( isset($params['mode']) && $params['mode'] == 'required' ) {
$require = true;
if ( isset($params['for_logged_in_only']) && $params['for_logged_in_only'] && !$this->Application->LoggedIn() ) {
$require = false;
}
if ( isset($params['condition']) ) {
if ( !$this->Application->ConfigValue($params['condition']) ) {
$require = false;
}
}
}
if ( EDITING_MODE ) {
// match SSL mode on front-end to one in administrative console, when browse modes are used
$require = $this->Application->ConfigValue('Require_AdminSSL');
}
- $http_query = $this->Application->recallObject('HTTPQuery');
+ $http_query = $this->Application->recallObject('kHTTPQuery');
/* @var $http_query kHTTPQuery */
$pass = $http_query->getRedirectParams();
$pass['pass_events'] = 1; // to make sure all events are passed when redirect happens
if ( $require ) {
if ( PROTOCOL == 'https://' ) {
$this->Application->SetVar('__KEEP_SSL__', 1);
return;
}
$pass['__SSL__'] = 1;
$this->Application->Redirect('', $pass);
}
else {
if ( PROTOCOL == 'https://' && $this->Application->ConfigValue('Force_HTTP_When_SSL_Not_Required') ) {
if ( $this->Application->GetVar('__KEEP_SSL__') ) {
return;
}
// $pass_more = Array ('pass' => 'm', 'm_cat_id' => 0, '__SSL__' => 0);
$pass['__SSL__'] = 0;
$this->Application->Redirect('', $pass); // $pass_more
}
}
}
function ConstOn($params)
{
$name = $this->SelectParam($params,'name,const');
return kUtil::constOn($name);
}
function SetDefaultCategory($params)
{
$category_id = $this->Application->findModule('Name', $params['module'], 'RootCat');
$this->Application->SetVar('m_cat_id', $category_id);
}
function XMLTemplate($params)
{
$this->NoDebug($params);
if ( isset($params['cache']) && $params['cache'] ) {
$nextyear = intval(date('Y') + 1);
$format = "D, d M Y H:i:s";
$expiration = gmdate($format, time() + $params['cache']) . ' GMT';
$last_modified = time();
header('Cache-Control: public, cache, max-age=' . $params['cache']);
header("Expires: $expiration");
header('Pragma: public');
// Getting headers sent by the client.
$headers = $this->Application->HttpQuery->getHeaders();
// Checking if the client is validating his cache and if it is current.
if ( isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) > $last_modified - $params['cache']) ) {
// Client's cache IS current, so we just respond '304 Not Modified'.
header('Last-Modified: ' . date($format, strtotime($headers['If-Modified-Since'])) . ' GMT', true, 304);
exit;
}
else {
// Image not cached or cache outdated, we respond '200 OK' and output the image.
header('Last-Modified: ' . gmdate($format, $last_modified) . ' GMT', true, 200);
}
}
// xml documents are usually long
kUtil::setResourceLimit();
if ( !$this->Application->GetVar('debug') ) {
return $this->Application->XMLHeader(getArrayValue($params, 'xml_version'));
}
return '';
}
function Header($params)
{
header($params['data']);
}
function NoDebug($params)
{
if ( !$this->Application->GetVar('debug') ) {
kUtil::safeDefine('DBG_SKIP_REPORTING', 1);
}
}
/**
* Returns Home category name
*
* @param Array $params
* @return string
* @deprecated
*/
function RootCategoryName($params)
{
$no_editing = array_key_exists('no_editing', $params) && $params['no_editing'];
return $this->Application->Phrase('la_rootcategory_name', !$no_editing);
}
/**
* Allows to attach file directly from email event template
*
* @param Array $params
*/
function AttachFile($params)
{
$path = FULL_PATH . '/' . $params['path'];
$pseudo = isset($params['special']) ? 'EmailSender.' . $params['special'] : 'EmailSender';
$esender = $this->Application->recallObject($pseudo);
/* @var $esender kEmailSendingHelper */
if ( file_exists($path) ) {
$esender->AddAttachment($path);
}
}
function CaptchaImage($params)
{
$this->NoDebug($params);
$this->Application->SetVar('skip_last_template', 1);
$captcha_helper = $this->Application->recallObject('CaptchaHelper');
/* @var $captcha_helper kCaptchaHelper */
// generate captcha code
$code = $captcha_helper->prepareCode( $this->Application->GetVar('var') );
$captcha_helper->GenerateCaptchaImage($code, $this->Application->GetVar('w'), $this->Application->GetVar('h'), true);
}
function SID($params)
{
return $this->Application->GetSID();
}
function ModuleInfo($params)
{
return $this->Application->findModule($params['key'], $params['value'], $params['return']);
}
function Random($params)
{
return rand(1, 100000000);
}
/**
* Prints parser params, available at current deep level
*
* @param Array $params
* @return string
*/
function PrintCurrentParams($params)
{
$current_params = $this->Application->Parser->Params;
foreach ($current_params as $param_name => $param_value) {
$current_params[$param_name] = $param_name . ' = "' . $param_value . '"';
}
return '' . implode("\n", $current_params) . '
';
}
/**
* Gets previously defined counter result
*
* @param Array $params
* @return int
*/
function GetCounter($params)
{
return $this->Application->getCounter($params['name'], $params);
}
/**
* Increments PageHit counter
*
* @param Array $params
* @return int
*/
function RegisterPageHit($params)
{
if ($this->Application->ConfigValue('UsePageHitCounter')) {
// get current counte
$sql = 'SELECT VariableValue
FROM '.TABLE_PREFIX.'SystemSettings
WHERE VariableName = "PageHitCounter"';
$page_counter = (int)$this->Conn->GetOne($sql);
$sql = 'UPDATE LOW_PRIORITY '.TABLE_PREFIX.'SystemSettings
SET VariableValue = '.($page_counter + 1).'
WHERE VariableName = "PageHitCounter"';
$this->Conn->Query($sql);
}
}
function Timestamp($params)
{
$format = isset($params['format']) ? $params['format'] : 'd.m.Y H:i:s';
return date($format);
}
function GetUrlHiddenFileds($params)
{
$vars = Array ('page', 'per_page', 'sort_by');
$ret = '';
if (array_key_exists('skip', $params)) {
$vars = array_diff($vars, $params['skip']);
}
foreach ($vars as $var_name) {
$var_value = $this->Application->GetVar($var_name);
if ($var_value) {
$ret .= '';
}
}
return $ret;
}
/**
* Returns current Page URL (without re-assembling it).
* "skip_query" param is optional and will remove the ?QUERY part from the result.
*
* @param Array $params
* @return string
* @access protected
*/
protected function CurrentPageLink($params)
{
if ( isset($params['skip_query']) && $params['skip_query'] ) {
return preg_replace('/\?' . preg_quote($_SERVER['QUERY_STRING'], '/') . '$/', '', $_SERVER['REQUEST_URI']);
}
return $_SERVER['REQUEST_URI'];
}
/**
* Returns current maintenance mode state
*
* @param Array $params
* @return int
* @access protected
*/
protected function MaintenanceMode($params)
{
$check_ips = isset($params['check_ips']) ? $params['check_ips'] : true;
return $this->Application->getMaintenanceMode($check_ips);
}
/**
* Checks if element with given name is defined
*
* @param Array $params
* @return int
* @access protected
*/
protected function ElementDefined($params)
{
return $this->Application->Parser->blockFound($params['name']);
}
/**
* Detects mobile browser.
*
* @param array $params
*
* @return string
* @link http://detectmobilebrowsers.com/
*/
protected function IsMobileBrowser($params)
{
$user_agent = $_SERVER['HTTP_USER_AGENT'];
if ( preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i', $user_agent) || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', substr($user_agent, 0, 4)) ) {
return true;
}
return false;
}
}
Index: branches/5.3.x/core/kernel/utility/email_send.php
===================================================================
--- branches/5.3.x/core/kernel/utility/email_send.php (revision 16155)
+++ branches/5.3.x/core/kernel/utility/email_send.php (revision 16156)
@@ -1,2094 +1,2094 @@
guessOptions = Array (
'attachments' => Array (),
'inline_attachments' => Array (),
'text_part' => false,
'html_part' => false,
);
// read SMTP server connection params from config
$smtp_mapping = Array ('server' => 'Smtp_Server', 'port' => 'Smtp_Port');
if ($this->Application->ConfigValue('Smtp_Authenticate')) {
$smtp_mapping['username'] = 'Smtp_User';
$smtp_mapping['password'] = 'Smtp_Pass';
}
foreach ($smtp_mapping as $smtp_name => $config_name) {
$this->smtpParams[$smtp_name] = $this->Application->ConfigValue($config_name);
}
$this->smtpParams['use_auth'] = isset($this->smtpParams['username']) ? true : false;
$this->smtpParams['localhost'] = 'localhost'; // The value to give when sending EHLO or HELO.
$this->sendMethod = $this->smtpParams['server'] && $this->smtpParams['port'] ? 'SMTP' : 'Mail';
if ($this->sendMethod == 'SMTP') {
// create connection object if we will use SMTP
- $this->smtpSocket = $this->Application->makeClass('Socket');
+ $this->smtpSocket = $this->Application->makeClass('kSocket');
}
$this->SetCharset(null, true);
}
/**
* Returns new message id header by sender's email address
*
* @param string $email_address email address
* @return string
*/
function GenerateMessageID($email_address)
{
list ($micros, $seconds) = explode(' ', microtime());
list ($user, $domain) = explode('@', $email_address, 2);
$message_id = strftime('%Y%m%d%H%M%S', $seconds).substr($micros, 1, 5).'.'.preg_replace('/[^A-Za-z]+/', '-', $user).'@'.$domain;
$this->SetHeader('Message-ID', '<'.$message_id.'>');
}
/**
* Returns extension of given filename
*
* @param string $filename
* @return string
*/
function GetFilenameExtension($filename)
{
$last_dot = mb_strrpos($filename, '.');
return $last_dot !== false ? mb_substr($filename, $last_dot + 1) : '';
}
/**
* Creates boundary for part by number (only if it's missing)
*
* @param int $part_number
*
*/
function CreatePartBoundary($part_number)
{
$part =& $this->parts[$part_number];
if (!isset($part['BOUNDARY'])) {
$part['BOUNDARY'] = md5(uniqid($part_number.time()));
}
}
/**
* Returns ready to use headers associative array of any message part by it's number
*
* @param int $part_number
* @return Array
*/
function GetPartHeaders($part_number)
{
$part =& $this->parts[$part_number];
if (!isset($part['Content-Type'])) {
return $this->SetError('MISSING_CONTENT_TYPE');
}
$full_type = strtolower($part['Content-Type']);
list ($type, $sub_type) = explode('/', $full_type);
$headers['Content-Type'] = $full_type;
switch ($type) {
case 'text':
case 'image':
case 'audio':
case 'video':
case 'application':
case 'message':
// 1. update content-type header
if (isset($part['CHARSET'])) {
$headers['Content-Type'] .= '; charset='.$part['CHARSET'];
}
if (isset($part['NAME'])) {
$headers['Content-Type'] .= '; name="'.$part['NAME'].'"';
}
// 2. set content-transfer-encoding header
if (isset($part['Content-Transfer-Encoding'])) {
$headers['Content-Transfer-Encoding'] = $part['Content-Transfer-Encoding'];
}
// 3. set content-disposition header
if (isset($part['DISPOSITION']) && $part['DISPOSITION']) {
$headers['Content-Disposition'] = $part['DISPOSITION'];
if (isset($part['NAME'])) {
$headers['Content-Disposition'] .= '; filename="'.$part['NAME'].'"';
}
}
break;
case 'multipart':
switch ($sub_type) {
case 'alternative':
case 'related':
case 'mixed':
case 'parallel':
$this->CreatePartBoundary($part_number);
$headers['Content-Type'] .= '; boundary="'.$part['BOUNDARY'].'"';
break;
default:
return $this->SetError('INVALID_MULTIPART_SUBTYPE', Array($sub_type));
}
break;
default:
return $this->SetError('INVALID_CONTENT_TYPE', Array($full_type));
}
// set content-id if any
if (isset($part['Content-ID'])) {
$headers['Content-ID'] = '<'.$part['Content-ID'].'>';
}
return $headers;
}
function GetPartBody($part_number)
{
$part =& $this->parts[$part_number];
if (!isset($part['Content-Type'])) {
return $this->SetError('MISSING_CONTENT_TYPE');
}
$full_type = strtolower($part['Content-Type']);
list ($type, $sub_type) = explode('/', $full_type);
$body = '';
switch ($type) {
// compose text/binary content
case 'text':
case 'image':
case 'audio':
case 'video':
case 'application':
case 'message':
// 1. get content of part
if (isset($part['FILENAME'])) {
// content provided via absolute path to content containing file
$filename = $part['FILENAME'];
$file_size = filesize($filename);
$body = file_get_contents($filename);
if ($body === false) {
return $this->SetError('FILE_PART_OPEN_ERROR', Array($filename));
}
$actual_size = strlen($body);
if (($file_size === false || $actual_size > $file_size) && get_magic_quotes_runtime()) {
$body = stripslashes($body);
}
if ($file_size !== false && $actual_size != $file_size) {
return $this->SetError('FILE_PART_DATA_ERROR', Array($filename));
}
}
else {
// content provided directly as one of part keys
if (!isset($part['DATA'])) {
return $this->SetError('FILE_PART_DATA_MISSING');
}
$body =& $part['DATA'];
}
// 2. get part transfer encoding
$encoding = isset($part['Content-Transfer-Encoding']) ? strtolower($part['Content-Transfer-Encoding']) : '';
if (!in_array($encoding, Array ('', 'base64', 'quoted-printable', '7bit'))) {
return $this->SetError('INVALID_ENCODING', Array($encoding));
}
if ($encoding == 'base64') {
// split base64 encoded text by 76 symbols at line (MIME requirement)
$body = chunk_split( base64_encode($body) );
}
break;
case 'multipart':
// compose multipart message
switch ($sub_type) {
case 'alternative':
case 'related':
case 'mixed':
case 'parallel':
$this->CreatePartBoundary($part_number);
$boundary = $this->line_break.'--'.$part['BOUNDARY'];
foreach ($part['PARTS'] as $multipart_number) {
$body .= $boundary.$this->line_break;
$part_headers = $this->GetPartHeaders($multipart_number);
if ($part_headers === false) {
// some of sub-part headers were invalid
return false;
}
foreach ($part_headers as $header_name => $header_value) {
$body .= $header_name.': '.$header_value.$this->line_break;
}
$part_body = $this->GetPartBody($multipart_number);
if ($part_body === false) {
// part body was invalid
return false;
}
$body .= $this->line_break.$part_body;
}
$body .= $boundary.'--'.$this->line_break;
break;
default:
return $this->SetError('INVALID_MULTIPART_SUBTYPE', Array($sub_type));
}
break;
default:
return $this->SetError('INVALID_CONTENT_TYPE', Array($full_type));
}
return $body;
}
/**
* Applies quoted-printable encoding to specified text
*
* @param string $text
* @param string $header_charset
* @param int $break_lines
* @return unknown
*/
function QuotedPrintableEncode($text, $header_charset = '', $break_lines = 1)
{
$ln = strlen($text);
$h = strlen($header_charset) > 0;
if ($h) {
$s = Array (
'=' => 1,
'?' => 1,
'_' => 1,
'(' => 1,
')' => 1,
'<' => 1,
'>' => 1,
'@' => 1,
',' => 1,
';' => 1,
'"' => 1,
'\\' => 1,
/*
'/' => 1,
'[' => 1,
']' => 1,
':' => 1,
'.' => 1,
*/
);
$b = $space = $break_lines = 0;
for ($i = 0; $i < $ln; $i++) {
if (isset($s[$text[$i]])) {
$b = 1;
break;
}
switch ($o = ord($text[$i])) {
case 9:
case 32:
$space = $i + 1;
$b = 1;
break 2;
case 10:
case 13:
break 2;
default:
if ($o < 32 || $o > 127) {
$b = 1;
break 2;
}
}
}
if($i == $ln) {
return $text;
}
if ($space > 0) {
return substr($text, 0, $space).($space < $ln ? $this->QuotedPrintableEncode(substr($text, $space), $header_charset, 0) : '');
}
}
for ($w = $e = '', $n = 0, $l = 0, $i = 0; $i < $ln; $i++) {
$c = $text[$i];
$o = ord($c);
$en = 0;
switch ($o) {
case 9:
case 32:
if (!$h) {
$w = $c;
$c = '';
}
else {
if ($b) {
if ($o == 32) {
$c = '_';
}
else {
$en = 1;
}
}
}
break;
case 10:
case 13:
if (strlen($w)) {
if ($break_lines && $l + 3 > 75) {
$e .= '='.$this->line_break;
$l = 0;
}
$e .= sprintf('=%02X', ord($w));
$l += 3;
$w = '';
}
$e .= $c;
if ($h) {
$e .= "\t";
}
$l = 0;
continue 2;
case 46:
case 70:
case 102:
$en = (!$h && ($l == 0 || $l + 1 > 75));
break;
default:
if ($o > 127 || $o < 32 || !strcmp($c, '=')) {
$en = 1;
}
elseif ($h && isset($s[$c])) {
$en = 1;
}
break;
}
if (strlen($w)) {
if ($break_lines && $l + 1 > 75) {
$e .= '='.$this->line_break;
$l = 0;
}
$e .= $w;
$l++;
$w = '';
}
if (strlen($c)) {
if ($en) {
$c = sprintf('=%02X', $o);
$el = 3;
$n = 1;
$b = 1;
}
else {
$el = 1;
}
if ($break_lines && $l + $el > 75) {
$e .= '='.$this->line_break;
$l = 0;
}
$e .= $c;
$l += $el;
}
}
if (strlen($w)) {
if ($break_lines && $l + 3 > 75) {
$e .= '='.$this->line_break;
}
$e .= sprintf('=%02X', ord($w));
}
return $h && $n ? '=?'.$header_charset.'?q?'.$e.'?=' : $e;
}
/**
* Sets message header + encodes is by quoted-printable using charset specified
*
* @param string $name
* @param string $value
* @param string $encoding_charset
*/
function SetHeader($name, $value, $encoding_charset = '')
{
if ($encoding_charset) {
// actually for headers base64 method may give shorter result
$value = $this->QuotedPrintableEncode($value, $encoding_charset);
}
$this->headers[$name] = $value;
}
/**
* Sets header + automatically encodes it using default charset
*
* @param string $name
* @param string $value
*/
function SetEncodedHeader($name, $value)
{
$this->SetHeader($name, $value, $this->charset);
}
/**
* Sets header which value is email and username +autoencode
*
* @param string $header
* @param string $address
* @param string $name
*/
function SetEncodedEmailHeader($header, $address, $name)
{
$this->SetHeader($header, $this->QuotedPrintableEncode($name, $this->charset) . ' <' . $address . '>');
}
function SetMultipleEncodedEmailHeader($header, $addresses)
{
$value = '';
foreach ($addresses as $name => $address) {
$value .= $this->QuotedPrintableEncode($name, $this->charset) . ' <' . $address . '>, ';
}
$this->SetHeader($header, substr($value, 0, -2));
}
/**
* Adds new part to message and returns it's number
*
* @param Array $part_definition
* @param int|bool $part_number number of new part
* @return int
*/
function AddPart(&$part_definition, $part_number = false)
{
$part_number = $part_number !== false ? $part_number : count($this->parts);
$this->parts[$part_number] =& $part_definition;
return $part_number;
}
/**
* Returns text version of HTML document
*
* @param string $html
* @param bool $keep_inp_tags
* @return string
*/
function ConvertToText($html, $keep_inp_tags = false)
{
if ( $keep_inp_tags && preg_match_all('/(<[\\/]?)inp2:([^>]*?)([\\/]?>)/s', $html, $regs) ) {
$found_tags = Array ();
foreach ($regs[0] as $index => $tag) {
$tag_placeholder = '%' . md5($index . ':' . $tag) . '%';
$found_tags[$tag_placeholder] = $tag;
// we can have duplicate tags -> replace only 1st occurrence (str_replace can't do that)
$html = preg_replace('/' . preg_quote($tag, '/') . '/', $tag_placeholder, $html, 1);
}
$html = $this->_convertToText($html);
foreach ($found_tags as $tag_placeholder => $tag) {
$html = str_replace($tag_placeholder, $tag, $html);
}
return $html;
}
return $this->_convertToText($html);
}
/**
* Returns text version of HTML document
*
* @param string $html
* @return string
*/
protected function _convertToText($html)
{
$search = Array (
"'(<\/td>.*)[\r\n]+(.*[\r\n]{0,2})|(<\/p>)|(<\/div>)|(<\/tr>)'i",
"'(.*?)'si",
"' |