📄 smarty_compiler.class.php
字号:
}
foreach ( $attrs as $arg_name => $arg_value )
{
if ( $arg_name == "file" )
{
$include_file = $arg_value;
continue;
}
else
{
if ( $arg_name == "assign" )
{
$assign_var = $arg_value;
}
}
if ( is_bool( $arg_value ) )
{
$arg_value = $arg_value ? "true" : "false";
}
$arg_list[] = "'{$arg_name}' => {$arg_value}";
}
$output = "<?php ";
if ( isset( $assign_var ) )
{
$output .= "ob_start();\n";
}
$output .= "\$_smarty_tpl_vars = \$this->_tpl_vars;\n\$this->_smarty_include(".$include_file.", array(".implode( ",", ( array )$arg_list )."));\n"."\$this->_tpl_vars = \$_smarty_tpl_vars;\n"."unset(\$_smarty_tpl_vars);\n";
if ( isset( $assign_var ) )
{
$output .= "\$this->assign(".$assign_var.", ob_get_contents()); ob_end_clean();\n";
}
$output .= " ?>";
return $output;
}
function _compile_include_php_tag( $tag_args )
{
$attrs = $this->_parse_attrs( $tag_args );
if ( empty( $attrs['file'] ) )
{
$this->_syntax_error( "missing 'file' attribute in include_php tag" );
return false;
}
$this->_parse_file_path( $this->trusted_dir, $this->_dequote( $attrs['file'] ), $resource_type, $resource_name );
if ( $this->security )
{
if ( $resource_type != "file" || !is_file( $resource_name ) )
{
$this->_syntax_error( "include_php: {$resource_type}: {$resource_name} is not readable" );
return false;
}
if ( !$this->_is_trusted( $resource_type, $resource_name ) )
{
$this->_syntax_error( "include_php: {$resource_type}: {$resource_name} is not trusted" );
return false;
}
}
if ( !empty( $attrs['assign'] ) )
{
$output = "<?php ob_start();\n";
$output .= "include('".$resource_name."');\n";
$output .= "\$this->assign(".$this->_dequote( $attrs['assign'] ).", ob_get_contents()); ob_end_clean();\n?>";
}
else
{
$output = "<?php include('".$resource_name."'); ?>";
}
return $output;
}
function _compile_section_start( $tag_args )
{
$attrs = $this->_parse_attrs( $tag_args );
$arg_list = array( );
$output = "<?php ";
$section_name = $attrs['name'];
if ( empty( $section_name ) )
{
$this->_syntax_error( "missing section name" );
}
$output .= "if (isset(\$this->_sections[{$section_name}])) unset(\$this->_sections[{$section_name}]);\n";
$section_props = "\$this->_sections[{$section_name}]";
foreach ( $attrs as $attr_name => $attr_value )
{
switch ( $attr_name )
{
case "loop" :
$output .= "{$section_props}['loop'] = is_array({$attr_value}) ? count({$attr_value}) : max(0, (int){$attr_value});\n";
break;
case "show" :
if ( is_bool( $attr_value ) )
{
$show_attr_value = $attr_value ? "true" : "false";
}
else
{
$show_attr_value = "(bool){$attr_value}";
}
$output .= "{$section_props}['show'] = {$show_attr_value};\n";
break;
case "name" :
$output .= "{$section_props}['{$attr_name}'] = {$attr_value};\n";
break;
case "max" :
case "start" :
$output .= "{$section_props}['{$attr_name}'] = (int){$attr_value};\n";
break;
case "step" :
$output .= "{$section_props}['{$attr_name}'] = ((int){$attr_value}) == 0 ? 1 : (int){$attr_value};\n";
break;
default :
$this->_syntax_error( "unknown section attribute - '{$attr_name}'" );
break;
}
}
if ( !isset( $attrs['show'] ) )
{
$output .= "{$section_props}['show'] = true;\n";
}
if ( !isset( $attrs['loop'] ) )
{
$output .= "{$section_props}['loop'] = 1;\n";
}
if ( !isset( $attrs['max'] ) )
{
$output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
}
else
{
$output .= "if ({$section_props}['max'] < 0)\n"." {$section_props}['max'] = {$section_props}['loop'];\n";
}
if ( !isset( $attrs['step'] ) )
{
$output .= "{$section_props}['step'] = 1;\n";
}
if ( !isset( $attrs['start'] ) )
{
$output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
}
else
{
$output .= "if ({$section_props}['start'] < 0)\n"." {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n"."else\n"." {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
}
$output .= "if ({$section_props}['show']) {\n"." {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n"." if ({$section_props}['total'] == 0)\n"." {$section_props}['show'] = false;\n"."} else\n"." {$section_props}['total'] = 0;\n";
$output .= "if ({$section_props}['show']):\n";
$output .= "\n for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;\n {$section_props}['iteration'] <= {$section_props}['total'];\n {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
$output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
$output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
$output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
$output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n";
$output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n";
$output .= "?>";
return $output;
}
function _compile_foreach_start( $tag_args )
{
$attrs = $this->_parse_attrs( $tag_args );
$arg_list = array( );
if ( empty( $attrs['from'] ) )
{
$this->_syntax_error( "missing 'from' attribute" );
}
if ( empty( $attrs['item'] ) )
{
$this->_syntax_error( "missing 'item' attribute" );
}
$from = $attrs['from'];
$item = $this->_dequote( $attrs['item'] );
if ( isset( $attrs['name'] ) )
{
$name = $attrs['name'];
}
$output = "<?php ";
if ( isset( $name ) )
{
$output .= "if (isset(\$this->_foreach[{$name}])) unset(\$this->_foreach[{$name}]);\n";
$foreach_props = "\$this->_foreach[{$name}]";
}
$key_part = "";
foreach ( $attrs as $attr_name => $attr_value )
{
switch ( $attr_name )
{
case "key" :
$key = $this->_dequote( $attrs['key'] );
$key_part = "\$this->_tpl_vars['{$key}'] => ";
break;
case "name" :
$output .= "{$foreach_props}['{$attr_name}'] = {$attr_value};\n";
}
}
if ( isset( $name ) )
{
$output .= "{$foreach_props}['total'] = count((array){$from});\n";
$output .= "{$foreach_props}['show'] = {$foreach_props}['total'] > 0;\n";
$output .= "if ({$foreach_props}['show']):\n";
$output .= "{$foreach_props}['iteration'] = 0;\n";
$output .= " foreach ((array){$from} as {$key_part}\$this->_tpl_vars['{$item}']):\n";
$output .= " {$foreach_props}['iteration']++;\n";
$output .= " {$foreach_props}['first'] = ({$foreach_props}['iteration'] == 1);\n";
$output .= " {$foreach_props}['last'] = ({$foreach_props}['iteration'] == {$foreach_props}['total']);\n";
}
else
{
$output .= "if (count((array){$from})):\n";
$output .= " foreach ((array){$from} as {$key_part}\$this->_tpl_vars['{$item}']):\n";
}
$output .= "?>";
return $output;
}
function _compile_capture_tag( $start, $tag_args = "" )
{
$attrs = $this->_parse_attrs( $tag_args );
if ( $start )
{
if ( isset( $attrs['name'] ) )
{
$buffer = $attrs['name'];
}
else
{
$buffer = "'default'";
}
$output = "<?php ob_start(); ?>";
$this->_capture_stack[] = $buffer;
}
else
{
$buffer = array_pop( $this->_capture_stack );
$output = "<?php \$this->_smarty_vars['capture'][{$buffer}] = ob_get_contents(); ob_end_clean(); ?>";
}
return $output;
}
function _compile_if_tag( $tag_args, $elseif = false )
{
preg_match_all( "/(?:\n \"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\" | # match all double quoted strings allowing escaped double quotes\n '[^'\\\\]*(?:\\\\.[^'\\\\]*)*' | # match all single quoted strings allowing escaped single quotes\n [(),] | # match parentheses and commas\n [^\\s(),]+ # match any other token that is not any of the above\n )/x", $tag_args, $match );
$tokens = $match[0];
$this->_parse_vars_props( $tokens );
$is_arg_stack = array( );
$i = 0;
for ( ; $i < count( $tokens ); ++$i )
{
$token =& $tokens[$i];
switch ( $token )
{
case "eq" :
$token = "==";
break;
case "ne" :
case "neq" :
$token = "!=";
break;
case "lt" :
$token = "<";
break;
case "le" :
case "lte" :
$token = "<=";
break;
case "gt" :
$token = ">";
break;
case "ge" :
case "gte" :
$token = ">=";
break;
case "and" :
$token = "&&";
break;
case "or" :
$token = "||";
break;
case "not" :
$token = "!";
break;
case "mod" :
$token = "%";
break;
case "(" :
array_push( $is_arg_stack, $i );
break;
case "is" :
if ( $tokens[$i - 1] == ")" )
{
$is_arg_start = array_pop( $is_arg_stack );
}
else
{
$is_arg_start = $i - 1;
}
$is_arg = implode( " ", array_slice( $tokens, $is_arg_start, $i - $is_arg_start ) );
$new_tokens = $this->_parse_is_expr( $is_arg, array_slice( $tokens, $i + 1 ) );
array_splice( $tokens, $is_arg_start, count( $tokens ), $new_tokens );
$i = $is_arg_start;
break;
default :
if ( !( $this->security && $tokens[$i + 1] == "(" && preg_match( "!^[a-zA-Z_]\\w+\$!", $tokens[$i] ) && !in_array( $tokens[$i], $this->security_settings['IF_FUNCS'] ) ) )
{
break;
}
$this->_syntax_error( "(secure mode) '".$tokens[$i]."' not allowed in if statement" );
break;
}
}
if ( $elseif )
{
return "<?php elseif (".implode( " ", $tokens )."): ?>";
}
else
{
return "<?php if (".implode( " ", $tokens )."): ?>";
}
}
function _parse_is_expr( $is_arg, $tokens )
{
$expr_end = 0;
$negate_expr = false;
if ( ( $first_token = array_shift( $tokens ) ) == "not" )
{
$negate_expr = true;
$expr_type = array_shift( $tokens );
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -