/php/extlib/smarty/libs/sysplugins/smarty_internal_smartytemplatecompiler.php

https://github.com/usualoma/movabletype · PHP · 184 lines · 89 code · 10 blank · 85 comment · 15 complexity · 7ed3e482eff2c5ab82efddcb6f4738d0 MD5 · raw file

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