You are here

function Smarty_Compiler::_compile_if_tag in Quiz 6.6

Same name and namespace in other branches
  1. 6.5 includes/moodle/lib/smarty/Smarty_Compiler.class.php \Smarty_Compiler::_compile_if_tag()

Compile {if ...} tag

Parameters

string $tag_args:

boolean $elseif if true, uses elseif instead of if:

Return value

string

1 call to Smarty_Compiler::_compile_if_tag()
Smarty_Compiler::_compile_tag in includes/moodle/lib/smarty/Smarty_Compiler.class.php
Compile a template tag

File

includes/moodle/lib/smarty/Smarty_Compiler.class.php, line 1238

Class

Smarty_Compiler
Template compiling class @package Smarty

Code

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->_var_regexp . '$~', $token) && isset($tokens[$i + 1]) && $tokens[$i + 1] == '(') {

          // variable function call
          $this
            ->_syntax_error("variable function call '{$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) . '): ?>';
  }
}