Index: trunk/core/kernel/db/db_tag_processor.php =================================================================== diff -u -N -r8570 -r8605 --- trunk/core/kernel/db/db_tag_processor.php (.../db_tag_processor.php) (revision 8570) +++ trunk/core/kernel/db/db_tag_processor.php (.../db_tag_processor.php) (revision 8605) @@ -242,11 +242,12 @@ $list_name = $this->Application->Parser->GetParam('list_name'); } - $requery = getArrayValue($params, 'requery'); + $requery = isset($params['requery']) && $params['requery']; if ($list_name && !$requery){ - $names_mapping = $this->Application->GetVar('NamesToSpecialMapping'); + $names_mapping = $this->Application->GetVar('NamesToSpecialMapping'); - $special = getArrayValue($names_mapping, $this->Prefix, $list_name); + $special = is_array($names_mapping) && isset($names_mapping[$this->Prefix]) && isset($names_mapping[$this->Prefix][$list_name]) ? $names_mapping[$this->Prefix][$list_name] : false; +// $special = getArrayValue($names_mapping, $this->Prefix, $list_name); if(!$special) { $special = $this->BuildListSpecial($params); @@ -610,7 +611,7 @@ if( isset($params['plus_or_as_label']) ) { $value = substr($value, 0,1) == '+' ? substr($value, 1) : $this->Application->Phrase($value); } - elseif( getArrayValue($params,'as_label') ) $value = $this->Application->Phrase($value); + elseif( isset($params['as_label']) && $params['as_label'] ) $value = $this->Application->Phrase($value); $first_chars = $this->SelectParam($params,'first_chars,cut_first'); if($first_chars) @@ -659,7 +660,7 @@ $param_name = $this->SelectParam($params, 'name'); $params = $this->Application->Parser->Params; } - $value = getArrayValue($params, $param_name); + $value = isset($params[$param_name]) ? $params[$param_name] : false; return $value && ($value != '$'.$param_name); } Index: trunk/core/kernel/db/dblist.php =================================================================== diff -u -N -r8428 -r8605 --- trunk/core/kernel/db/dblist.php (.../dblist.php) (revision 8428) +++ trunk/core/kernel/db/dblist.php (.../dblist.php) (revision 8605) @@ -610,7 +610,8 @@ function AddOrderField($field, $direction = 'asc', $is_expression = false) { // original multilanguage field - convert to current lang field - if (getArrayValue($this->Fields, $field, 'formatter') == 'kMultiLanguage' && !getArrayValue($this->Fields, $field, 'master_field')) { + $formatter = isset($this->Fields[$field]['formatter']) ? $this->Fields[$field]['formatter'] : false; + if ($formatter == 'kMultiLanguage' && !isset($this->Fields[$field]['master_field'])) { $lang = $this->Application->GetVar('m_lang'); $field = 'l'.$lang.'_'.$field; } Index: trunk/core/kernel/utility/formatters/multilang_formatter.php =================================================================== diff -u -N -r8361 -r8605 --- trunk/core/kernel/utility/formatters/multilang_formatter.php (.../multilang_formatter.php) (revision 8361) +++ trunk/core/kernel/utility/formatters/multilang_formatter.php (.../multilang_formatter.php) (revision 8605) @@ -96,7 +96,7 @@ function Format($value, $field_name, &$object, $format=null) { - $master_field = getArrayValue($object->Fields, $field_name, 'master_field'); + $master_field = isset($object->Fields[$field_name]['master_field']) ? $object->Fields[$field_name]['master_field'] : false; if (!$master_field) { // if THIS field is master it does NOT have reference to it's master_field $lang = $this->Application->GetVar('m_lang'); $value = $object->GetDBField('l'.$lang.'_'.$field_name); //getting value of current language Index: trunk/core/kernel/application.php =================================================================== diff -u -N -r8598 -r8605 --- trunk/core/kernel/application.php (.../application.php) (revision 8598) +++ trunk/core/kernel/application.php (.../application.php) (revision 8605) @@ -160,6 +160,8 @@ var $CompilationCache = array(); //used when compiling templates var $CachedProcessors = array(); //used when running compiled templates + var $LambdaElements = 1; // for autonumbering unnamed RenderElements [any better place for this prop? KT] + /** * Returns kApplication instance anywhere in the script. * @@ -1123,7 +1125,7 @@ } } - if (getArrayValue($params, 'opener') == 'u') { + if (isset($params['opener']) && $params['opener'] == 'u') { $wid = $this->Application->GetVar('m_wid'); $stack_name = rtrim('opener_stack_'.$wid, '_'); $opener_stack = $this->RecallVar($stack_name); @@ -1195,7 +1197,8 @@ } // append pass through variables to each link to be build - $params = array_merge_recursive2($this->getPassThroughVariables($params), $params); +// $params = array_merge_recursive2($this->getPassThroughVariables($params), $params); + $params = array_merge($this->getPassThroughVariables($params), $params); if ($force_rewrite || ($this->RewriteURLs($ssl) && !$no_rewrite)) { @@ -1496,7 +1499,7 @@ $params['admin'] = 1; } - if( getArrayValue($params,'escape') ) + if( isset($params['escape']) && $params['escape'] ) { $ret = addslashes($ret); unset($params['escape']); Index: trunk/core/kernel/globals.php =================================================================== diff -u -N -r8402 -r8605 --- trunk/core/kernel/globals.php (.../globals.php) (revision 8402) +++ trunk/core/kernel/globals.php (.../globals.php) (revision 8605) @@ -74,6 +74,8 @@ // function getArrayValue(&$array, $key) { +// global $debugger; +// if (is_object($debugger)) $debugger->ProfilePoint('getArrayValue', 1); $ret = isset($array[$key]) ? $array[$key] : false; if ($ret && func_num_args() > 2) { for ($i = 2; $i < func_num_args(); $i++) { Index: trunk/core/kernel/parser/construct_tags.php =================================================================== diff -u -N -r6583 -r8605 --- trunk/core/kernel/parser/construct_tags.php (.../construct_tags.php) (revision 6583) +++ trunk/core/kernel/parser/construct_tags.php (.../construct_tags.php) (revision 8605) @@ -1,5 +1,8 @@ Tag != 'block' && $tag->Tag != 'DefineElement') { + // && ($tag->Tag != 'RenderElement' && isset($tag->NP['_short_closing_'])) + if ($tag->Tag != 'block' && $tag->Tag != 'DefineElement' && $tag->Tag != 'Capture' && !($tag->Tag == 'RenderElement' && isset($tag->NP['_short_closing_']))) { $this->Parser->AppendCode($tag->GetCode()); } // $this->Parser->AppendCompiledCode( $tag->GetCode() ); @@ -170,12 +174,18 @@ switch ($this->Tag) { case 'block': case 'DefineElement': + case 'RenderElement': if ($this->Tag == 'DefineElement') { $this->SetStopTag('end_define'); //This recursion level should end when 'blockend' is found } else { $this->SetStopTag('blockend'); //This recursion level should end when 'blockend' is found } + if ($this->Tag == 'RenderElement') { + $this->NP['name'] = '__lambda_element_'.$this->Application->LambdaElements++; + $RenderTag =& new Tag($this->TagData.' name="'.$this->NP['name'].'"', $this->Parser); + $this->Parser->AppendCode($RenderTag->GetCode()); + } $this->Parser->Recurve($this); //Saving current tag in parser recursion array $this->Parser->SetBuffer(''); $this->BlockName = $this->NP['name']; //Stroing BlockName @@ -246,12 +256,23 @@ //caching func body $this->Application->PreParsedCache[$this->BlockName] = $f_body; - $func = create_function('$params', $f_body); + $compile_body = preg_replace('/\/\*COMPILE-ONLY\*\/.*/m', '', $f_body); + + $func = create_function('$params', $compile_body); $this->Application->PreParsedBlocks[$this->BlockName] = $func; $this->Parser->Args = null; $this->Parser->ResetCode(); - $this->Parser->AppendCompiledFunction($this->BlockName, $f_body); + $real_name = $this->Parser->AppendCompiledFunction($this->BlockName, $f_body); + + if ($this->Tag == 'RenderElement') { + $RenderTag =& new Tag($this->TagData.' name="'.$this->BlockName.'"', $this->Parser); +// $this->Parser->AppendCompiledCode($RenderTag->GetCode()); + + // for compilation run + $RenderTag->Process(); + } + } return true; } @@ -274,4 +295,84 @@ } } +class CaptureTag extends ConstructTag { + var $VarName = null; + var $Mode = CM_LATE_PARSE; + + function Process() + { + switch ($this->Tag) { + case 'Capture': + $this->Parser->Recurve($this); //Saving current tag in parser recursion array + $this->Parser->SetBuffer(''); + $this->VarName = $this->NP['to_var']; //Stroing BlockName + $this->StoreSkipMode(); + + if (isset($this->NP['mode']) && $this->NP['mode'] == 'parse_now') { + $this->Mode = CM_PARSE; + } + $this->SuggestSkipMode(skip_tags); + break; + } + } + + function RunCapture($f, $func, $cur_lambda) + { + $code = array(); + $code[] = '/*COMPILE-ONLY*/ '.$f[2]; + $code[] = '/*LAMBDA-ONLY*/ $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'] = $application->PreParsedBlocks[\'capture_'.$this->VarName.$cur_lambda.'\'];'; + $code[] = '$__f = $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'];'; + $code[] = '$application->Parser->SetParam(\''.$this->VarName.'\', $__f(array())'.');'; + $code[] = '$'.$this->VarName.' = $application->Parser->GetParam(\''.$this->VarName.'\');'; + $code[] = '$params[\''.$this->VarName.'\'] = $'.$this->VarName.';'; + if ($this->Parser->RecursionIndex > 1) { + $this->Parser->AppendCode($code, -1); + } + else { + $this->Application->Parser->SetParam($this->VarName, $func(array())); + $this->Parser->AppendCompiledCode($code); + } + } + + function CheckRecursion(&$tag) + { + if (parent::CheckRecursion($tag)) { //if endtag matches (SkipMode would be restored then) + $f_code = $this->Parser->GetCode(); + array_unshift($f_code, '$o = \'\';'); + array_unshift($f_code, '$application =& kApplication::Instance();'); + $f_code[] = 'return $o;'; + + $f = $this->Parser->PrepareCompiledFunction('capture_'.$this->VarName, $f_code, false); + $f_code = trim(join("\n\t", $f_code)); + $func = create_function('$params', $f_code); + $this->Application->PreParsedBlocks['capture_'.$this->VarName] = $func; + $cur_lambda = $this->Application->LambdaElements++; + $this->Application->PreParsedBlocks['capture_'.$this->VarName.$cur_lambda] = $func; + + $this->Parser->AppendCompiledCode($f[1]); + + if ($this->Mode == CM_PARSE) { + $this->RunCapture($f, $func, $cur_lambda); + } + elseif ($this->Mode == CM_LATE_PARSE) { + $code = array(); + $code[] = '/*COMPILE-ONLY*/ '.$f[2]; + $code[] = '/*LAMBDA-ONLY*/ $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'] = $application->PreParsedBlocks[\'capture_'.$this->VarName.$cur_lambda.'\'];'; + $code[] = '$application->LateParsed[\''.$this->VarName.'\'] = '.$cur_lambda.';'; + if ($this->Parser->RecursionIndex > 1) { + $this->Parser->AppendCode($code, -1); + } + else { + $this->Parser->AppendCompiledCode($code); + } + $this->Application->LateParsed[$this->VarName] = $cur_lambda; + } + $this->Parser->ResetCode(); + return true; + } + return ($tag->Tag == $this->StopTag); //Tag matches StopTag we are waiting for to close current recursion + } + +} + ?> \ No newline at end of file Index: trunk/core/kernel/parser/template_parser.php =================================================================== diff -u -N -r8358 -r8605 --- trunk/core/kernel/parser/template_parser.php (.../template_parser.php) (revision 8358) +++ trunk/core/kernel/parser/template_parser.php (.../template_parser.php) (revision 8605) @@ -28,7 +28,7 @@ var $DataExists = false; var $FromPreParseCache = false; - + function TemplateParser() { parent::kBase(); @@ -155,26 +155,28 @@ return $code; } - function AppendCode($code) + function AppendCode($code, $level_offset=0) { + if ($this->RecursionIndex+$level_offset <= 0 ) $level_offset = 0; if (defined('EXPERIMENTAL_PRE_PARSE')) { - if (!isset($this->Code[$this->RecursionIndex])) { - $this->Code[$this->RecursionIndex] = Array(); + if (!isset($this->Code[$this->RecursionIndex+$level_offset])) { + $this->Code[$this->RecursionIndex+$level_offset] = Array(); } if (is_array($code)) { foreach ($code as $line) { - $this->Code[$this->RecursionIndex][] = rtrim($line, "\n")."\n"; + $this->Code[$this->RecursionIndex+$level_offset][] = rtrim($line, "\n")."\n"; } } else { - $this->Code[$this->RecursionIndex][] .= rtrim($code, "\n")."\n"; + $this->Code[$this->RecursionIndex+$level_offset][] .= rtrim($code, "\n")."\n"; } } } - function AppendCompiledFunction($f_name, $f_body) + function PrepareCompiledFunction($f_name, $f_body, $add_reference=true) { $real_name = 'f_'.abs(crc32($this->TemplateName)).'_'.$f_name; + $real_code = ''; if (defined('EXPERIMENTAL_PRE_PARSE')) { // if such function already compiled if ( isset($this->Application->CompiledFunctions[$f_name]) || @@ -189,29 +191,50 @@ } } - $this->CompiledBuffer .= "\t".'$application->PreParsedBlocks[\''.$f_name.'\'] = \''.$real_name.'\';'."\n"; - $this->CompiledBuffer .= 'if (!function_exists(\''.$real_name.'\')) {'."\n"; - $this->CompiledBuffer .= "\t".'function '.$real_name.'($params)'."\n\t{\n"; - $this->CompiledBuffer .= $f_body; - $this->CompiledBuffer .= "\t}\n\n"; - $this->CompiledBuffer .= '}'."\n"; + if (is_array($f_body)) { + $real_body = ''; + foreach ($f_body as $line) { + if (preg_match('/^\/\*LAMBDA-ONLY\*\//', $line)) continue; + $real_body .= "\t\t".rtrim($line, "\n")."\n"; + }; + $f_body = $real_body; + } + else { + $f_body = preg_replace('/\/\*LAMBDA-ONLY\*\/.*/m', '', $f_body); + } - $this->Application->CompiledFunctions[$f_name] = $real_name; + $ref = "\t".'$application->PreParsedBlocks[\''.$f_name.'\'] = \''.$real_name.'\';'."\n"; + if ($add_reference) $real_code .= $ref; + $real_code .= 'if (!function_exists(\''.$real_name.'\')) {'."\n"; + $real_code .= "\t".'function '.$real_name.'($params)'."\n\t{\n"; + $real_code .= $f_body; + $real_code .= "\t}\n\n"; + $real_code .= '}'."\n"; /*if (defined('DEBUG_MODE') && DEBUG_MODE && defined('DBG_PRE_PARSE') && DBG_PRE_PARSE) { // this shows newly compiled functions (blocks) global $debugger; $f_body = "\t".'function '.$real_name.'($params)'."\n\t{\n".$f_body."\t}\n\n"; $debugger->appendHTML($debugger->highlightString($f_body)); }*/ + $this->Application->CompiledFunctions[$f_name] = $real_name; + + return array($real_name, $real_code, $ref); } } + function AppendCompiledFunction($f_name, $f_body) + { + $f = $this->PrepareCompiledFunction($f_name, $f_body); + $this->CompiledBuffer .= $f[1]; + } + function AppendCompiledCode($code) { if (defined('EXPERIMENTAL_PRE_PARSE')) { if (is_array($code)) { foreach ($code as $line) { + if (preg_match('/^\/\*LAMBDA-ONLY\*\//', $line)) continue; $this->CompiledBuffer .= "\t".rtrim($line, "\n")."\n"; } } @@ -333,7 +356,8 @@ } // temporary - for backward compatability with in-portal style if - if ($opening_tag == '' && $tag_part != 'm_if' && $tag_part != 'm_DefineElement') { + $compat_tags = array('m_if', 'm_DefineElement', 'm_Capture', 'm_RenderElement'); + if ($opening_tag == '' && !in_array($tag_part, $compat_tags)) { if (strpos($the_tag, ' ') !== false) { list($function, $params) = explode(' ', $the_tag, 2); } @@ -355,6 +379,8 @@ $tag = '__COMMENT__'; } + if ($closing_tag == '>') $tag .= ' _short_closing_="1"'; + $this->Position = $tag_close_pos + $close_len; return $tag; } @@ -642,11 +668,11 @@ if( !isset($pass_params['PrefixSpecial']) && isset($pass_params['prefix']) ) $pass_params['PrefixSpecial'] = $pass_params['prefix']; $ret = $f($pass_params); - + if (isset($params['return_params']) && $params['return_params']) { $this->ParamsStack[$this->ParamsRecursionIndex - 1] = array_merge($this->ParamsStack[$this->ParamsRecursionIndex - 1], $this->ParamsStack[$this->ParamsRecursionIndex]); } - + unset($this->ParamsStack[$this->ParamsRecursionIndex--]); $this->Params = $this->ParamsStack[$this->ParamsRecursionIndex]; $this->MainParser = true; @@ -681,10 +707,10 @@ $template_name ); } - + $this->Application->Parser =& $this; $this->Application->Parser->DataExists = $this->Application->Parser->DataExists || $BlockParser->DataExists; - + return $o; } Index: trunk/core/kernel/utility/debugger.php =================================================================== diff -u -N -r8586 -r8605 --- trunk/core/kernel/utility/debugger.php (.../debugger.php) (revision 8586) +++ trunk/core/kernel/utility/debugger.php (.../debugger.php) (revision 8605) @@ -21,6 +21,8 @@ var $ProfilerTotals = Array(); var $ProfilerTotalCount = Array(); + var $ProfilePoints = Array(); + /** * Prevent recursion when processing debug_backtrace() function results * @@ -893,6 +895,31 @@ return 0; } + function ProfilePoint($title, $level=1) + { + $trace_results = debug_backtrace(); + $level = min($level,count($trace_results)-1); + + do { + $point = $trace_results[$level]; + $location = $point['file'].':'.$point['line']; + $level++; + $has_more = isset($trace_results[$level]); + } while ($has_more && $point['function'] == $trace_results[$level]['function'] ); + + if ($location == ':') { + echo ''; + } + + if (!isset($this->ProfilePoints[$title])) { + $this->ProfilePoints[$title] = array(); + } + if (!isset($this->ProfilePoints[$title][$location])) { + $this->ProfilePoints[$title][$location] = 0; + } + $this->ProfilePoints[$title][$location]++; + } + /** * Generates report * @@ -927,6 +954,20 @@ $this->appendHTML($top_line); $this->moveToBegin(1); + if (count($this->ProfilePoints)>0) { + foreach($this->ProfilePoints as $point => $locations) { + arsort($this->ProfilePoints[$point]); + } + + $this->appendHTML($this->highlightString($this->print_r($this->ProfilePoints, true))); + /*foreach ($this->ProfilePoints as $point => $locations) { + foreach ($locations as $location => $occurences) { + + + } + }*/ + } + if ($this->constOn('DBG_SQL_PROFILE') && isset($this->ProfilerTotals['sql'])) { // sql query profiling was enabled -> show totals $this->appendHTML('SQL Total time: '.$this->ProfilerTotals['sql'].' Number of queries: '.$this->ProfilerTotalCount['sql']); Index: trunk/core/kernel/utility/event.php =================================================================== diff -u -N -r7855 -r8605 --- trunk/core/kernel/utility/event.php (.../event.php) (revision 7855) +++ trunk/core/kernel/utility/event.php (.../event.php) (revision 8605) @@ -155,8 +155,11 @@ function getEventParam($name) { $args = func_get_args(); - array_unshift($args, $this->specificParams); - return call_user_func_array('getArrayValue', $args); // getArrayValue($this->specificParams, $name); + if (count($args) > 1) { + array_unshift($args, $this->specificParams); + return call_user_func_array('getArrayValue', $args); // getArrayValue($this->specificParams, $name); + } + return isset($this->specificParams[$name]) ? $this->specificParams[$name] : false; } function getPrefixSpecial($from_submit=false) @@ -294,13 +297,13 @@ // 2. check if this section has perm_prefix mapping to other prefix $sections_helper =& $this->Application->recallObject('SectionsHelper'); /* @var $sections_helper kSectionsHelper */ - + $section_data =& $sections_helper->getSectionData($section); if ($section_data && isset($section_data['perm_prefix']) && $section_data['perm_prefix'] != $top_prefix) { $this->setEventParam('top_prefix', $section_data['perm_prefix']); $section = $this->Application->getUnitOption($section_data['perm_prefix'].'.main', 'PermSection'); } - + if (!$section) { if ($this->Application->isDebugMode()) { $this->Application->Debugger->appendTrace(); Index: trunk/core/kernel/parser/tags.php =================================================================== diff -u -N -r8472 -r8605 --- trunk/core/kernel/parser/tags.php (.../tags.php) (revision 8472) +++ trunk/core/kernel/parser/tags.php (.../tags.php) (revision 8605) @@ -197,12 +197,23 @@ */ function Process() { + $short_closing = false; + if (isset($this->NP['_short_closing_'])) { + unset($this->NP['_short_closing_']); + $this->TagData = str_replace(' _short_closing_="1"', '', $this->TagData); + $short_closing = true; + } if ($this->Processor == 'm' || $this->Processor == 'm_TagProcessor') { //if we are procssing Main tags - if ($this->Tag == 'block' || $this->Tag == 'DefineElement') { + if ($this->Tag == 'block' || $this->Tag == 'DefineElement' || ($this->Tag == 'RenderElement' && $short_closing)) { $tag =& new BlockTag('', $this->Parser); $tag->CopyFrom($this); $tag->Process(); } + elseif($this->Tag == 'Capture') { + $tag =& new CaptureTag('', $this->Parser); + $tag->CopyFrom($this); + $tag->Process(); + } elseif ($this->Parser->SkipMode == skip_tags) { return; } @@ -314,14 +325,20 @@ if ($echo) $code[] = '$o = '."'';\n"; - switch ( $this->Tag ) { - case 'DefaultParam': + switch ( strtolower($this->Tag) ) { + case 'defaultparam': foreach ($this->NP as $key => $val) { $code[] = 'if (!isset($'.$key.')) $application->Parser->SetParam(\''.$key.'\', \''.$val.'\');'; $code[] = '$'.$key.' = isset($'.$key.') ? $'.$key.' : \''.$val.'\';'; } return $code; case 'param': + $code[] = 'if (isset($application->LateParsed["'.$this->NP['name'].'"])) {'; + $code[] = '$__f = $application->PreParsedBlocks[\'capture_'.$this->NP['name'].'\'];'; + $code[] = '$application->Parser->SetParam(\''.$this->NP['name'].'\', $__f(array())'.');'; + $code[] = '$'.$this->NP['name'].' = $application->Parser->GetParam(\''.$this->NP['name'].'\');'; + $code[] = '$params[\''.$this->NP['name'].'\'] = $'.$this->NP['name'].';'; + $code[] = '}'; $param_code = '$o .= $params["'.$this->NP['name'].'"]'; if (isset($this->NP['plus'])) { $param_code .= ' + '.$this->NP['plus']; @@ -426,6 +443,7 @@ if (isset($pass_params['result_to_var'])) { $code[] = '$'.$pass_params['result_to_var'].' = $application->Parser->GetParam(\''.$pass_params['result_to_var'].'\');'; + $code[] = '$params[\''.$pass_params['result_to_var'].'\'] = $'.$pass_params['result_to_var'].';'; $echo = false; } Index: trunk/core/kernel/processors/main_processor.php =================================================================== diff -u -N -r8545 -r8605 --- trunk/core/kernel/processors/main_processor.php (.../main_processor.php) (revision 8545) +++ trunk/core/kernel/processors/main_processor.php (.../main_processor.php) (revision 8605) @@ -203,6 +203,12 @@ function Param($params) { //$parser =& $this->Application->recallObject('TemplateParser'); + $name = $params['name']; + if (isset($this->Application->LateParsed[$name])) { + $f = $this->Application->PreParsedBlocks['capture_'.$name.$this->Application->LateParsed[$name]]; + $this->Application->Parser->SetParam($name, $f(array())); + } + $res = $this->Application->Parser->GetParam($params['name']); if ($res === false) $res = ''; if (isset($params['plus'])) @@ -458,7 +464,7 @@ if (array_key_exists('default', $params)) return $params['default']; //backward compatibility $translation = $this->Application->Phrase($this->SelectParam($params, 'label,name,title')); - if (getArrayValue($params, 'escape')) { + if (isset($params['escape']) && $params['escape']) { $translation = htmlspecialchars($translation, ENT_QUOTES); $translation = addslashes($translation); } Index: trunk/core/kernel/kbase.php =================================================================== diff -u -N -r8474 -r8605 --- trunk/core/kernel/kbase.php (.../kbase.php) (revision 8474) +++ trunk/core/kernel/kbase.php (.../kbase.php) (revision 8605) @@ -474,7 +474,8 @@ if($fields) { $this->VirtualFields = $fields; - $this->Fields = array_merge_recursive2($this->VirtualFields, $this->Fields); + $this->Fields = array_merge($this->VirtualFields, $this->Fields); +// $this->Fields = array_merge_recursive2($this->VirtualFields, $this->Fields); } }