Tag = $tag; } function Open($tag) { if (!$this->_checkRequiredParams($tag)) { return false; } return ''; } /** * Checks, that all required attributes for tag are passed * * @param Array $tag * @return bool */ function _checkRequiredParams($tag) { $missing_params = array_diff($this->_requiredParams, array_keys($tag['NP'])); if (!$missing_params) { return true; } $error_msg = 'Tag ' . $this->Parser->TagInfo($tag, true) . ' called without required ' . implode(', ', $missing_params) . ' attribute'; if (count($missing_params) > 1) { $error_msg .= '(-s)'; } $this->Application->handleError(E_USER_ERROR, $error_msg, $tag['file'], $tag['line']); return false; } /** * All tags inside block tag are passed through to this method * Any returned result is appened to current level's buffer * This can be used to implement special handling of such tags as * * @param unknown_type $tag * @return unknown */ function PassThrough(&$tag) { return ''; } function Close($tag) { return $this->Parser->Buffers[$this->Parser->Level]; } function AppendCode(&$o, $code, $php_tags=true) { if ($php_tags) { $o .= ''; } else { $o .= ( is_array($code) ? "\t".implode("\n\t", $code)."\n" : $code); } } } class _Tag_Comment extends _BlockTag { function PassThrough(&$tag) { $tag['processed'] = true; } function Close($tag) { return ''; } } class _Tag_DefineElement extends _BlockTag { /*var $ElemName; function Open($tag) { $o = ''; $pointer = abs(crc32($tag['file'])).'_'.$tag['line']; $f_name = $tag['NP']['name'].'_'.$pointer; $this->ElemName = $tag['NP']['name']; $code[] = "\$_parser->Elements['{$tag['NP']['name']}'] = '$f_name';"; // function_exists is required here, because a template may be included more than once // leading to Cannot redeclare error $code[] = "if (!function_exists('{$f_name}')) {"; $code[] = "function $f_name(&\$_parser, \$params) {"; $code[] = "global \$application;"; $code[] = "if (!\$_output = \$_parser->CacheStart('{$pointer}')) {"; $defaults = $this->Parser->CompileParamsArray($tag['NP']); $code[] = "\$params = array_merge($defaults, \$params);"; $code[] = "if (!isset(\$params['PrefixSpecial']) && isset(\$params['prefix'])) {\$params['PrefixSpecial'] = \$params['prefix'];};"; $code[] = "extract(\$params);"; $code[] = "\$_parser->SetParams(\$params);"; $code[] = 'ob_start();'; $this->AppendCode($o, $code, false); return $o . '?'.'>'; } function Close($tag) { $o = $this->Parser->Buffers[$this->Parser->Level]; $code[] = "\$_parser->CacheEnd();\n"; $code[] = '$_output = ob_get_contents();'; $code[] = 'ob_end_clean();'; $code[] = '}'; $code[] = "return \$_output === true ? '' : \$_output;"; $code[] = '}}'; $code[] = "\$_parser->CachableElements['".$this->ElemName."'] = ".($this->Parser->Cachable[$this->Parser->Level] ? 'true':'false').';'; $o .= 'AppendCode($o, $code, false); return $o; // $this->Parser->Definitions .= $o."\n"; // return ''; } */ function _Tag_DefineElement($tag) { parent::_BlockTag($tag); $this->_requiredParams = Array ('name'); } function Open($tag) { $o = parent::Open($tag); $f_name = $tag['NP']['name'].'_'.abs(crc32($tag['file'])).'_'.$tag['line']; $code[] = "\$_parser->Elements['{$tag['NP']['name']}'] = '$f_name';"; // function_exists is required here, because a template may be included more than once // leading to Cannot redeclare error $code[] = "if (!function_exists('{$f_name}')) {"; $code[] = "function $f_name(&\$_parser, \$params) {"; $code[] = "global \$application;"; $defaults = $this->Parser->CompileParamsArray($tag['NP']); $code[] = "\$params = array_merge($defaults, \$params);"; $code[] = "if (!isset(\$params['PrefixSpecial']) && isset(\$params['prefix'])) {\$params['PrefixSpecial'] = \$params['prefix'];};"; $code[] = "extract(\$params);"; $code[] = "\$_parser->SetParams(\$params);"; $code[] = 'ob_start();'; $this->AppendCode($o, $code); return $o; } function Close($tag) { $o = $this->Parser->Buffers[$this->Parser->Level]; $code[] = '$_output = ob_get_contents();'; $code[] = 'ob_end_clean();'; $code[] = 'return $_output;'; $code[] = '}}'; $this->AppendCode($o, $code); return $o; } } class _Tag_Capture extends _Tag_DefineElement { function _Tag_Capture($tag) { parent::_Tag_DefineElement($tag); $this->_requiredParams = Array ('to_var'); } function Open($tag) { if (!$this->_checkRequiredParams($tag)) { return false; } $tag['NP']['name'] = '__capture_'.$tag['NP']['to_var']; $o = ''; // $this->AppendCode($o, "\$_parser->Captures['{$tag['NP']['to_var']}'] = 1;", false); $this->AppendCode($o, "\$_parser->Captures['{$tag['NP']['to_var']}'] = 1;"); $o .= parent::Open($tag); return $o; } } class _Tag_RenderElement extends _Tag_DefineElement { var $Single = true; var $OriginalTag; function _Tag_RenderElement($tag) { parent::_Tag_DefineElement($tag); if (!$tag['is_closing']) { $this->_requiredParams = Array ('design'); } } function Open($tag) { if (!$this->_checkRequiredParams($tag)) { return false; } $o = ''; if ($tag['is_closing']) { if (isset($tag['NP']['design'])) { $this->RenderDesignCode($o, $tag['NP']); return $o; } $to_pass = $this->Parser->CompileParamsArray($tag['NP']); /* $pointer = abs(crc32($tag['file'])).'_'.$tag['line']; // $code[] = "}"; // $code[] = "if (!\$_parser->CachableElements['".$tag['NP']['name']."']) {"; // $code[] = "\$_parser->CacheEndInside();"; // $code[] = "}"; $o .= 'AppendCode($o, $this->Parser->BreakCache('', $pointer.'a', "\$_parser->CachableElements['".$tag['NP']['name']."']"), false); $this->AppendCode($o, "echo (\$_parser->ParseBlock($to_pass));\n", false); $this->AppendCode($o, $this->Parser->BreakCache('', $pointer.'b') . " ?".">\n", false); // $this->AppendCode($o, "if (!\$_parser->CacheStartOrContinue(\$_parser->CachableElements['".$tag['NP']['name']."'], '{$pointer}')) {".' ?'.'>', false); */ $this->AppendCode($o, "echo (\$_parser->ParseBlock($to_pass));"); return $o; } $this->Single = false; $this->OriginalTag = $tag; $tag['NP']['name'] = '__lambda'; return parent::Open($tag); } function RenderDesignCode(&$o, $params) { $to_pass = $this->Parser->CompileParamsArray($params); $code[] = "echo (\$_parser->ParseBlock(array_merge($to_pass, array('name'=>'{$params['design']}','content'=>\$_parser->ParseBlock($to_pass), 'keep_data_exists'=>1))));"; $this->AppendCode($o, $code); } function Close($tag) { if ($this->Single) { return $this->Parser->Buffers[$this->Parser->Level]; } $o = parent::Close($tag); $this->OriginalTag['NP']['name'] = '__lambda'; $this->RenderDesignCode($o, $this->OriginalTag['NP']); return $o; } } class _Tag_Param extends _BlockTag { function _Tag_Param($tag) { parent::_BlockTag($tag); $this->_requiredParams = Array ('name'); } function Open($tag) { $o = parent::Open($tag); $code[] = "if (isset(\$_parser->Captures['{$tag['NP']['name']}'])) {"; $code[] = "\${$tag['NP']['name']} = \$_parser->ParseBlock(array('name' => '__capture_{$tag['NP']['name']}'));"; $code[] = "\$params['{$tag['NP']['name']}'] = \${$tag['NP']['name']};"; $code[] = "}"; $code[] = "echo (\${$tag['NP']['name']});"; $this->AppendCode($o, $code); return $o; } } class _Tag_Include extends _BlockTag { function Open($tag) { $o = ''; $to_pass = $this->Parser->CompileParamsArray($tag['NP']); $this->AppendCode($o, "echo (\$_parser->IncludeTemplate($to_pass))"); return $o; } } class _Tag_If extends _BlockTag { /** * Permanently inverses if tag (used in ifnot tag) * * @var bool */ var $_Inversed = false; function _Tag_If($tag) { parent::_BlockTag($tag); $this->_requiredParams = Array ('check'); } function Open($tag) { $o = parent::Open($tag); $to_pass = $this->Parser->CompileParamsArray($tag['NP']); $code[] = "\$_splited = \$_parser->SplitTag(array('tag'=>\"{$tag['NP']['check']}\", 'file'=>'{$tag['file']}', 'line'=>{$tag['line']}));"; $code[] = 'if ($_splited[\'prefix\'] == \'__auto__\') {$_splited[\'prefix\'] = $PrefixSpecial;}'; $code[] = '$_p_ =& $_parser->GetProcessor($_splited[\'prefix\']);'; if (isset($tag['NP']['inverse']) || $this->_Inversed) { $code[] = "if (!\$_p_->ProcessParsedTag(\$_splited['name'], $to_pass, \$_splited['prefix'], '{$tag['file']}', {$tag['line']})) {"; } else { $code[] = "if (\$_p_->ProcessParsedTag(\$_splited['name'], $to_pass, \$_splited['prefix'], '{$tag['file']}', {$tag['line']})) {"; } $this->AppendCode($o, $code); return $o; } function PassThrough(&$tag) { $o = ''; if ($tag['name'] == 'else') { $this->AppendCode($o, '} else {'); $tag['processed'] = true; } if ($tag['name'] == 'elseif') { if (!$this->_checkRequiredParams($tag)) { return ''; } $to_pass = $this->Parser->CompileParamsArray($tag['NP']); $code[] = "\$_splited = \$_parser->SplitTag(array('tag'=>\"{$tag['NP']['check']}\", 'file'=>'{$tag['file']}', 'line'=>{$tag['line']}));"; $code[] = 'if ($_splited[\'prefix\'] == \'__auto__\') {$_splited[\'prefix\'] = $PrefixSpecial;}'; $code[] = '$_p_ =& $_parser->GetProcessor($_splited[\'prefix\']);'; if (isset($tag['NP']['inverse']) || $this->_Inversed) { $code[] = "} else if (!\$_p_->ProcessParsedTag(\$_splited['name'], $to_pass, \$_splited['prefix'], '{$tag['file']}', {$tag['line']})) {"; } else { $code[] = "} else if (\$_p_->ProcessParsedTag(\$_splited['name'], $to_pass, \$_splited['prefix'], '{$tag['file']}', {$tag['line']})) {"; } $this->AppendCode($o, $code); $tag['processed'] = true; } return $o; } function Close($tag) { $o = $this->Parser->Buffers[$this->Parser->Level]; $this->AppendCode($o, "}\n"); return $o; } } class _Tag_IfNot extends _Tag_If { function _Tag_IfNot($tag) { parent::_Tag_If($tag); $this->_Inversed = true; } } class _Tag_DefaultParam extends _BlockTag { function Open($tag) { $o = ''; foreach ($tag['NP'] as $key => $val) { $code[] = 'if (!isset($'.$key.')) $params[\''.$key.'\'] = \''.$val.'\';'; $code[] = '$'.$key.' = isset($'.$key.') ? $'.$key.' : \''.$val.'\';'; } $this->AppendCode($o, $code); return $o; } } class _Tag_Cache extends _BlockTag { function Open($tag) { $pointer = abs(crc32($tag['file'])).'_'.$tag['line']; $o = ''; $this->AppendCode($o, "if (!\$_parser->CacheStart('{$pointer}')) {\n"); return $o; } function Close($tag) { $o = $this->Parser->Buffers[$this->Parser->Level]; $this->AppendCode($o, "\$_parser->CacheEnd();\n}\n"); return $o; } }