?? smarty_compiler.class.php
字號:
<?php/** * Project: Smarty: the PHP compiling template engine * File: Smarty_Compiler.class.php * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * 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 Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * @link http://smarty.php.net/ * @author Monte Ohrt <monte at ohrt dot com> * @author Andrei Zmievski <andrei@php.net> * @version 2.6.13 * @copyright 2001-2005 New Digital Group, Inc. * @package Smarty *//* $Id: Smarty_Compiler.class.php,v 1.378 2006/01/29 18:11:22 messju Exp $ *//** * Template compiling class * @package Smarty */class Smarty_Compiler extends Smarty { // internal vars /**#@+ * @access private */ var $_folded_blocks = array(); // keeps folded template 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 var $_plugin_info = array(); // keeps track of plugins to load var $_init_smarty_vars = false; var $_permitted_tokens = array('true','false','yes','no','on','off','null'); var $_db_qstr_regexp = null; // regexps are setup in the constructor var $_si_qstr_regexp = null; var $_qstr_regexp = null; var $_func_regexp = null; var $_reg_obj_regexp = null; var $_var_bracket_regexp = null; var $_num_const_regexp = null; var $_dvar_guts_regexp = null; var $_dvar_regexp = null; var $_cvar_regexp = null; var $_svar_regexp = null; var $_avar_regexp = null; var $_mod_regexp = null; var $_var_regexp = null; var $_parenth_param_regexp = null; var $_func_call_regexp = null; var $_obj_ext_regexp = null; var $_obj_start_regexp = null; var $_obj_params_regexp = null; var $_obj_call_regexp = null; var $_cacheable_state = 0; var $_cache_attrs_count = 0; var $_nocache_count = 0; var $_cache_serial = null; var $_cache_include = null; var $_strip_depth = 0; var $_additional_newline = "\n"; /**#@-*/ /** * The class constructor. */ function Smarty_Compiler() { // matches double quoted strings: // "foobar" // "foo\"bar" $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"'; // matches single quoted strings: // 'foobar' // 'foo\'bar' $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; // matches single or double quoted strings $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')'; // matches bracket portion of vars // [0] // [foo] // [$bar] $this->_var_bracket_regexp = '\[\$?[\w\.]+\]'; // matches numerical constants // 30 // -12 // 13.22 $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)'; // matches $ vars (not objects): // $foo // $foo.bar // $foo.bar.foobar // $foo[0] // $foo[$bar] // $foo[5][blah] // $foo[5].bar[$foobar][4] $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))'; $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]'; $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?'; $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp; // matches config vars: // #foo# // #foobar123_foo# $this->_cvar_regexp = '\#\w+\#'; // matches section vars: // %foo.bar% $this->_svar_regexp = '\%\w+\.\w+\%'; // matches all valid variables (no quotes, no modifiers) $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|' . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')'; // matches valid variable syntax: // $foo // $foo // #foo# // #foo# // "text" // "text" $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')'; // matches valid object call (one level of object nesting allowed in parameters): // $foo->bar // $foo->bar() // $foo->bar("text") // $foo->bar($foo, $bar, "text") // $foo->bar($foo, "foo") // $foo->bar->foo() // $foo->bar->foo->bar() // $foo->bar($foo->bar) // $foo->bar($foo->bar()) // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar)) $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')'; $this->_obj_restricted_param_regexp = '(?:' . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')' . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)'; $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|' . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)'; $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; // matches valid modifier syntax: // |foo // |@foo // |foo:"bar" // |foo:$bar // |foo:"bar":$foobar // |foo|bar // |foo:$foo->bar $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)'; // matches valid function name: // foo123 // _foo_bar $this->_func_regexp = '[a-zA-Z_]\w*'; // matches valid registered object: // foo->bar $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*'; // matches valid parameter values: // true // $foo // $foo|bar // #foo# // #foo#|bar // "text" // "text"|bar // $foo->bar $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; // matches valid parenthesised function parameters: // // "text" // $foo, $bar, "text" // $foo|bar, "foo"|bar, $foo->bar($foo)|bar $this->_parenth_param_regexp = '(?:\((?:\w+|' . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|' . $this->_param_regexp . ')))*)?\))'; // matches valid function call: // foo() // foo_bar($foo) // _foo_bar($foo,"bar") // foo123($foo,$foo->bar(),"foo") $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:' . $this->_parenth_param_regexp . '))'; } /** * compile a resource * * sets $compiled_content to the compiled source * @param string $resource_name * @param string $source_content * @param string $compiled_content * @return true */ function _compile_file($resource_name, $source_content, &$compiled_content) { 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; } } $this->_load_filters(); $this->_current_file = $resource_name; $this->_current_line_no = 1; $ldq = preg_quote($this->left_delimiter, '~'); $rdq = preg_quote($this->right_delimiter, '~'); // run template source through prefilter functions if (count($this->_plugins['prefilter']) > 0) { foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { if ($prefilter === false) continue; if ($prefilter[3] || is_callable($prefilter[0])) { $source_content = call_user_func_array($prefilter[0], array($source_content, &$this)); $this->_plugins['prefilter'][$filter_name][3] = true; } else { $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented"); } } } /* fetch all special blocks */ $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s"; preg_match_all($search, $source_content, $match, PREG_SET_ORDER); $this->_folded_blocks = $match; reset($this->_folded_blocks); /* replace special blocks by "{php}" */ $source_content = preg_replace($search.'e', "'" . $this->_quote_replace($this->left_delimiter) . 'php' . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'" . $this->_quote_replace($this->right_delimiter) . "'" , $source_content); /* Gather all template tags. */ preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match); $template_tags = $_match[1]; /* Split content by template tags to obtain non-template content. */ $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content); /* loop through text blocks */ for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { /* match anything resembling php tags */ if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?php[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) { /* replace tags with placeholders to prevent recursive replacements */ $sp_match[1] = array_unique($sp_match[1]); usort($sp_match[1], '_smarty_sort_length'); for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]); } /* process each one */ for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { if ($this->php_handling == SMARTY_PHP_PASSTHRU) { /* echo php contents */ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]); } else if ($this->php_handling == SMARTY_PHP_QUOTE) { /* quote php tags */ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]); } else if ($this->php_handling == SMARTY_PHP_REMOVE) { /* remove php tags */ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]); } else { /* SMARTY_PHP_ALLOW, but echo non php starting tags */ $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]); $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]); } } } } /* Compile the template tags into PHP code. */ $compiled_tags = array(); for ($i = 0, $for_max = count($template_tags); $i < $for_max; $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"); } if (count($this->_tag_stack)>0) { list($_open_tag, $_line_no) = end($this->_tag_stack); $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__); return; } /* Reformat $text_blocks between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */ $strip = false; for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { if ($compiled_tags[$i] == '{strip}') { $compiled_tags[$i] = ''; $strip = true;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -