📄 smarty_compiler.class.php
字号:
$output .= " for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1; {$section_props}['iteration'] <= {$section_props}['total']; {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n"; $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n"; $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n"; $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n"; $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n"; $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n"; $output .= "?>"; return $output; } /** * Compile {foreach ...} tag. * * @param string $tag_args * @return string */ function _compile_foreach_start($tag_args) { $attrs = $this->_parse_attrs($tag_args); $arg_list = array(); if (empty($attrs['from'])) { $this->_syntax_error("missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); } if (empty($attrs['item'])) { $this->_syntax_error("missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); } $from = $attrs['from']; $item = $this->_dequote($attrs['item']); if (isset($attrs['name'])) $name = $attrs['name']; $output = '<?php '; if (isset($name)) { $output .= "if (isset(\$this->_foreach[$name])) unset(\$this->_foreach[$name]);\n"; $foreach_props = "\$this->_foreach[$name]"; } $key_part = ''; foreach ($attrs as $attr_name => $attr_value) { switch ($attr_name) { case 'key': $key = $this->_dequote($attrs['key']); $key_part = "\$this->_tpl_vars['$key'] => "; break; case 'name': $output .= "{$foreach_props}['$attr_name'] = $attr_value;\n"; break; } } if (isset($name)) { $output .= "{$foreach_props}['total'] = count(\$_from = (array)$from);\n"; $output .= "{$foreach_props}['show'] = {$foreach_props}['total'] > 0;\n"; $output .= "if ({$foreach_props}['show']):\n"; $output .= "{$foreach_props}['iteration'] = 0;\n"; $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; $output .= " {$foreach_props}['iteration']++;\n"; $output .= " {$foreach_props}['first'] = ({$foreach_props}['iteration'] == 1);\n"; $output .= " {$foreach_props}['last'] = ({$foreach_props}['iteration'] == {$foreach_props}['total']);\n"; } else { $output .= "if (count(\$_from = (array)$from)):\n"; $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; } $output .= '?>'; return $output; } /** * Compile {capture} .. {/capture} tags * * @param boolean $start true if this is the {capture} tag * @param string $tag_args * @return string */ function _compile_capture_tag($start, $tag_args = '') { $attrs = $this->_parse_attrs($tag_args); if ($start) { if (isset($attrs['name'])) $buffer = $attrs['name']; else $buffer = "'default'"; if (isset($attrs['assign'])) $assign = $attrs['assign']; else $assign = null; $output = "<?php ob_start(); ?>"; $this->_capture_stack[] = array($buffer, $assign); } else { list($buffer, $assign) = array_pop($this->_capture_stack); $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); "; if (isset($assign)) { $output .= " \$this->assign($assign, ob_get_contents());"; } $output .= "ob_end_clean(); ?>"; } return $output; } /** * Compile {if ...} tag * * @param string $tag_args * @param boolean $elseif if true, uses elseif instead of if * @return string */ function _compile_if_tag($tag_args, $elseif = false) { /* Tokenize args for 'if' tag. */ preg_match_all('/(?> ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token \b\w+\b | # valid word token \S+ # anything else )/x', $tag_args, $match); $tokens = $match[0]; // make sure we have balanced parenthesis $token_count = array_count_values($tokens); if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__); } $is_arg_stack = array(); for ($i = 0; $i < count($tokens); $i++) { $token = &$tokens[$i]; switch (strtolower($token)) { case '!': case '%': case '!==': case '==': case '===': case '>': case '<': case '!=': case '<>': case '<<': case '>>': case '<=': case '>=': case '&&': case '||': case '|': case '^': case '&': case '~': case ')': case ',': case '+': case '-': case '*': case '/': case '@': break; case 'eq': $token = '=='; break; case 'ne': case 'neq': $token = '!='; break; case 'lt': $token = '<'; break; case 'le': case 'lte': $token = '<='; break; case 'gt': $token = '>'; break; case 'ge': case 'gte': $token = '>='; break; case 'and': $token = '&&'; break; case 'or': $token = '||'; break; case 'not': $token = '!'; break; case 'mod': $token = '%'; break; case '(': array_push($is_arg_stack, $i); break; case 'is': /* If last token was a ')', we operate on the parenthesized expression. The start of the expression is on the stack. Otherwise, we operate on the last encountered token. */ if ($tokens[$i-1] == ')') $is_arg_start = array_pop($is_arg_stack); else $is_arg_start = $i-1; /* Construct the argument for 'is' expression, so it knows what to operate on. */ $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); /* Pass all tokens from next one until the end to the 'is' expression parsing function. The function will return modified tokens, where the first one is the result of the 'is' expression and the rest are the tokens it didn't touch. */ $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); /* Replace the old tokens with the new ones. */ array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); /* Adjust argument start so that it won't change from the current position for the next iteration. */ $i = $is_arg_start; break; default: if(preg_match('!^' . $this->_func_regexp . '$!', $token) ) { // function call if($this->security && !in_array($token, $this->security_settings['IF_FUNCS'])) { $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); } } elseif(preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$!', $token)) { // object or variable $token = $this->_parse_var_props($token); } elseif(is_numeric($token)) { // number, skip it } else { $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__); } break; } } if ($elseif) return '<?php elseif ('.implode(' ', $tokens).'): ?>'; else return '<?php if ('.implode(' ', $tokens).'): ?>'; } function _compile_arg_list($type, $name, $attrs, &$cache_code) { $arg_list = array(); if (isset($type) && isset($name) && isset($this->_plugins[$type]) && isset($this->_plugins[$type][$name]) && empty($this->_plugins[$type][$name][4]) && is_array($this->_plugins[$type][$name][5]) ) { /* we have a list of parameters that should be cached */ $_cache_attrs = $this->_plugins[$type][$name][5]; $_count = $this->_cache_attrs_count++; $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');"; } else { /* no parameters are cached */ $_cache_attrs = null; } foreach ($attrs as $arg_name => $arg_value) { if (is_bool($arg_value)) $arg_value = $arg_value ? 'true' : 'false'; if (is_null($arg_value)) $arg_value = 'null'; if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) { $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)"; } else { $arg_list[] = "'$arg_name' => $arg_value"; } } return $arg_list; } /** * Parse is expression * * @param string $is_arg * @param array $tokens * @return array */ function _parse_is_expr($is_arg, $tokens) { $expr_end = 0; $negate_expr = false; if (($first_token = array_shift($tokens)) == 'not') { $negate_expr = true; $expr_type = array_shift($tokens); } else $expr_type = $first_token; switch ($expr_type) { case 'even': if (@$tokens[$expr_end] == 'by') { $expr_end++; $expr_arg = $tokens[$expr_end++]; $expr = "!(($is_arg / $expr_arg) % " . $this->_parse_var_props($expr_arg) . ")"; } else $expr = "!($is_arg % 2)"; break; case 'odd': if (@$tokens[$expr_end] == 'by') { $expr_end++; $expr_arg = $tokens[$expr_end++]; $expr = "(($is_arg / $expr_arg) % ". $this->_parse_var_props($expr_arg) . ")"; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -