📄 smarty_compiler.class.php
字号:
<?php
class smarty_compiler extends smarty
{
var $_sectionelse_stack = array( );
var $_foreachelse_stack = array( );
var $_literal_blocks = array( );
var $_php_blocks = array( );
var $_current_file = null;
var $_current_line_no = 1;
var $_capture_stack = array( );
function _compile_file( $tpl_file, $template_source, &$template_compiled )
{
if ( $this->security && $this->php_handling == SMARTY_PHP_ALLOW && !$this->security_settings['PHP_HANDLING'] )
{
$this->php_handling = SMARTY_PHP_PASSTHRU;
}
if ( is_array( $this->prefilter_funcs ) && 0 < count( $this->prefilter_funcs ) )
{
foreach ( $this->prefilter_funcs as $prefilter )
{
if ( function_exists( $prefilter ) )
{
$template_source = $prefilter( $template_source, $this );
}
else
{
$this->_trigger_error_msg( "prefilter function {$prefilter} does not exist." );
}
}
}
$this->_current_file = $tpl_file;
$this->_current_line_no = 1;
$ldq = preg_quote( $this->left_delimiter, "!" );
$rdq = preg_quote( $this->right_delimiter, "!" );
$template_source = preg_replace( "!({$ldq})\\*(.*?)\\*({$rdq})!se", "'\\1*'.str_repeat(\"\n\", substr_count('\\2', \"\n\")) .'*\\3'", $template_source );
preg_match_all( "!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_source, $match );
$this->_literal_blocks = $match[1];
$template_source = preg_replace( "!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $this->quote_replace( $this->left_delimiter."literal".$this->right_delimiter ), $template_source );
preg_match_all( "!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $template_source, $match );
$this->_php_blocks = $match[1];
$template_source = preg_replace( "!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $this->quote_replace( $this->left_delimiter."php".$this->right_delimiter ), $template_source );
preg_match_all( "!{$ldq}\\s*(.*?)\\s*{$rdq}!s", $template_source, $match );
$template_tags = $match[1];
$text_blocks = preg_split( "!{$ldq}.*?{$rdq}!s", $template_source );
$curr_tb = 0;
for ( ; $curr_tb < count( $text_blocks ); ++$curr_tb )
{
if ( preg_match_all( "!(<\\?[^?]*?\\?>|<script\\s+language\\s*=\\s*[\\\"']?php[\\\"']?\\s*>)!is", $text_blocks[$curr_tb], $sp_match ) )
{
$curr_sp = 0;
for ( ; $curr_sp < count( $sp_match[0] ); ++$curr_sp )
{
if ( preg_match( "!^(<\\?(php\\s|\\s|=\\s)|<script\\s*language\\s*=\\s*[\\\"']?php[\\\"']?\\s*>)!is", $sp_match[0][$curr_sp] ) )
{
if ( $this->php_handling == SMARTY_PHP_PASSTHRU )
{
$text_blocks[$curr_tb] = str_replace( $sp_match[0][$curr_sp], "<?php echo '".str_replace( "'", "\\'", $sp_match[0][$curr_sp] )."'; ?>"."\n", $text_blocks[$curr_tb] );
}
else if ( $this->php_handling == SMARTY_PHP_QUOTE )
{
$text_blocks[$curr_tb] = str_replace( $sp_match[0][$curr_sp], htmlspecialchars( $sp_match[0][$curr_sp] ), $text_blocks[$curr_tb] );
}
else if ( $this->php_handling == SMARTY_PHP_REMOVE )
{
if ( substr( $sp_match[0][$curr_sp], 0, 2 ) == "<?" )
{
$text_blocks[$curr_tb] = str_replace( $sp_match[0][$curr_sp], "", $text_blocks[$curr_tb] );
}
else
{
$text_blocks[$curr_tb] = preg_replace( "!".preg_quote( $sp_match[0][$curr_sp], "!" ).".*?</script\\s*>!is", "", $text_blocks[$curr_tb] );
}
}
}
else
{
$text_blocks[$curr_tb] = str_replace( $sp_match[0][$curr_sp], "<?php echo '".str_replace( "'", "\\'", $sp_match[0][$curr_sp] )."'; ?>"."\n", $text_blocks[$curr_tb] );
}
}
}
}
$compiled_tags = array( );
$i = 0;
for ( ; $i < count( $template_tags ); ++$i )
{
$this->_current_line_no += substr_count( $text_blocks[$i], "\n" );
$compiled_tags[] = $this->_compile_tag( $template_tags[$i] );
$this->_current_line_no += substr_count( $template_tags[$i], "\n" );
}
$template_compiled = "";
$i = 0;
for ( ; $i < count( $compiled_tags ); ++$i )
{
$template_compiled .= $text_blocks[$i].$compiled_tags[$i];
}
$template_compiled .= $text_blocks[$i];
if ( preg_match_all( "!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $template_compiled, $match ) )
{
$strip_tags = $match[0];
$strip_tags_modified = preg_replace( "!{$ldq}/?strip{$rdq}|[\t ]+\$|^[\t ]+!m", "", $strip_tags );
$strip_tags_modified = preg_replace( "![\\r\\n]+!m", "", $strip_tags_modified );
$i = 0;
for ( ; $i < count( $strip_tags ); ++$i )
{
$template_compiled = preg_replace( "!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $this->quote_replace( $strip_tags_modified[$i] ), $template_compiled, 1 );
}
}
$template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime( "%Y-%m-%d %H:%M:%S" )."\n";
$template_header .= " compiled from ".$tpl_file." */ ?>\n";
$template_compiled = $template_header.$template_compiled;
if ( $template_compiled[strlen( $template_compiled ) - 1] == "\n" )
{
$template_compiled = substr( $template_compiled, 0, -1 );
}
if ( is_array( $this->postfilter_funcs ) && 0 < count( $this->postfilter_funcs ) )
{
foreach ( $this->postfilter_funcs as $postfilter )
{
if ( function_exists( $postfilter ) )
{
$template_compiled = $postfilter( $template_compiled, $this );
}
else
{
$this->_trigger_error_msg( "postfilter function {$postfilter} does not exist." );
}
}
}
return true;
}
function _compile_tag( $template_tag )
{
if ( $template_tag[0] == "*" && $template_tag[strlen( $template_tag ) - 1] == "*" )
{
return "";
}
$qstr_regexp = "\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"|'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'";
preg_match( "/^(\n (?: ".$qstr_regexp." | (?>[^\"'\\s]+))+\n )\n (?:\\s+(.*))?\n /xs", $template_tag, $match );
$tag_command = $match[1];
$tag_args = isset( $match[2] ) ? $match[2] : "";
if ( preg_match( "!^\\\$\\w+(?>(\\[(\\d+|\\w+(\\.\\w+)?)\\])|((\\.|->)\\w+))*(?>\\|@?\\w+(:(?>".$qstr_regexp."|[^|]+))*)*\$!", $tag_command ) || preg_match( "!^#(\\w+)#(?>\\|@?\\w+(:(?>".$qstr_regexp."|[^|]+))*)*\$!", $tag_command ) || preg_match( "!^%\\w+\\.\\w+%(?>\\|@?\\w+(:(?>".$qstr_regexp."|[^|]+))*)*\$!", $tag_command ) )
{
settype( $tag_command, "array" );
$this->_parse_vars_props( $tag_command );
return "<?php echo {$tag_command['0']}; ?>\n";
}
switch ( $tag_command )
{
case "include" :
return $this->_compile_include_tag( $tag_args );
case "include_php" :
return $this->_compile_include_php_tag( $tag_args );
case "if" :
return $this->_compile_if_tag( $tag_args );
case "else" :
return "<?php else: ?>";
case "elseif" :
return $this->_compile_if_tag( $tag_args, true );
case "/if" :
return "<?php endif; ?>";
case "capture" :
return $this->_compile_capture_tag( true, $tag_args );
case "/capture" :
return $this->_compile_capture_tag( false );
case "ldelim" :
return $this->left_delimiter;
case "rdelim" :
return $this->right_delimiter;
case "section" :
array_push( $this->_sectionelse_stack, false );
return $this->_compile_section_start( $tag_args );
case "sectionelse" :
$this->_sectionelse_stack[count( $this->_sectionelse_stack ) - 1] = true;
return "<?php endfor; else: ?>";
case "/section" :
if ( array_pop( $this->_sectionelse_stack ) )
{
return "<?php endif; ?>";
}
return "<?php endfor; endif; ?>";
case "foreach" :
array_push( $this->_foreachelse_stack, false );
return $this->_compile_foreach_start( $tag_args );
case "foreachelse" :
$this->_foreachelse_stack[count( $this->_foreachelse_stack ) - 1] = true;
return "<?php endforeach; else: ?>";
case "/foreach" :
if ( array_pop( $this->_foreachelse_stack ) )
{
return "<?php endif; ?>";
}
return "<?php endforeach; endif; ?>";
case "config_load" :
return $this->_compile_config_load_tag( $tag_args );
case "strip" :
case "/strip" :
return $this->left_delimiter.$tag_command.$this->right_delimiter;
case "literal" :
list( , $literal_block ) = each( $this->_literal_blocks );
$this->_current_line_no += substr_count( $literal_block, "\n" );
return "<?php echo '".str_replace( "'", "\\'", str_replace( "\\", "\\\\", $literal_block ) )."'; ?>\n";
case "php" :
if ( $this->security && !$this->security_settings['PHP_TAGS'] )
{
$this->_syntax_error( "(secure mode) php tags not permitted", E_USER_WARNING );
}
else
{
list( , $php_block ) = each( $this->_php_blocks );
$this->_current_line_no += substr_count( $php_block, "\n" );
}
return "<?php ".$php_block." ?>";
case "insert" :
return $this->_compile_insert_tag( $tag_args );
default :
if ( isset( $this->compiler_funcs[$tag_command] ) )
{
return $this->_compile_compiler_tag( $tag_command, $tag_args );
}
else if ( isset( $this->custom_funcs[$tag_command] ) )
{
return $this->_compile_custom_tag( $tag_command, $tag_args );
}
else
{
$this->_syntax_error( "unknown tag - '{$tag_command}'", E_USER_WARNING );
break;
}
}
}
function _compile_compiler_tag( $tag_command, $tag_args )
{
$function = $this->compiler_funcs[$tag_command];
if ( !function_exists( $function ) )
{
$this->_syntax_error( "compiler function '{$tag_command}' is not implemented", E_USER_WARNING );
}
else
{
return "<?php ".$function( $tag_args, $this )." ?>";
}
}
function _compile_custom_tag( $tag_command, $tag_args )
{
$function = $this->custom_funcs[$tag_command];
if ( !function_exists( $function ) )
{
$this->_syntax_error( "custom function '{$tag_command}' is not implemented", E_USER_WARNING );
}
else
{
$arg_list = array( );
$attrs = $this->_parse_attrs( $tag_args );
foreach ( $attrs as $arg_name => $arg_value )
{
if ( is_bool( $arg_value ) )
{
$arg_value = $arg_value ? "true" : "false";
}
$arg_list[] = "'{$arg_name}' => {$arg_value}";
}
return "<?php {$function}(array(".implode( ",", ( array )$arg_list )."), \$this); if(\$this->_extract) { extract(\$this->_tpl_vars); \$this->_extract=false; } ?>";
}
}
function _compile_insert_tag( $tag_args )
{
$attrs = $this->_parse_attrs( $tag_args );
$name = substr( $attrs['name'], 1, -1 );
if ( empty( $name ) )
{
$this->_syntax_error( "missing insert name" );
}
foreach ( $attrs as $arg_name => $arg_value )
{
if ( is_bool( $arg_value ) )
{
$arg_value = $arg_value ? "true" : "false";
}
$arg_list[] = "'{$arg_name}' => {$arg_value}";
}
return "<?php echo \$this->_run_insert_handler(array(".implode( ", ", ( array )$arg_list ).")); ?>\n";
}
function _compile_config_load_tag( $tag_args )
{
$attrs = $this->_parse_attrs( $tag_args );
if ( empty( $attrs['file'] ) )
{
$this->_syntax_error( "missing 'file' attribute in config_load tag" );
}
if ( empty( $attrs['section'] ) )
{
$attrs['section'] = "null";
}
$scope = @$this->_dequote( $attrs['scope'] );
if ( !empty( $scope ) )
{
if ( $scope != "local" && $scope != "parent" && $scope != "global" )
{
$this->_syntax_error( "invalid 'scope' attribute value" );
}
}
else if ( !empty( $attrs['global'] ) && $attrs['global'] )
{
$scope = "parent";
}
else
{
$scope = "local";
}
$output = "<?php \$this->_config_load(".$attrs['file'].", ".$attrs['section'].", '{$scope}'); ?>";
return $output;
}
function _compile_include_tag( $tag_args )
{
$attrs = $this->_parse_attrs( $tag_args );
$arg_list = array( );
if ( empty( $attrs['file'] ) )
{
$this->_syntax_error( "missing 'file' attribute in include tag" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -