Index: trunk/core/kernel/parser/template_parser.php =================================================================== diff -u -N -r5219 -r6093 --- trunk/core/kernel/parser/template_parser.php (.../template_parser.php) (revision 5219) +++ trunk/core/kernel/parser/template_parser.php (.../template_parser.php) (revision 6093) @@ -44,8 +44,10 @@ function SortParams() { uasort($this->ForSort, array ("TemplateParser", "CmpParams")); - $this->Pattern = Array(); - $this->Values = Array(); + +// commented out by Kostja, otherwise when rednerElement is done into var (result_to_var) the other params are reset +// $this->Pattern = Array(); +// $this->Values = Array(); foreach($this->ForSort as $pair) { $this->Pattern[] = $pair[0]; @@ -61,23 +63,35 @@ return $a_len > $b_len ? -1 : 1; } - function SetParams($params) + function SetParams($params, $for_parsing=true) { if (!is_array($params)) $params = Array(); $this->ForSort = array(); $this->Params = $params; $this->ParamsStack[$this->ParamsRecursionIndex] = $params; + if (!$for_parsing) return ; + foreach ($params as $key => $val) { $this->AddParam('/[{]{0,1}\$'.$key.'[}]{0,1}/i', $val, 1); //Do not sort every time } $this->SortParams(); //Sort once after adding is done } - function GetParam($name) + /** + * Returns parser parameter value at specified deep level + * + * @param string $name + * @param int $deep_level if greather then 0 then use from ParamsStack + * @return mixed + */ + function GetParam($name, $deep_level = 0) { - //return isset($this->Params[strtolower($name)]) ? $this->Params[strtolower($name)] : false; + if ($deep_level > 0) { + return isset($this->ParamsStack[$deep_level][$name]) ? $this->ParamsStack[$deep_level][$name] : false; + } + return isset($this->Params[$name]) ? $this->Params[$name] : false; } @@ -90,7 +104,7 @@ function SetParam($name, $value) { $this->Params[strtolower($name)] = $value; - $this->AddParam('/[{]{0,1}\$'.$name.'[}]{0,1}/i', $val, 0); + $this->AddParam('/[{]{0,1}\$'.$name.'[}]{0,1}/i', $value, $this->FromPreParseCache); } function SetBuffer($body) @@ -169,14 +183,11 @@ } } + $this->CompiledBuffer .= "\t".'$application->PreParsedBlocks[\''.$f_name.'\'] = \''.$real_name.'\';'."\n"; $this->CompiledBuffer .= 'if (!function_exists(\''.$real_name.'\')) {'."\n"; - - - $this->CompiledBuffer .= "\t".'$application->PreParsedBlocks[\''.$f_name.'\'] = \''.$real_name.'\';'; - $this->CompiledBuffer .= "\n\t".'function '.$real_name.'($params)'."\n\t{\n"; - $this->CompiledBuffer .= $f_body; - $this->CompiledBuffer .= "\t}\n\n"; - + $this->CompiledBuffer .= "\t".'function '.$real_name.'($params)'."\n\t{\n"; + $this->CompiledBuffer .= $f_body; + $this->CompiledBuffer .= "\t}\n\n"; $this->CompiledBuffer .= '}'."\n"; $this->Application->CompiledFunctions[$f_name] = $real_name; @@ -256,6 +267,16 @@ } $close_len = strlen($closing_tag); + + // Cutting trailing line-breaks after tags (same way PHP does it) + if (substr($this->Template, $tag_close_pos+$close_len, 2) == "\r\n") { + $this->Template = substr_replace($this->Template, '', $tag_close_pos, 2); + } + elseif (substr($this->Template, $tag_close_pos+$close_len, 1) == "\n") { + $this->Template = substr_replace($this->Template, '', $tag_close_pos, 1); + } + + //Cutting out the tag itself $tag = substr($this->Template, $tag_open_pos + $open_len, $tag_close_pos - $tag_open_pos - $open_len); @@ -296,7 +317,7 @@ // if there is no prefix for the tag if (strpos($tag, ':') === 0) { $prefix = getArrayValue($this->Params, 'PrefixSpecial'); - $tag = $prefix.$tag; + $tag = $prefix.$tag.' _auto_prefix_="1"'; } // temporary - for backward compatability with in-portal style if @@ -312,7 +333,7 @@ } if ($opening_tag == ''); + $this->AppendOutput(''); $tag = '__COMMENT__'; } @@ -334,14 +355,23 @@ } } - function CheckDir($dir) + /** + * Recursive mkdir + * + * @param string $dir + * @param string $base_path base path to directory where folders should be created in + */ + function CheckDir($dir, $base_path = '') { if (file_exists($dir)) { return; } else { + // remove $base_path from beggining because it is already created during install + $dir = preg_replace('/^'.preg_quote($base_path.'/', '/').'/', '', $dir, 1); $segments = explode('/', $dir); - $cur_path = ''; + $cur_path = $base_path; + foreach ($segments as $segment) { // do not add leading / for windows paths (c:\...) $cur_path .= preg_match('/^[a-zA-Z]{1}:/', $segment) ? $segment : '/'.$segment; @@ -352,6 +382,97 @@ } } + function ParseTemplate($name, $pre_parse = 1, $params=array(), $silent=0) + { + $this->FromPreParseCache = false; + if ($this->GetParam('from_inportal')) $pre_parse = 0; + if ($pre_parse) { + $pre_parsed = $this->Application->TemplatesCache->GetPreParsed($name); + if ($pre_parsed && $pre_parsed['active']) { // active means good (not expired) pre-parsed cache + $this->FromPreParseCache = true; + $this->SetParams($params, 0); // 0 to disable params sorting and regexp generation - not needed when processing pre-parsed + ob_start(); + if ($pre_parsed['mode'] == 'file') { + include($pre_parsed['fname']); + } + else { + eval('?'.'>'.$pre_parsed['content']); + } + $output = ob_get_contents(); + ob_end_clean(); + } + else { + $this->SetParams($params); + + $this->CompiledBuffer .= '<'.'?php'."\n"; + $this->CompiledBuffer .= 'global $application;'."\n"; + + $this->CompiledBuffer .= '$params =& $application->Parser->Params;'."\n"; + $this->CompiledBuffer .= 'extract($params);'."\n"; + + $this->CompiledBuffer .= '$o = \'\';'."\n"; + + $output = $this->NewParse($this->Application->TemplatesCache->GetTemplateBody($name, $silent), $name); + + $this->CompiledBuffer .= '?'.'>'."\n"; + + if (defined('SAFE_MODE') && SAFE_MODE) { + if (!isset($conn)) $conn =& $this->Application->GetADODBConnection(); + $conn->Query('REPLACE INTO '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ('.$conn->qstr($pre_parsed['fname']).','.$conn->qstr($this->CompiledBuffer).','.adodb_mktime().')'); + } + else { + $compiled = fopen($pre_parsed['fname'], 'w'); + fwrite($compiled, $this->CompiledBuffer); + fclose($compiled); + } + + } + if ( !$this->GetParam('from_inportal') && strpos($output, 'Application->recallObject('Inp1Parser'); + $output = $inp1_parser->Parse($name, $output); + } + return $output; + } + + // pre-parse is OFF + $this->SetParams($params); + return $this->NewParse($this->Application->TemplatesCache->GetTemplateBody($name), $name, $pre_parse); + } + + function NewParse($template, $name='unknown', $pre_parse = 1) + { + $this->Template = $template; + $this->TemplateName = $name; + $this->Position = 0; + $this->Output = ''; + $this->TagHolder = new MyTagHolder(); + + $has_inp_tags = false; + + if (!getArrayValue($this->Params, 'PrefixSpecial')) { + $this->Params['PrefixSpecial'] = '$PrefixSpecial'; + } + + //While we have more tags + while ($tag_data = $this->FindTag2()) + { + if ($tag_data == '__COMMENT__') continue; + //Create tag object from passed tag data + if( $this->Application->isDebugMode() && constOn('DBG_SHOW_TAGS') ) + { + global $debugger; + $debugger->appendHTML('mode: '.$this->SkipModeName().' tag '.$debugger->highlightString($tag_data).' in '.$debugger->getFileLink($debugger->getLocalFile(FULL_PATH.THEMES_PATH.'/'.$this->TemplateName).'.tpl', $this->CurrentLineNumber(), '', true)); + } + $tag =& $this->TagHolder->GetTag($tag_data, $this); + + if (!$this->CheckRecursion($tag)) //we do NOT process closing tags + { + $tag->Process(); + } + } + return $this->Output; + } + function Parse($template, $name='unknown', $pre_parse = 1) { $this->Template = $template; @@ -365,16 +486,15 @@ if ($this->GetParam('from_inportal')) $pre_parse = 0; if (defined('EXPERIMENTAL_PRE_PARSE') && $pre_parse) { - $template_cache =& $this->Application->recallObject('TemplatesCache'); - $fname = $template_cache->GetRealFilename($this->TemplateName).'.php'; + $fname = $this->Application->TemplatesCache->GetRealFilename($this->TemplateName).'.php'; $fname = str_replace(FULL_PATH, FULL_PATH.'/kernel/cache', $fname); if (!defined('SAFE_MODE') || !SAFE_MODE) { - $this->CheckDir(dirname($fname)); + $this->CheckDir(dirname($fname), FULL_PATH.'/kernel/cache'); } - $tname = $template_cache->GetRealFilename($this->TemplateName).'.tpl'; + $tname = $this->Application->TemplatesCache->GetRealFilename($this->TemplateName).'.tpl'; $output = ''; $is_cached = false; ob_start();