StopTag = $tag; } function StoreSkipMode() { $this->SkipMode = $this->Parser->SkipMode; } function RestoreSkipMode() { $this->Parser->SetSkipMode($this->SkipMode); } function RestoreThisLevelSkipMode() { $this->SkipMode = $this->Parser->Recursion[$this->Parser->RecursionIndex]->SkipMode; } function SuggestSkipMode($mode) { if ($mode >= 1) //if we need to skip - always forcing it $this->Parser->SetSkipMode($mode); else { //if we need to turn of skipping if ($this->SkipMode == parse) //check if initially skipping was off $this->Parser->SetSkipMode(parse); //set it to off only then } } function GetLogic() { if ($this->Parser->SkipMode != parse) { $this->Logic = false; return; } $check = $this->GetParam('check'); if ($check) { if (strpos($check, '_') !== false) { list($prefix, $function) = explode('_', $check, 2); } else { $function = $check; $prefix = $this->Parser->GetParam('PrefixSpecial'); } } else { $prefix = $this->GetParam('prefix'); $function = $this->GetParam('function'); } $this->NP['prefix'] = $prefix; $this->NP['function'] = $function; $inverse = $this->GetParam('inverse'); if ($prefix !== false) { $tag =& new Tag('', $this->Parser); $tag->Tag = $function; $tmp = $this->Application->processPrefix($prefix); $tag->Processor = $tmp['prefix']; $tag->Prefix=$tmp['prefix']; $tag->Special=$tmp['special']; $tag->NamedParams = $this->NP; $this->Logic = $tag->DoProcessTag(); // echo " this->Logic : ".$this->Logic."
"; } else { $this->Logic = $function; } if($inverse) $this->Logic = !$this->Logic; } function Process() { switch ($this->Tag) { case 'if': case 'ifnot': $this->GetLogic(); $this->SetStopTag('endif'); //This recursion level should end when 'endif' is found $this->Parser->Recurve($this); //Saving current tag in parser recursion array $this->StoreSkipMode(); //Storing initial SkipMode if ($this->Logic) { $this->SuggestSkipMode(parse); //suggest we parse it } else { $this->SuggestSkipMode(skip); //suggest we don't parse it } break; case 'elseif': $if_logic = $this->Parser->Recursion[$this->Parser->RecursionIndex]->Logic; if (!$if_logic) { //if IF or ELSEIF above have not worked $this->GetLogic(); if ($this->Logic) { //ELSEIF should run $this->Parser->Recursion[$this->Parser->RecursionIndex]->Logic = $this->Logic; //To escape running ELSE or ELSEIF below $this->SuggestSkipMode(parse); } else { //ELSEIF should NOT run $this->SuggestSkipMode(skip); } } else //IF or ELSEIF above HAVE worked - this ELSEIF should NOT run $this->SuggestSkipMode(skip); break; case 'else': $if_logic = $this->Parser->Recursion[$this->Parser->RecursionIndex]->Logic; $this->RestoreThisLevelSkipMode(); if (!$if_logic) { //IF was false - ELSE should run $this->SuggestSkipMode(parse); } else { //IF was true - ELSE should not run $this->SuggestSkipMode(skip); } break; } } function CheckRecursion(&$tag) { if ($this->CheckEndRecursion($tag)) { if (defined('EXPERIMENTAL_PRE_PARSE')) { if ($tag->Tag == 'if' || $tag->Tag == 'endif') { $this->Parser->AppendCompiledCode('}'); $this->Parser->ResetCode(); } } $this->RestoreSkipMode(); //Restoring original SkipMode return true; } else { if (defined('EXPERIMENTAL_PRE_PARSE')) { // && ($tag->Tag != 'RenderElement' && isset($tag->NP['_short_closing_'])) if ($tag->Tag != 'block' && $tag->Tag != 'DefineElement' && $tag->Tag != 'Capture' && !($tag->Tag == 'RenderElement' && isset($tag->NP['_short_closing_']))) { $this->Parser->AppendCode($tag->GetCode()); } // $this->Parser->AppendCompiledCode( $tag->GetCode() ); } } return false; } function CheckEndRecursion(&$tag) { if ($tag->GetParam('_closing_tag_') == 1 && $tag->Tag == $this->Tag) { return true; } return ($tag->Tag == $this->StopTag); //Tag matches StopTag we are waiting for to close current recursion } } class BlockTag extends ConstructTag { var $BlockName = ''; var $InsideBlock = 0; function Process() { switch ($this->Tag) { case 'block': case 'DefineElement': case 'RenderElement': if ($this->Tag == 'DefineElement') { $this->SetStopTag('end_define'); //This recursion level should end when 'blockend' is found } else { $this->SetStopTag('blockend'); //This recursion level should end when 'blockend' is found } if ($this->Tag == 'RenderElement') { $this->NP['name'] = '__lambda_element_'.abs(crc32($this->TemplateName)).'_'.$this->Application->LambdaElements++; $RenderTag =& new Tag($this->TagData.' name="'.$this->NP['name'].'"', $this->Parser); $this->Parser->AppendCode($RenderTag->GetCode()); } $this->Parser->Recurve($this); //Saving current tag in parser recursion array $this->Parser->SetBuffer(''); $this->BlockName = $this->NP['name']; //Stroing BlockName if (isset($this->NP['args']) ) { $this->Parser->Args = explode(',', $this->NP['args']); } $this->StoreSkipMode(); $this->SuggestSkipMode(skip_tags); //We need to skip tags from now break; } } function CheckRecursion(&$tag) { if (parent::CheckRecursion($tag)) { //if endtag matches (SkipMode would be restored then) //Creating template from buffer //if (defined('EXPERIMENTAL_PRE_PARSE') && isset($this->Application->PreParsedBlocks[$this->BlockName])) return true; $template = new Template(); $template->SetBody($this->Parser->GetBuffer()); //Adding template to application' cache $this->Application->TemplatesCache->SetTemplate($this->BlockName, $template, $this->Parser->TemplateName); if (defined('EXPERIMENTAL_PRE_PARSE')) { $code = $this->Parser->GetCode(); /*if ($this->Parser->UsedProcessors) { array_unshift($code, '$application->CheckProcessors(array("'.implode('", "', $this->Parser->UsedProcessors).'"));'); } $this->Parser->UsedProcessors = null;*/ array_unshift($code, '$o = \'\';'); array_unshift($code, '$application->Parser->SetParams($params, false);'); array_unshift($code, '$application =& kApplication::Instance();'); array_unshift($code, 'extract($params);'); $defaults = '$defaults = Array('; foreach ($this->NP as $name => $val) { if ($name == 'name') continue; $defaults .= '"'.$name.'" => "'.str_replace('"', '\"', $val).'",'; } $defaults .= ');'; array_unshift($code, '$params = array_merge_recursive2($defaults, $params);'); array_unshift($code, $defaults); $code[] = 'return $o;'; global $debugger; $dbg_functions = $this->Application->isDebugMode() && constOn('DBG_PRINT_PREPARSED'); $f_body = ''; //echo "
";
				$l = 0;
				if ($dbg_functions) echo "function ".$this->BlockName." {
"; foreach ($code as $line) { $l++; if ($dbg_functions) { echo $l.' '.$debugger->highlightString(trim($line)."\n", true); } $f_body .= "\t\t".rtrim($line, "\n")."\n"; } if ($dbg_functions) echo "} // function ".$this->BlockName." end

"; //echo "
"; //caching func body $this->Application->PreParsedCache[$this->BlockName] = $f_body; $compile_body = preg_replace('/\/\*COMPILE-ONLY\*\/.*/m', '', $f_body); $func = create_function('$params', $compile_body); $this->Application->PreParsedBlocks[$this->BlockName] = $func; $this->Parser->Args = null; $this->Parser->ResetCode(); $real_name = $this->Parser->AppendCompiledFunction($this->BlockName, $f_body); if ($this->Tag == 'RenderElement') { $RenderTag =& new Tag($this->TagData.' name="'.$this->BlockName.'"', $this->Parser); // $this->Parser->AppendCompiledCode($RenderTag->GetCode()); // for compilation run $RenderTag->Process(); } } return true; } else { // append the tag itself to the block - while in block, we check every tag to be 'blockend' // if it is not - we need to append the tag to the buffer, which we'll parse later in 'parse_block' //if ($tag->Tag != 'block') { if (defined('EXPERIMENTAL_PRE_PARSE') && isset($this->Application->PreParsedBlocks[$this->BlockName])) { return; } if (defined('EXPERIMENTAL_PRE_PARSE')) { // $this->Parser->AppendCode($tag->GetCode()); } else { $this->Parser->AppendOutput($tag->GetFullTag()); } //} return false; } } } class CaptureTag extends ConstructTag { var $VarName = null; var $Mode = CM_LATE_PARSE; function Process() { switch ($this->Tag) { case 'Capture': $this->Parser->Recurve($this); //Saving current tag in parser recursion array $this->Parser->SetBuffer(''); $this->VarName = $this->NP['to_var']; //Stroing BlockName $this->StoreSkipMode(); if (isset($this->NP['mode']) && $this->NP['mode'] == 'parse_now') { $this->Mode = CM_PARSE; } $this->SuggestSkipMode(skip_tags); break; } } function RunCapture($f, $func, $cur_lambda) { $code = array(); $code[] = '/*COMPILE-ONLY*/ '.$f[2]; $code[] = '/*LAMBDA-ONLY*/ $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'] = $application->PreParsedBlocks[\'capture_'.$this->VarName.$cur_lambda.'\'];'; $code[] = '$__f = $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'];'; $code[] = '$application->Parser->SetParam(\''.$this->VarName.'\', $__f(array())'.');'; $code[] = '$'.$this->VarName.' = $application->Parser->GetParam(\''.$this->VarName.'\');'; $code[] = '$params[\''.$this->VarName.'\'] = $'.$this->VarName.';'; if ($this->Parser->RecursionIndex > 1) { $this->Parser->AppendCode($code, -1); } else { $this->Application->Parser->SetParam($this->VarName, $func(array())); $this->Parser->AppendCompiledCode($code); } } function CheckRecursion(&$tag) { if (parent::CheckRecursion($tag)) { //if endtag matches (SkipMode would be restored then) $f_code = $this->Parser->GetCode(); array_unshift($f_code, '$o = \'\';'); array_unshift($f_code, '$application =& kApplication::Instance();'); $f_code[] = 'return $o;'; $f = $this->Parser->PrepareCompiledFunction('capture_'.$this->VarName, $f_code, false); $f_code = trim(join("\n\t", $f_code)); $func = create_function('$params', $f_code); $this->Application->PreParsedBlocks['capture_'.$this->VarName] = $func; $cur_lambda = $this->Application->LambdaElements++; $this->Application->PreParsedBlocks['capture_'.$this->VarName.$cur_lambda] = $func; $this->Parser->AppendCompiledCode($f[1]); if ($this->Mode == CM_PARSE) { $this->RunCapture($f, $func, $cur_lambda); } elseif ($this->Mode == CM_LATE_PARSE) { $code = array(); $code[] = '/*COMPILE-ONLY*/ '.$f[2]; $code[] = '/*LAMBDA-ONLY*/ $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'] = $application->PreParsedBlocks[\'capture_'.$this->VarName.$cur_lambda.'\'];'; $code[] = '$application->LateParsed[\''.$this->VarName.'\'] = '.$cur_lambda.';'; if ($this->Parser->RecursionIndex > 1) { $this->Parser->AppendCode($code, -1); } else { $this->Parser->AppendCompiledCode($code); } $this->Application->LateParsed[$this->VarName] = $cur_lambda; } $this->Parser->ResetCode(); return true; } return ($tag->Tag == $this->StopTag); //Tag matches StopTag we are waiting for to close current recursion } } ?>