📄 smarty_compiler.class.php
字号:
$this->_syntax_error("invalid attribute name - '$token'");
break;
case 1:
/* If the token is '=', then we go to state 2. */
if ($token == '=') {
$state = 2;
} else
$this->_syntax_error("expecting '=' after attribute name");
break;
case 2:
/* If token is not '=', we set the attribute value and go to
state 0. */
if ($token != '=') {
/* We booleanize the token if it's a non-quoted possible
boolean value. */
if (preg_match('!^(on|yes|true)$!', $token))
$token = true;
else if (preg_match('!^(off|no|false)$!', $token))
$token = false;
/* If the token is not variable (doesn't start with
'$', '#', or '%') and not enclosed in single or
double quotes we single-quote it. */
else if ($quote && !in_array($token{0}, $var_delims) &&
!(($token{0} == '"' || $token[0] == "'") &&
$token{strlen($token)-1} == $token{0}))
$token = '"'.$token.'"';
$attrs[$attr_name] = $token;
$state = 0;
} else
$this->_syntax_error("'=' cannot be an attribute value");
break;
}
}
$this->_parse_vars_props($attrs);
return $attrs;
}
/*======================================================================*\
Function: _parse_vars_props
Purpose: compile variables and section properties tokens into
PHP code
\*======================================================================*/
function _parse_vars_props(&$tokens)
{
$qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
$var_exprs = preg_grep('!^\$\w+(?>(\[(\d+|\w+(\.\w+)?)\])|((\.|->)\w+))*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
$conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
$sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
if (count($var_exprs)) {
foreach ($var_exprs as $expr_index => $var_expr) {
$tokens[$expr_index] = $this->_parse_var($var_expr);
}
}
if (count($conf_var_exprs)) {
foreach ($conf_var_exprs as $expr_index => $var_expr) {
$tokens[$expr_index] = $this->_parse_conf_var($var_expr);
}
}
if (count($sect_prop_exprs)) {
foreach ($sect_prop_exprs as $expr_index => $section_prop_expr) {
$tokens[$expr_index] = $this->_parse_section_prop($section_prop_expr);
}
}
}
/*======================================================================*\
Function: _parse_var
Purpose: parse variable expression into PHP code
\*======================================================================*/
function _parse_var($var_expr)
{
$parts = explode('|', substr($var_expr, 1), 2);
$var_ref = $parts[0];
$modifiers = isset($parts[1]) ? $parts[1] : '';
preg_match_all('!\[\w+(\.\w+)?\]|(->|\.)\w+|^\w+!', $var_ref, $match);
$indexes = $match[0];
$var_name = array_shift($indexes);
/* Handle $smarty.* variable references as a special case. */
if ($var_name == 'smarty') {
/*
* If the reference could be compiled, use the compiled output;
* otherwise, fall back on the $smarty variable generated at
* run-time.
*/
if (($smarty_ref = $this->_compile_smarty_ref($indexes)) !== null) {
$output = $smarty_ref;
} else {
$var_name = substr(array_shift($indexes), 1);
$output = "\$this->_smarty_vars['$var_name']";
}
} else {
$output = "\$this->_tpl_vars['$var_name']";
}
foreach ($indexes as $index) {
if ($index{0} == '[') {
$index = substr($index, 1, -1);
if (is_numeric($index)) {
$output .= "[$index]";
} else {
$parts = explode('.', $index);
$section = $parts[0];
$section_prop = isset($parts[1]) ? $parts[1] : 'index';
$output .= "[\$this->_sections['$section']['$section_prop']]";
}
} else if ($index{0} == '.') {
$output .= "['" . substr($index, 1) . "']";
} else {
$output .= $index;
}
}
$this->_parse_modifiers($output, $modifiers);
return $output;
}
/*======================================================================*\
Function: _parse_conf_var
Purpose: parse configuration variable expression into PHP code
\*======================================================================*/
function _parse_conf_var($conf_var_expr)
{
$parts = explode('|', $conf_var_expr, 2);
$var_ref = $parts[0];
$modifiers = isset($parts[1]) ? $parts[1] : '';
$var_name = substr($var_ref, 1, -1);
$output = "\$this->_config[0]['vars']['$var_name']";
$this->_parse_modifiers($output, $modifiers);
return $output;
}
/*======================================================================*\
Function: _parse_section_prop
Purpose: parse section property expression into PHP code
\*======================================================================*/
function _parse_section_prop($section_prop_expr)
{
$parts = explode('|', $section_prop_expr, 2);
$var_ref = $parts[0];
$modifiers = isset($parts[1]) ? $parts[1] : '';
preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
$section_name = $match[1];
$prop_name = $match[2];
$output = "\$this->_sections['$section_name']['$prop_name']";
$this->_parse_modifiers($output, $modifiers);
return $output;
}
/*======================================================================*\
Function: _parse_modifiers
Purpose: parse modifier chain into PHP code
\*======================================================================*/
function _parse_modifiers(&$output, $modifier_string)
{
$qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
preg_match_all('!\|(@?\w+)((?>:(?:'. $qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $match);
list(, $modifiers, $modifier_arg_strings) = $match;
for ($i = 0; $i < count($modifiers); $i++) {
$modifier_name = $modifiers[$i];
preg_match_all('!:(' . $qstr_regexp . '|[^:]+)!', $modifier_arg_strings[$i], $match);
$modifier_args = $match[1];
if ($modifier_name{0} == '@') {
$map_array = 'false';
$modifier_name = substr($modifier_name, 1);
} else
$map_array = 'true';
/*
* First we lookup the modifier function name in the registered
* modifiers table.
*/
@$mod_func_name = $this->custom_mods[$modifier_name];
/*
* If we don't find that modifier there, we assume it's just a PHP
* function name.
*/
if (!isset($mod_func_name)) {
if ($this->security && !in_array($modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
$this->_syntax_error("(secure mode) modifier '$modifier_name' is not allowed", E_USER_WARNING);
continue;
} else {
$mod_func_name = $modifier_name;
}
}
if (!function_exists($mod_func_name)) {
$this->_syntax_error("modifier '$modifier_name' is not implemented", E_USER_WARNING);
continue;
}
$this->_parse_vars_props($modifier_args);
if (count($modifier_args) > 0)
$modifier_args = ', '.implode(', ', $modifier_args);
else
$modifier_args = '';
$output = "\$this->_run_mod_handler('$mod_func_name', $map_array, $output$modifier_args)";
}
}
/*======================================================================*\
Function: _compile_smarty_ref
Purpose: Compiles references of type $smarty.foo
\*======================================================================*/
function _compile_smarty_ref(&$indexes)
{
/* Extract the reference name. */
$ref = substr($indexes[0], 1);
switch ($ref) {
case 'now':
$compiled_ref = 'time()';
if (count($indexes) > 1) {
$this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference');
}
break;
case 'foreach':
case 'section':
if ($indexes[1]{0} != '.') {
$this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference');
}
$name = substr($indexes[1], 1);
array_shift($indexes);
if ($ref == 'foreach')
$compiled_ref = "\$this->_foreach['$name']";
else
$compiled_ref = "\$this->_sections['$name']";
break;
/* These cases have to be handled at run-time. */
case 'env':
case 'get':
case 'post':
case 'cookies':
case 'server':
case 'session':
case 'request':
case 'capture':
return null;
default:
$this->_syntax_error('$smarty.' . $ref . ' is an unknown reference');
break;
}
array_shift($indexes);
return $compiled_ref;
}
/*======================================================================*\
Function: _syntax_error
Purpose: display Smarty syntax error
\*======================================================================*/
function _syntax_error($error_msg, $error_type = E_USER_ERROR)
{
trigger_error("Smarty: [in " . $this->_current_file . " line " .
$this->_current_line_no . "]: syntax error: $error_msg", $error_type);
}
}
/* vim: set et: */
?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -