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) { $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_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 $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 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, $as_template=false) { 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'])) 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']), $template_name ); $this->Application->Parser =& $this; 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; } } ?>