3 * Smarty Internal Plugin Smarty Template Compiler Base
4 * This file contains the basic classes and methods for compiling Smarty templates with lexer/parser
12 * Class SmartyTemplateCompiler
15 * @subpackage Compiler
17 class Smarty_Internal_SmartyTemplateCompiler extends Smarty_Internal_TemplateCompilerBase
34 * array of vars which can be compiled in local scope
38 public $local_var = array();
41 * array of callbacks called when the normal compile process of template is finished
45 public $postCompileCallbacks = array();
52 public $prefixCompiledCode = '';
59 public $postfixCompiledCode = '';
64 * @param string $lexer_class class name
65 * @param string $parser_class class name
66 * @param Smarty $smarty global instance
68 public function __construct($lexer_class, $parser_class, Smarty $smarty)
70 parent::__construct($smarty);
71 // get required plugins
72 $this->lexer_class = $lexer_class;
73 $this->parser_class = $parser_class;
77 * method to compile a Smarty template
79 * @param mixed $_content template source
80 * @param bool $isTemplateSource
82 * @return bool true if compiling succeeded, false if it failed
83 * @throws \SmartyCompilerException
85 protected function doCompile($_content, $isTemplateSource = false)
87 /* here is where the compiling takes place. Smarty
88 tags in the templates are replaces with PHP code,
89 then written to compiled files. */
90 // init the lexer/parser to compile the template
92 new $this->parser_class(new $this->lexer_class(str_replace(array("\r\n", "\r"), "\n", $_content), $this),
94 if ($isTemplateSource && $this->template->caching) {
95 $this->parser->insertPhpCode("<?php\n\$_smarty_tpl->compiled->nocache_hash = '{$this->nocache_hash}';\n?>\n");
97 if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
98 $mbEncoding = mb_internal_encoding();
99 mb_internal_encoding('ASCII');
104 if ($this->smarty->_parserdebug) {
105 $this->parser->PrintTrace();
106 $this->parser->lex->PrintTrace();
108 // get tokens from lexer and parse them
109 while ($this->parser->lex->yylex()) {
110 if ($this->smarty->_parserdebug) {
111 echo "<pre>Line {$this->parser->lex->line} Parsing {$this->parser->yyTokenName[$this->parser->lex->token]} Token " .
112 htmlentities($this->parser->lex->value) . "</pre>";
114 $this->parser->doParse($this->parser->lex->token, $this->parser->lex->value);
117 // finish parsing process
118 $this->parser->doParse(0, 0);
120 mb_internal_encoding($mbEncoding);
122 // check for unclosed tags
123 if (count($this->_tag_stack) > 0) {
125 list($openTag, $_data) = array_pop($this->_tag_stack);
126 $this->trigger_template_error("unclosed {$this->smarty->left_delimiter}" . $openTag .
127 "{$this->smarty->right_delimiter} tag");
129 // call post compile callbacks
130 foreach ($this->postCompileCallbacks as $cb) {
132 $parameter[ 0 ] = $this;
133 call_user_func_array($cb[ 0 ], $parameter);
135 // return compiled code
136 return $this->prefixCompiledCode . $this->parser->retvalue . $this->postfixCompiledCode;
140 * Register a post compile callback
141 * - when the callback is called after template compiling the compiler object will be inserted as first parameter
143 * @param callback $callback
144 * @param array $parameter optional parameter array
145 * @param string $key optional key for callback
146 * @param bool $replace if true replace existing keyed callback
149 public function registerPostCompileCallback($callback, $parameter = array(), $key = null, $replace = false)
151 array_unshift($parameter, $callback);
153 if ($replace || !isset($this->postCompileCallbacks[ $key ])) {
154 $this->postCompileCallbacks[ $key ] = $parameter;
157 $this->postCompileCallbacks[] = $parameter;
162 * Remove a post compile callback
164 * @param string $key callback key
166 public function unregisterPostCompileCallback($key)
168 unset($this->postCompileCallbacks[ $key ]);