You are here

function Smarty_Compiler::_compile_file in Quiz 6.5

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

compile a resource

sets $compiled_content to the compiled source

Parameters

string $resource_name:

string $source_content:

string $compiled_content:

Return value

true

File

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

Class

Smarty_Compiler
Template compiling class @package Smarty

Code

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;

      /* remove leading whitespaces */
      $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
    }
    if ($strip) {

      /* strip all $text_blocks before the next '/strip' */
      for ($j = $i + 1; $j < $for_max; $j++) {

        /* remove leading and trailing whitespaces of each line */
        $text_blocks[$j] = preg_replace('![\\t ]*[\\r\\n]+[\\t ]*!', '', $text_blocks[$j]);
        if ($compiled_tags[$j] == '{/strip}') {

          /* remove trailing whitespaces from the last text_block */
          $text_blocks[$j] = rtrim($text_blocks[$j]);
        }
        $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array(
          "'" => "\\'",
          "\\" => "\\\\",
        )) . "'; ?>";
        if ($compiled_tags[$j] == '{/strip}') {
          $compiled_tags[$j] = "\n";

          /* slurped by php, but necessary
             if a newline is following the closing strip-tag */
          $strip = false;
          $i = $j;
          break;
        }
      }
    }
  }
  $compiled_content = '';

  /* Interleave the compiled contents and text blocks to get the final result. */
  for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
    if ($compiled_tags[$i] == '') {

      // tag result empty, remove first newline from following text block
      $text_blocks[$i + 1] = preg_replace('~^(\\r\\n|\\r|\\n)~', '', $text_blocks[$i + 1]);
    }
    $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
  }
  $compiled_content .= $text_blocks[$i];

  // remove \n from the end of the file, if any
  if (($_len = strlen($compiled_content)) && $compiled_content[$_len - 1] == "\n") {
    $compiled_content = substr($compiled_content, 0, -1);
  }
  if (!empty($this->_cache_serial)) {
    $compiled_content = "<?php \$this->_cache_serials['" . $this->_cache_include . "'] = '" . $this->_cache_serial . "'; ?>" . $compiled_content;
  }

  // remove unnecessary close/open tags
  $compiled_content = preg_replace('~\\?>\\n?<\\?php~', '', $compiled_content);

  // run compiled template through postfilter functions
  if (count($this->_plugins['postfilter']) > 0) {
    foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
      if ($postfilter === false) {
        continue;
      }
      if ($postfilter[3] || is_callable($postfilter[0])) {
        $compiled_content = call_user_func_array($postfilter[0], array(
          $compiled_content,
          &$this,
        ));
        $this->_plugins['postfilter'][$filter_name][3] = true;
      }
      else {
        $this
          ->_trigger_fatal_error("Smarty plugin error: postfilter '{$filter_name}' is not implemented");
      }
    }
  }

  // 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 " . strtr(urlencode($resource_name), array(
    '%2F' => '/',
    '%3A' => ':',
  )) . " */ ?>\n";

  /* Emit code to load needed plugins. */
  $this->_plugins_code = '';
  if (count($this->_plugin_info)) {
    $_plugins_params = "array('plugins' => array(";
    foreach ($this->_plugin_info as $plugin_type => $plugins) {
      foreach ($plugins as $plugin_name => $plugin_info) {
        $_plugins_params .= "array('{$plugin_type}', '{$plugin_name}', '" . strtr($plugin_info[0], array(
          "'" => "\\'",
          "\\" => "\\\\",
        )) . "', {$plugin_info[1]}, ";
        $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
      }
    }
    $_plugins_params .= '))';
    $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins({$_plugins_params}, \$this); ?>\n";
    $template_header .= $plugins_code;
    $this->_plugin_info = array();
    $this->_plugins_code = $plugins_code;
  }
  if ($this->_init_smarty_vars) {
    $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
    $this->_init_smarty_vars = false;
  }
  $compiled_content = $template_header . $compiled_content;
  return true;
}