You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

smarty_internal_smartytemplatecompiler.php 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <?php
  2. /**
  3. * Smarty Internal Plugin Smarty Template Compiler Base
  4. * This file contains the basic classes and methods for compiling Smarty templates with lexer/parser
  5. *
  6. * @package Smarty
  7. * @subpackage Compiler
  8. * @author Uwe Tews
  9. */
  10. /**
  11. * Class SmartyTemplateCompiler
  12. *
  13. * @package Smarty
  14. * @subpackage Compiler
  15. */
  16. class Smarty_Internal_SmartyTemplateCompiler extends Smarty_Internal_TemplateCompilerBase
  17. {
  18. /**
  19. * Lexer class name
  20. *
  21. * @var string
  22. */
  23. public $lexer_class;
  24. /**
  25. * Parser class name
  26. *
  27. * @var string
  28. */
  29. public $parser_class;
  30. /**
  31. * array of vars which can be compiled in local scope
  32. *
  33. * @var array
  34. */
  35. public $local_var = array();
  36. /**
  37. * array of callbacks called when the normal compile process of template is finished
  38. *
  39. * @var array
  40. */
  41. public $postCompileCallbacks = array();
  42. /**
  43. * prefix code
  44. *
  45. * @var string
  46. */
  47. public $prefixCompiledCode = '';
  48. /**
  49. * postfix code
  50. *
  51. * @var string
  52. */
  53. public $postfixCompiledCode = '';
  54. /**
  55. * Initialize compiler
  56. *
  57. * @param string $lexer_class class name
  58. * @param string $parser_class class name
  59. * @param Smarty $smarty global instance
  60. */
  61. public function __construct($lexer_class, $parser_class, Smarty $smarty)
  62. {
  63. parent::__construct($smarty);
  64. // get required plugins
  65. $this->lexer_class = $lexer_class;
  66. $this->parser_class = $parser_class;
  67. }
  68. /**
  69. * method to compile a Smarty template
  70. *
  71. * @param mixed $_content template source
  72. * @param bool $isTemplateSource
  73. *
  74. * @return bool true if compiling succeeded, false if it failed
  75. * @throws \SmartyCompilerException
  76. */
  77. protected function doCompile($_content, $isTemplateSource = false)
  78. {
  79. /* here is where the compiling takes place. Smarty
  80. tags in the templates are replaces with PHP code,
  81. then written to compiled files. */
  82. // init the lexer/parser to compile the template
  83. $this->parser =
  84. new $this->parser_class(new $this->lexer_class(str_replace(array("\r\n",
  85. "\r"), "\n", $_content), $this),
  86. $this);
  87. if ($isTemplateSource && $this->template->caching) {
  88. $this->parser->insertPhpCode("<?php\n\$_smarty_tpl->compiled->nocache_hash = '{$this->nocache_hash}';\n?>\n");
  89. }
  90. if (function_exists('mb_internal_encoding')
  91. && function_exists('ini_get')
  92. && ((int) ini_get('mbstring.func_overload')) & 2
  93. ) {
  94. $mbEncoding = mb_internal_encoding();
  95. mb_internal_encoding('ASCII');
  96. } else {
  97. $mbEncoding = null;
  98. }
  99. if ($this->smarty->_parserdebug) {
  100. $this->parser->PrintTrace();
  101. $this->parser->lex->PrintTrace();
  102. }
  103. // get tokens from lexer and parse them
  104. while ($this->parser->lex->yylex()) {
  105. if ($this->smarty->_parserdebug) {
  106. echo "<pre>Line {$this->parser->lex->line} Parsing {$this->parser->yyTokenName[$this->parser->lex->token]} Token " .
  107. htmlentities($this->parser->lex->value) . "</pre>";
  108. }
  109. $this->parser->doParse($this->parser->lex->token, $this->parser->lex->value);
  110. }
  111. // finish parsing process
  112. $this->parser->doParse(0, 0);
  113. if ($mbEncoding) {
  114. mb_internal_encoding($mbEncoding);
  115. }
  116. // check for unclosed tags
  117. if (count($this->_tag_stack) > 0) {
  118. // get stacked info
  119. list($openTag, $_data) = array_pop($this->_tag_stack);
  120. $this->trigger_template_error("unclosed {$this->smarty->left_delimiter}" . $openTag .
  121. "{$this->smarty->right_delimiter} tag");
  122. }
  123. // call post compile callbacks
  124. foreach ($this->postCompileCallbacks as $cb) {
  125. $parameter = $cb;
  126. $parameter[ 0 ] = $this;
  127. call_user_func_array($cb[ 0 ], $parameter);
  128. }
  129. // return compiled code
  130. return $this->prefixCompiledCode . $this->parser->retvalue . $this->postfixCompiledCode;
  131. }
  132. /**
  133. * Register a post compile callback
  134. * - when the callback is called after template compiling the compiler object will be inserted as first parameter
  135. *
  136. * @param callback $callback
  137. * @param array $parameter optional parameter array
  138. * @param string $key optional key for callback
  139. * @param bool $replace if true replace existing keyed callback
  140. *
  141. */
  142. public function registerPostCompileCallback($callback, $parameter = array(), $key = null, $replace = false)
  143. {
  144. array_unshift($parameter, $callback);
  145. if (isset($key)) {
  146. if ($replace || !isset($this->postCompileCallbacks[ $key ])) {
  147. $this->postCompileCallbacks[ $key ] = $parameter;
  148. }
  149. } else {
  150. $this->postCompileCallbacks[] = $parameter;
  151. }
  152. }
  153. /**
  154. * Remove a post compile callback
  155. *
  156. * @param string $key callback key
  157. */
  158. public function unregisterPostCompileCallback($key)
  159. {
  160. unset($this->postCompileCallbacks[ $key ]);
  161. }
  162. }