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.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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", "\r"), "\n", $_content), $this),
  85. $this);
  86. if ($isTemplateSource && $this->template->caching) {
  87. $this->parser->insertPhpCode("<?php\n\$_smarty_tpl->compiled->nocache_hash = '{$this->nocache_hash}';\n?>\n");
  88. }
  89. if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
  90. $mbEncoding = mb_internal_encoding();
  91. mb_internal_encoding('ASCII');
  92. } else {
  93. $mbEncoding = null;
  94. }
  95. if ($this->smarty->_parserdebug) {
  96. $this->parser->PrintTrace();
  97. $this->parser->lex->PrintTrace();
  98. }
  99. // get tokens from lexer and parse them
  100. while ($this->parser->lex->yylex()) {
  101. if ($this->smarty->_parserdebug) {
  102. echo "<pre>Line {$this->parser->lex->line} Parsing {$this->parser->yyTokenName[$this->parser->lex->token]} Token " .
  103. htmlentities($this->parser->lex->value) . "</pre>";
  104. }
  105. $this->parser->doParse($this->parser->lex->token, $this->parser->lex->value);
  106. }
  107. // finish parsing process
  108. $this->parser->doParse(0, 0);
  109. if ($mbEncoding) {
  110. mb_internal_encoding($mbEncoding);
  111. }
  112. // check for unclosed tags
  113. if (count($this->_tag_stack) > 0) {
  114. // get stacked info
  115. list($openTag, $_data) = array_pop($this->_tag_stack);
  116. $this->trigger_template_error("unclosed {$this->smarty->left_delimiter}" . $openTag .
  117. "{$this->smarty->right_delimiter} tag");
  118. }
  119. // call post compile callbacks
  120. foreach ($this->postCompileCallbacks as $cb) {
  121. $parameter = $cb;
  122. $parameter[0] = $this;
  123. call_user_func_array($cb[0], $parameter);
  124. }
  125. // return compiled code
  126. return $this->prefixCompiledCode . $this->parser->retvalue . $this->postfixCompiledCode;
  127. }
  128. /**
  129. * Register a post compile callback
  130. * - when the callback is called after template compiling the compiler object will be inserted as first parameter
  131. *
  132. * @param callback $callback
  133. * @param array $parameter optional parameter array
  134. * @param string $key optional key for callback
  135. * @param bool $replace if true replace existing keyed callback
  136. */
  137. public function registerPostCompileCallback($callback, $parameter = array(), $key = null, $replace = false)
  138. {
  139. array_unshift($parameter, $callback);
  140. if (isset($key)) {
  141. if ($replace || !isset($this->postCompileCallbacks[$key])) {
  142. $this->postCompileCallbacks[$key] = $parameter;
  143. }
  144. } else {
  145. $this->postCompileCallbacks[] = $parameter;
  146. }
  147. }
  148. /**
  149. * Remove a post compile callback
  150. *
  151. * @param string $key callback key
  152. */
  153. public function unregisterPostCompileCallback($key)
  154. {
  155. unset($this->postCompileCallbacks[$key]);
  156. }
  157. }