Index: trunk/core/kernel/parser/template_parser.php =================================================================== diff -u -r932 -r1339 --- trunk/core/kernel/parser/template_parser.php (.../template_parser.php) (revision 932) +++ trunk/core/kernel/parser/template_parser.php (.../template_parser.php) (revision 1339) @@ -1,6 +1,6 @@ Ses =& $this->Application->recallObject('Session'); + + if (defined('EXPERIMENTAL_PRE_PARSE')) { + $conn =& $this->Application->GetADODBConnection(); + if (isset($this->Application->PreParsedBlocks) && is_array($this->Application->PreParsedBlocks)) return; + $data = $conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "blocks_cache"'); + if ($data && $data['Cached'] > (time() - 3600) ) { + $blocks = unserialize($data['Data']); + foreach ($blocks as $name => $f_body) { + $func = create_function('$params', $f_body); + $this->Application->PreParsedBlocks[$name] = $func; + } + $cached = $data['Cached']; + } + else { + $cached = 0; + } + } } function AddParam($pattern, $value, $dont_sort=0) @@ -57,22 +80,20 @@ if (!is_array($params)) $params = Array(); $this->Params = $params; foreach ($params as $key => $val) { - $this->AddParam('/\$'.$key.'/', $val, 1); //Do not sort every time + $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) { - if (isset($this->Params[$name])) - return $this->Params[$name]; - else - return false; + //return isset($this->Params[strtolower($name)]) ? $this->Params[strtolower($name)] : false; + return isset($this->Params[$name]) ? $this->Params[$name] : false; } function SetParam($name, $value) { - $this->Params[$name] = $value; + $this->Params[strtolower($name)] = $value; } function SetBuffer($body) @@ -85,20 +106,82 @@ return $this->Buffers[$this->RecursionIndex]; } + function GetCode() + { + return $this->Code[$this->RecursionIndex]; + } + function AppendBuffer($append) { $this->Buffers[$this->RecursionIndex] .= $append; + $this->AppendCode( $this->ConvertToCode($append) ); } - function AppendOutput($append) + function AppendOutput($append, $append_code=false) { - if ($this->SkipMode == parse) + if ($this->SkipMode == parse) { $this->Output .= $append; //append to Ouput only if we are parsing + if ($append_code) $this->AppendCompiledHTML($append); + } elseif ($this->SkipMode == skip_tags) { $this->AppendBuffer($append); //append to buffer if we are skipping tags } } + function ConvertToCode($data) + { + $code = '$o .= \''. str_replace("'", "\'", $data) .'\';'; + $code = explode("\n", $code); + return $code; + } + + function AppendCode($code) + { + if (defined('EXPERIMENTAL_PRE_PARSE')) { + if (!isset($this->Code[$this->RecursionIndex])) { + $this->Code[$this->RecursionIndex] = Array(); + } + if (is_array($code)) { + foreach ($code as $line) { + $this->Code[$this->RecursionIndex][] = rtrim($line, "\n")."\n"; + } + } + else { + $this->Code[$this->RecursionIndex][] .= rtrim($code, "\n")."\n"; + } + } + } + + function AppendCompiledFunction($f_name, $f_body) + { + if (defined('EXPERIMENTAL_PRE_PARSE')) { + $this->CompiledBuffer .= 'function '.$f_name.'($params)'."\n{\n"; + $this->CompiledBuffer .= $f_body; + $this->CompiledBuffer .= "}\n\n"; + } + } + + function AppendCompiledCode($code) + { + if (defined('EXPERIMENTAL_PRE_PARSE')) { + $this->CompiledBuffer .= $code; + } + } + + function AppendCompiledHTML($append) + { + if (defined('EXPERIMENTAL_PRE_PARSE')) { + $this->CompiledBuffer .= '?'.'>'."\n"; + $this->CompiledBuffer .= $append; + $this->CompiledBuffer .= '<'.'?php'."\n"; + } + } + + function ResetCode() + { + $this->Code[$this->RecursionIndex] = Array(); + } + function FindTag() { $tagOpen = strpos($this->Template, '<%', $this->Position); //Finding tag start @@ -128,57 +211,77 @@ return $tag; } - function Parse($template) + function CurrentLineNumber() { + return substr_count(substr($this->Template, 0, $this->Position), "\n")+1; + } + + function SkipModeName() + { + switch ($this->SkipMode) { + case skip: return 'skip'; + case skip_tags: return 'skip_tags'; + case parse: return 'parse'; + } + } + + function Parse($template, $name='unknown') + { $this->Template = $template; + $this->TemplateName = $name; $this->Position = 0; $this->Output = ''; + $this->CompiledBuffer .= '<'.'?php'."\n"; //While we have more tags while ($tag_data = $this->FindTag()) { //Create tag object from passed tag data + if( $this->Application->isDebugMode() && dbg_ConstOn('DBG_SHOW_TAGS') ) + { + global $debugger; + $debugger->appendHTML('mode: '.$this->SkipModeName().' tag '.$debugger->highlightString($tag_data).' in '.$debugger->getFileLink($debugger->getLocalFile(DOC_ROOT.BASE_PATH.TEMPLATES_PATH.'/'.$this->TemplateName).'.tpl', $this->CurrentLineNumber(), '', true)); + } $tag =& new Tag($tag_data, $this); if (!$this->CheckRecursion($tag)) //we do NOT process closing tags { $tag->Process(); } } + $this->CompiledBuffer .= '?'.'>'."\n"; return $this->Output; } - function ParseBlock($params, $force_pass_params=0) + function ParseBlock($params, $force_pass_params=0, $as_template=false) { - $BlockParser =& $this->Application->Factory->makeClass('TemplateParser'); + if (defined('EXPERIMENTAL_PRE_PARSE')) { + if (isset($this->Application->PreParsedBlocks[$params['name']]) ) { + $f = $this->Application->PreParsedBlocks[$params['name']]; + //$this->SetParams($params); + return $f($params); + } + } + + $BlockParser =& $this->Application->makeClass('TemplateParser'); if (isset($params['pass_params']) || $force_pass_params) { $BlockParser->SetParams(array_merge($this->Params, $params)); } else $BlockParser->SetParams($params); $this->Application->Parser =& $BlockParser; - if (!isset($params['name'])) die("***Error: Block name not passed to ParseBlock
"); + if (!isset($params['name'])) trigger_error('***Error: Block name not passed to ParseBlock', E_USER_ERROR); $templates_cache =& $this->Application->recallObject('TemplatesCache'); + + $template_name = $as_template ? $params['name'] : $templates_cache->GetTemplateFileName($params['name']) . '-block:'.$params['name']; + $o = $BlockParser->Parse( - $templates_cache->GetTemplateBody($params['name']) + $templates_cache->GetTemplateBody($params['name']), + $template_name ); $this->Application->Parser =& $this; return $o; } - function ParseXML($template, $params) - { - $templates_cache =& $this->Application->recallObject('TemplatesCache'); - $xml = $templates_cache->GetTemplateBody($template); - - $PreParser =& new TemplateParser(); - $PreParser->SetParams($params); - $this->Application->Parser =& $PreParser; - $xml = $PreParser->Parse($xml); - $this->Application->Parser =& $this; - $XMLParser =& new XMLParser($params); - $this->AppendOutput($XMLParser->Parse($xml)); - } - function Recurve(&$tag) { $this->Recursion[++$this->RecursionIndex] =& $tag; @@ -201,32 +304,4 @@ } } -// ################### TESTS ############################ - -global $suite; -if (isset($suite)) { - class TestTemplateParser extends TestCase { - function testFindTag() - { - $parser =& new TemplateParser(); - $parser->Template = 'before<%first_tag%>between<%second_tag%>after'; - $this->assertEquals('first_tag', $parser->FindTag()); - $this->assertEquals('second_tag', $parser->FindTag()); - $parser->FindTag(); - $this->assertEquals('beforebetweenafter', $parser->Output); - } - - function testAppendOutput() - { - $parser =& new TemplateParser(); - $parser->AppendOutput('1'); - $this->assertEquals('1', $parser->Output); - $parser->SetSkipMode(skip); - $parser->AppendOutput('2'); - $this->assertEquals('1', $parser->Output); - } - } - $suite->addTest(new TestSuite("TestTemplateParser")); -} - ?> \ No newline at end of file