📄 smarty_compiler.class.php
字号:
<?php/* * Project: Smarty: the PHP compiling template engine * File: Smarty_Compiler.class.php * Author: Monte Ohrt <monte@ispi.net> * Andrei Zmievski <andrei@php.net> * * Version: 1.5.2 * Copyright: 2001 ispi of Lincoln, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General var * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General var License for more details. * * You should have received a copy of the GNU Lesser General var * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * You may contact the authors of Smarty by e-mail at: * monte@ispi.net * andrei@php.net * * Or, write to: * Monte Ohrt * Director of Technology, ispi * 237 S. 70th suite 220 * Lincoln, NE 68510 * * The latest version of Smarty can be obtained from: * http://www.phpinsider.com/ * */class Smarty_Compiler extends Smarty { // internal vars var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part var $_foreachelse_stack = array(); // keeps track of whether foreach had 'else' part var $_literal_blocks = array(); // keeps literal template blocks var $_php_blocks = array(); // keeps php code blocks var $_current_file = null; // the current template being compiled var $_current_line_no = 1; // line number for error messages var $_capture_stack = array(); // keeps track of nested capture buffers/*======================================================================*\ Function: _compile_file() Input: compile a template file\*======================================================================*/ function _compile_file($tpl_file, $template_source, &$template_compiled) { if ($this->security) { // do not allow php syntax to be executed unless specified if ($this->php_handling == SMARTY_PHP_ALLOW && !$this->security_settings['PHP_HANDLING']) { $this->php_handling = SMARTY_PHP_PASSTHRU; } } // run template source through prefilter functions if (is_array($this->prefilter_funcs) && count($this->prefilter_funcs) > 0) { 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, '!'); /* Annihilate the comments. */ $template_source = preg_replace("!({$ldq})\*(.*?)\*({$rdq})!se", "'\\1*'.str_repeat(\"\n\", substr_count('\\2', \"\n\")) .'*\\3'", $template_source); /* Pull out the literal blocks. */ 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); /* Pull out the php code blocks. */ 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); /* Gather all template tags. */ preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_source, $match); $template_tags = $match[1]; /* Split content by template tags to obtain non-template content. */ $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $template_source); /* loop through text blocks */ for ($curr_tb = 0; $curr_tb < count($text_blocks); $curr_tb++) { /* match anything within <? ?> */ if (preg_match_all('!(<\?[^?]*?\?>|<script\s+language\s*=\s*[\"\']?php[\"\']?\s*>)!is', $text_blocks[$curr_tb], $sp_match)) { /* found at least one match, loop through each one */ for ($curr_sp = 0; $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])) { /* php tag */ if ($this->php_handling == SMARTY_PHP_PASSTHRU) { /* echo php contents */ $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) { /* quote php tags */ $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) { /* remove php tags */ 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 /* attempt to remove everything between <script ...> and </script> */ $text_blocks[$curr_tb] = preg_replace('!'.preg_quote($sp_match[0][$curr_sp], '!').'.*?</script\s*>!is', '', $text_blocks[$curr_tb]); } } else /* echo the non-php tags */ $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]); } } } /* Compile the template tags into PHP code. */ $compiled_tags = array(); for ($i = 0; $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 = ''; /* Interleave the compiled contents and text blocks to get the final result. */ for ($i = 0; $i < count($compiled_tags); $i++) { $template_compiled .= $text_blocks[$i].$compiled_tags[$i]; } $template_compiled .= $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", $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); for ($i = 0; $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); } // 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 ".$tpl_file." */ ?>\n"; $template_compiled = $template_header.$template_compiled; // remove \n from the end of the file, if any if ($template_compiled{strlen($template_compiled) - 1} == "\n" ) { $template_compiled = substr($template_compiled, 0, -1); } // run compiled template through postfilter functions if (is_array($this->postfilter_funcs) && count($this->postfilter_funcs) > 0) { 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 Purpose: Compile a template tag\*======================================================================*/ function _compile_tag($template_tag) { /* Matched comment. */ if ($template_tag{0} == '*' && $template_tag{strlen($template_tag) - 1} == '*') return ''; $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; /* Split tag into two parts: command and the arguments. */ preg_match('/^( (?: ' . $qstr_regexp . ' | (?>[^"\'\s]+))+ ) (?:\s+(.*))? /xs', $template_tag, $match); $tag_command = $match[1]; $tag_args = isset($match[2]) ? $match[2] : ''; /* If the tag name matches a variable or section property definition, we simply process it. */ if (preg_match('!^\$\w+(?>(\[(\d+|\w+(\.\w+)?)\])|((\.|->)\w+))*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tag_command) || // if a variable preg_match('!^#(\w+)#(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tag_command) || // or a configuration variable preg_match('!^%\w+\.\w+%(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tag_command)) { // or a section property 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; ?>"; else return "<?php endfor; endif; ?>"; case 'foreach': array_push($this->_foreachelse_stack, false); return $this->_compile_foreach_start($tag_args); break; 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; ?>"; else 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); return; } list (,$php_block) = each($this->_php_blocks); $this->_current_line_no += substr_count($php_block, "\n"); return '<?php '.$php_block.' ?>';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -