Ses =& $this->Application->recallObject('Session');
}
function AddParam($pattern, $value, $dont_sort=0)
{
$this->ForSort[] = Array($pattern, $value);
if (!$dont_sort) //used when mass-adding params, to escape sorting after every new param
$this->SortParams(); //but do sort by default!
}
//We need to sort params by its name length desc, so that params starting with same word get parsed correctly
function SortParams()
{
uasort($this->ForSort, array ("TemplateParser", "CmpParams"));
$this->Pattern = Array();
$this->Values = Array();
foreach($this->ForSort as $pair)
{
$this->Pattern[] = $pair[0];
$this->Values[] = $pair[1];
}
}
function CmpParams($a, $b)
{
$a_len = strlen($a[0]);
$b_len = strlen($b[0]);
if ($a_len == $b_len) return 0;
return $a_len > $b_len ? -1 : 1;
}
function SetParams($params)
{
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->SortParams(); //Sort once after adding is done
}
function GetParam($name)
{
if (isset($this->Params[$name]))
return $this->Params[$name];
else
return false;
}
function SetParam($name, $value)
{
$this->Params[$name] = $value;
}
function SetBuffer($body)
{
$this->Buffers[$this->RecursionIndex] = $body;
}
function GetBuffer()
{
return $this->Buffers[$this->RecursionIndex];
}
function AppendBuffer($append)
{
$this->Buffers[$this->RecursionIndex] .= $append;
}
function AppendOutput($append)
{
if ($this->SkipMode == parse)
$this->Output .= $append; //append to Ouput only if we are parsing
elseif ($this->SkipMode == skip_tags) {
$this->AppendBuffer($append); //append to buffer if we are skipping tags
}
}
function FindTag()
{
$tagOpen = strpos($this->Template, '<%', $this->Position); //Finding tag start
$inp_tag = false;
$tagOpenLen = 2;
if ($tagOpen === false) { //If not tags left - adding all other data
$this->AppendOutput(substr($this->Template, $this->Position));
return false;
}
//Adding all data before tag open
$this->AppendOutput(substr($this->Template, $this->Position, $tagOpen - $this->Position));
//Finding tag end
$tagCloseLen = 2;
$tagClose = strpos($this->Template, "%>", $tagOpen);
if ($tagClose === false) die ("Can't find tag closing");
//Cutting out the tag itself
$tag = substr($this->Template, $tagOpen + $tagOpenLen, $tagClose - $tagOpen - $tagOpenLen);
//Seting current position right after the tag
$this->Position = $tagClose + $tagCloseLen;
return $tag;
}
function Parse($template)
{
$this->Template = $template;
$this->Position = 0;
$this->Output = '';
//While we have more tags
while ($tag_data = $this->FindTag())
{
//Create tag object from passed tag data
$tag =& new Tag($tag_data, $this);
if (!$this->CheckRecursion($tag)) //we do NOT process closing tags
{
$tag->Process();
}
}
return $this->Output;
}
function ParseBlock($params, $force_pass_params=0)
{
$BlockParser =& $this->Application->Factory->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
");
$templates_cache =& $this->Application->recallObject('TemplatesCache');
$o = $BlockParser->Parse(
$templates_cache->GetTemplateBody($params['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;
}
function CheckRecursion(&$tag)
{
if ($this->RecursionIndex > 0) { //If we are inside the recursion
if ($this->Recursion[$this->RecursionIndex]->CheckRecursion($tag)) { //If we can close this recursion
unset($this->Recursion[$this->RecursionIndex--]); //unsetting current recursion level and decreasing it at the same time
return true; //we should inform not to process closing tag
}
}
return false;
}
function SetSkipMode($mode)
{
$this->SkipMode = $mode;
}
}
// ################### 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"));
}
?>