📄 smarty_compiler.class.php
字号:
/* Interleave the compiled contents and text blocks to get the final result. */
for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
if ($compiled_tags[$i] == '') {
// tag result empty, remove first newline from following text block
$text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
}
$compiled_content .= $text_blocks[$i].$compiled_tags[$i];
}
$compiled_content .= $text_blocks[$i];
/* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */
if (preg_match_all("~{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}~s", $compiled_content, $_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);
for ($i = 0, $for_max = count($strip_tags); $i < $for_max; $i++)
$compiled_content = preg_replace("~{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}~s",
$this->_quote_replace($strip_tags_modified[$i]),
$compiled_content, 1);
}
// remove \n from the end of the file, if any
if (($_len=strlen($compiled_content)) && ($compiled_content{$_len - 1} == "\n" )) {
$compiled_content = substr($compiled_content, 0, -1);
}
if (!empty($this->_cache_serial)) {
$compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
}
// remove unnecessary close/open tags
$compiled_content = preg_replace('~\?>\n?<\?php~', '', $compiled_content);
// run compiled template through postfilter functions
if (count($this->_plugins['postfilter']) > 0) {
foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
if ($postfilter === false) continue;
if ($postfilter[3] || is_callable($postfilter[0])) {
$compiled_content = call_user_func_array($postfilter[0],
array($compiled_content, &$this));
$this->_plugins['postfilter'][$filter_name][3] = true;
} else {
$this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
}
}
}
// put header at the top of the compiled template
$template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
$template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
/* Emit code to load needed plugins. */
$this->_plugins_code = '';
if (count($this->_plugin_info)) {
$_plugins_params = "array('plugins' => array(";
foreach ($this->_plugin_info as $plugin_type => $plugins) {
foreach ($plugins as $plugin_name => $plugin_info) {
$_plugins_params .= "array('$plugin_type', '$plugin_name', '$plugin_info[0]', $plugin_info[1], ";
$_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
}
}
$_plugins_params .= '))';
$plugins_code = "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
$template_header .= $plugins_code;
$this->_plugin_info = array();
$this->_plugins_code = $plugins_code;
}
if ($this->_init_smarty_vars) {
$template_header .= "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
$this->_init_smarty_vars = false;
}
$compiled_content = $template_header . $compiled_content;
return true;
}
/**
* Compile a template tag
*
* @param string $template_tag
* @return string
*/
function _compile_tag($template_tag)
{
/* Matched comment. */
if ($template_tag{0} == '*' && $template_tag{strlen($template_tag) - 1} == '*')
return '';
/* Split tag into two three parts: command, command modifiers and the arguments. */
if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
. '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
(?:\s+(.*))?$
~xs', $template_tag, $match)) {
$this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
}
$tag_command = $match[1];
$tag_modifier = isset($match[2]) ? $match[2] : null;
$tag_args = isset($match[3]) ? $match[3] : null;
if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
/* tag name is a variable or object */
$_return = $this->_parse_var_props($tag_command . $tag_modifier, $this->_parse_attrs($tag_args));
if(isset($_tag_attrs['assign'])) {
return "<?php \$this->assign('" . $this->_dequote($_tag_attrs['assign']) . "', $_return ); ?>\n";
} else {
return "<?php echo $_return; ?>" . $this->_additional_newline;
}
}
/* If the tag name is a registered object, we process it. */
if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
}
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':
$this->_push_tag('if');
return $this->_compile_if_tag($tag_args);
case 'else':
list($_open_tag) = end($this->_tag_stack);
if ($_open_tag != 'if' && $_open_tag != 'elseif')
$this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
else
$this->_push_tag('else');
return '<?php else: ?>';
case 'elseif':
list($_open_tag) = end($this->_tag_stack);
if ($_open_tag != 'if' && $_open_tag != 'elseif')
$this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
if ($_open_tag == 'if')
$this->_push_tag('elseif');
return $this->_compile_if_tag($tag_args, true);
case '/if':
$this->_pop_tag('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':
$this->_push_tag('section');
return $this->_compile_section_start($tag_args);
case 'sectionelse':
$this->_push_tag('sectionelse');
return "<?php endfor; else: ?>";
break;
case '/section':
$_open_tag = $this->_pop_tag('section');
if ($_open_tag == 'sectionelse')
return "<?php endif; ?>";
else
return "<?php endfor; endif; ?>";
case 'foreach':
$this->_push_tag('foreach');
return $this->_compile_foreach_start($tag_args);
break;
case 'foreachelse':
$this->_push_tag('foreachelse');
return "<?php endforeach; unset(\$_from); else: ?>";
case '/foreach':
$_open_tag = $this->_pop_tag('foreach');
if ($_open_tag == 'foreachelse')
return "<?php endif; ?>";
else
return "<?php endforeach; unset(\$_from); endif; ?>";
break;
case 'strip':
case '/strip':
if ($tag_command{0}=='/') {
$this->_pop_tag('strip');
if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
$this->_additional_newline = "\n";
return $this->left_delimiter.$tag_command.$this->right_delimiter;
}
} else {
$this->_push_tag('strip');
if ($this->_strip_depth++==0) { /* outermost opening {strip} */
$this->_additional_newline = "";
return $this->left_delimiter.$tag_command.$this->right_delimiter;
}
}
return '';
case 'php':
/* handle folded tags replaced by {php} */
list(, $block) = each($this->_folded_blocks);
$this->_current_line_no += substr_count($block[0], "\n");
/* the number of matched elements in the regexp in _compile_file()
determins the type of folded tag that was found */
switch (count($block)) {
case 2: /* comment */
return '';
case 3: /* literal */
return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
case 4: /* php */
if ($this->security && !$this->security_settings['PHP_TAGS']) {
$this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
return;
}
return '<?php ' . $block[3] .' ?>';
}
break;
case 'insert':
return $this->_compile_insert_tag($tag_args);
default:
if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
return $output;
} else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
return $output;
} else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
return $output;
} else {
$this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
}
}
}
/**
* compile the custom compiler tag
*
* sets $output to the compiled custom compiler tag
* @param string $tag_command
* @param string $tag_args
* @param string $output
* @return boolean
*/
function _compile_compiler_tag($tag_command, $tag_args, &$output)
{
$found = false;
$have_function = true;
/*
* First we check if the compiler function has already been registered
* or loaded from a plugin file.
*/
if (isset($this->_plugins['compiler'][$tag_command])) {
$found = true;
$plugin_func = $this->_plugins['compiler'][$tag_command][0];
if (!is_callable($plugin_func)) {
$message = "compiler function '$tag_command' is not implemented";
$have_function = false;
}
}
/*
* Otherwise we need to load plugin file and look for the function
* inside it.
*/
else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
$found = true;
include_once $plugin_file;
$plugin_func = 'smarty_compiler_' . $tag_command;
if (!is_callable($plugin_func)) {
$message = "plugin function $plugin_func() not found in $plugin_file\n";
$have_function = false;
} else {
$this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
}
}
/*
* True return value means that we either found a plugin or a
* dynamically registered function. False means that we didn't and the
* compiler should now emit code to load custom function plugin for this
* tag.
*/
if ($found) {
if ($have_function) {
$output = call_user_func_array($plugin_func, array($tag_args, &$this));
if($output != '') {
$output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
. $output
. $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
}
} else {
$this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
}
return true;
} else {
return false;
}
}
/**
* compile block function tag
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -