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('/[{]{0,1}\$'.$key.'[}]{0,1}/i', $val, 1); //Do not sort every time
}
$this->SortParams(); //Sort once after adding is done
}
function GetParam($name)
{
//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[strtolower($name)] = $value;
}
function SetBuffer($body)
{
$this->Buffers[$this->RecursionIndex] = $body;
}
function GetBuffer()
{
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, $append_code=false)
{
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) {
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)
{
$real_name = 'f_'.abs(crc32($this->TemplateName)).'_'.$f_name;
if (defined('EXPERIMENTAL_PRE_PARSE')) {
// if such function already compiled
if ( isset($this->Application->CompiledFunctions[$f_name]) ||
function_exists($real_name)
)
{
if (!isset($this->Application->CompiledFunctions[$f_name])) {
$real_name = $real_name.'_';
}
else {
$real_name = $this->Application->CompiledFunctions[$f_name].'_';
}
}
$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 .= '}'."\n";
$this->Application->CompiledFunctions[$f_name] = $real_name;
}
}
function AppendCompiledCode($code)
{
if (defined('EXPERIMENTAL_PRE_PARSE')) {
if (is_array($code)) {
foreach ($code as $line) {
$this->CompiledBuffer .= "\t".rtrim($line, "\n")."\n";
}
}
else {
$this->CompiledBuffer .= $code;
}
$this->CompiledBuffer .= "\t".'echo $o;'."\n\t".'$o = \'\';'."\n";
}
}
function AppendCompiledHTML($append)
{
if (defined('EXPERIMENTAL_PRE_PARSE')) {
$this->CompiledBuffer .= '?'.'>'."\n";
$this->CompiledBuffer .= rtrim($append, "\t");
$this->CompiledBuffer .= '<'.'?php'."\n";
}
}
function ResetCode()
{
$this->Code[$this->RecursionIndex] = Array();
}
function FindTag2()
{
$openings = Array('<%' => '%>', ' Array('>', '/>'), ' '>', '' => '', '');
$tag_open_pos = false;
foreach ($openings as $an_opening => $closings) {
$pos = strpos($this->Template, $an_opening, $this->Position);
if ($pos !== false && ($tag_open_pos === false || (int) $pos <= (int) $tag_open_pos)) {
$tag_open_pos = $pos;
$open_len = strlen($an_opening);
$opening_tag = $an_opening;
$tag_closings = $closings;
}
}
if ($tag_open_pos === false) { //If no tags left - adding all other data
$this->AppendOutput(substr($this->Template, $this->Position), true);
return false;
}
//Adding all data before tag open
$this->AppendOutput(substr($this->Template, $this->Position, $tag_open_pos - $this->Position), true);
if (is_array($tag_closings)) {
$tag_close_pos = false;
foreach ($tag_closings as $a_closing) {
$pos = strpos($this->Template, $a_closing, $tag_open_pos);
if ($pos !== false && ($tag_close_pos === false || (int) $pos <= (int) $tag_close_pos)) {
$tag_close_pos = $pos;
$closing_tag = $a_closing;
}
}
}
elseif ($opening_tag == '') {
$closing_tag = '';
$tag_close_pos = $tag_open_pos + $open_len;
}
else {
$closing_tag = $tag_closings;
$tag_close_pos = strpos($this->Template, $closing_tag, $tag_open_pos);
}
$close_len = strlen($closing_tag);
//Cutting out the tag itself
$tag = substr($this->Template, $tag_open_pos + $open_len, $tag_close_pos - $tag_open_pos - $open_len);
if ($opening_tag == '') { //empty closing means old style in-portal if ....
$tag = 'm:endif';
}
if ($opening_tag == 'Params, 'PrefixSpecial');
$tag = $prefix.$tag;
}
// temporary - for backward compatability with in-portal style if
if ($opening_tag == '' && $tag_part != 'm_if' && $tag_part != 'm_DefineElement') {
if (strpos($the_tag, ' ') !== false) {
list($function, $params) = explode(' ', $the_tag, 2);
}
else {
$function = $the_tag;
$params = '';
}
$tag = 'm:if prefix="'.$prefix.'" function="'.$function.'" '.$params;
}
if ($opening_tag == '');
$tag = '__COMMENT__';
}
$this->Position = $tag_close_pos + $close_len;
return $tag;
}
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 CheckDir($dir)
{
if (file_exists($dir)) {
return;
}
else {
$segments = explode('/', $dir);
$cur_path = '';
foreach ($segments as $segment) {
// do not add leading / for windows paths (c:\...)
$cur_path .= preg_match('/^[a-zA-Z]{1}:/', $segment) ? $segment : '/'.$segment;
if (!file_exists($cur_path)) {
mkdir($cur_path);
}
}
}
}
function Parse($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 ($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 = str_replace(FULL_PATH, FULL_PATH.'/kernel/cache', $fname);
if (!defined('SAFE_MODE') || !SAFE_MODE) {
$this->CheckDir(dirname($fname));
}
$tname = $template_cache->GetRealFilename($this->TemplateName).'.tpl';
$output = '';
$is_cached = false;
ob_start();
if (defined('SAFE_MODE') && SAFE_MODE) {
$conn =& $this->Application->GetADODBConnection();
$cached = $conn->GetRow('SELECT * FROM '.TABLE_PREFIX.'Cache WHERE VarName = "'.$fname.'"');
if ($cached !== false && $cached['Cached'] > filemtime($tname)) {
eval('?'.'>'.$cached['Data']);
$is_cached = true;
}
}
else {
if (file_exists($fname) && filemtime($fname) > filemtime($tname)) {
include($fname);
$is_cached = true;
}
}
$output = ob_get_contents();
ob_end_clean();
if ( $is_cached && !$this->GetParam('from_inportal') ) {
if ( strpos($output, 'Application->recallObject('Inp1Parser');
$output = $inp1_parser->Parse($name, $output);
}
return $output;
}
$this->CompiledBuffer .= '<'.'?php'."\n";
$this->CompiledBuffer .= 'global $application;'."\n";
$this->CompiledBuffer .= '$params =& $application->Parser->Params;'."\n";
$this->CompiledBuffer .= '$o = \'\';'."\n";
}
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() && dbg_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 =& new MyTag($tag_data, $this);
$tag =& $this->TagHolder->GetTag($tag_data, $this);
if (!$this->CheckRecursion($tag)) //we do NOT process closing tags
{
$tag->Process();
}
}
if ( !$this->GetParam('from_inportal') ) {
if ( strpos($this->Output, 'Application->recallObject('Inp1Parser');
$this->Output = $inp1_parser->Parse($name, $this->Output);
$has_inp_tags = true;
}
}
if (defined('EXPERIMENTAL_PRE_PARSE') && $pre_parse && !$has_inp_tags) {
// $this->CompiledBuffer .= 'echo $o;'."\n";
$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($fname).','.$conn->qstr($this->CompiledBuffer).','.adodb_mktime().')');
}
else {
$compiled = fopen($fname, 'w');
fwrite($compiled, $this->CompiledBuffer);
fclose($compiled);
}
}
return $this->Output;
}
function ParseBlock($params, $force_pass_params=0, $as_template=false)
{
if( $this->Application->isDebugMode() && dbg_ConstOn('DBG_SHOW_TAGS') )
{
global $debugger;
$debugger->appendHTML('ParseBlock '.$params['name'].' pass_params is '.$params['pass_params'].' force is '.$force_pass_params.' in '.$debugger->getFileLink($debugger->getLocalFile(FULL_PATH.THEMES_PATH.'/'.$this->TemplateName).'.tpl', $this->CurrentLineNumber(), '', true));
}
/*if ( $this->Application->isDebugMode() && dbg_ConstOn('DBG_PRE_PARSE') ) {
global $debugger;
$debugger->CurrentPreParsedBlock = $params['name'];
}*/
if (defined('EXPERIMENTAL_PRE_PARSE')) {
$this->MainParser = false;
if (isset($this->Application->PreParsedBlocks[$params['name']]) ) {
if ($this->ParamsRecursionIndex == 0) {
$this->ParamsStack[$this->ParamsRecursionIndex] = $this->Params;
}
if (isset($params['pass_params']) || $force_pass_params) {
$pass_params = array_merge($this->ParamsStack[$this->ParamsRecursionIndex], $params);
}
else {
$pass_params = $params;
}
$this->ParamsStack[++$this->ParamsRecursionIndex] = $pass_params;
$this->Params = $pass_params;
$f = $this->Application->PreParsedBlocks[$params['name']];
// $this->ParamsRecursionIndex--;
//$this->SetParams($params);
if( !isset($pass_params['PrefixSpecial']) && isset($pass_params['prefix']) ) $pass_params['PrefixSpecial'] = $pass_params['prefix'];
$ret = $f($pass_params);
unset($this->ParamsStack[$this->ParamsRecursionIndex--]);
$this->Params = $this->ParamsStack[$this->ParamsRecursionIndex];
$this->MainParser = true;
return $ret;
}
}
$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'])) 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'];
$silent = getArrayValue($params, 'from_inportal') && !defined('DBG_TEMPLATE_FAILURE');
$o = $BlockParser->Parse(
$templates_cache->GetTemplateBody($params['name'], $silent),
$template_name
);
if (getArrayValue($params, 'BlockNoData') && !$BlockParser->DataExists) {
$template_name = $as_template ? $params['BlockNoData'] : $templates_cache->GetTemplateFileName($params['BlockNoData']) . '-block:'.$params['BlockNoData'];
$o = $BlockParser->Parse(
$templates_cache->GetTemplateBody($params['BlockNoData'], $silent),
$template_name
);
}
$this->Application->Parser =& $this;
$this->Application->Parser->DataExists = $this->Application->Parser->DataExists || $BlockParser->DataExists;
return $o;
}
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;
}
}
?>