4 * Smarty Resource Data Object
5 * Meta Data Container for Template Files
8 * @subpackage TemplateResources
10 * @property string $content compiled content
12 class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
20 public $nocache_hash = null;
23 * get a Compiled Object of this source
25 * @param Smarty_Internal_Template $_template template object
27 * @return Smarty_Template_Compiled compiled object
29 static function load($_template)
31 $compiled = new Smarty_Template_Compiled();
32 if ($_template->source->handler->hasCompiledHandler) {
33 $_template->source->handler->populateCompiledFilepath($compiled, $_template);
35 $compiled->populateCompiledFilepath($_template);
41 * populate Compiled Object with compiled filepath
43 * @param Smarty_Internal_Template $_template template object
45 public function populateCompiledFilepath(Smarty_Internal_Template $_template)
47 $source = &$_template->source;
48 $smarty = &$_template->smarty;
49 $this->filepath = $smarty->getCompileDir();
50 if (isset($_template->compile_id)) {
51 $this->filepath .= preg_replace('![^\w]+!', '_', $_template->compile_id) .
52 ($smarty->use_sub_dirs ? $smarty->ds : '^');
54 // if use_sub_dirs, break file into directories
55 if ($smarty->use_sub_dirs) {
56 $this->filepath .= $source->uid[ 0 ] . $source->uid[ 1 ] . $smarty->ds . $source->uid[ 2 ] .
57 $source->uid[ 3 ] . $smarty->ds . $source->uid[ 4 ] . $source->uid[ 5 ] . $smarty->ds;
59 $this->filepath .= $source->uid . '_';
60 if ($source->isConfig) {
61 $this->filepath .= (int) $smarty->config_read_hidden + (int) $smarty->config_booleanize * 2 +
62 (int) $smarty->config_overwrite * 4;
64 $this->filepath .= (int) $smarty->merge_compiled_includes + (int) $smarty->escape_html * 2 +
65 (($smarty->merge_compiled_includes && $source->type === 'extends') ?
66 (int) $smarty->extends_recursion * 4 : 0);
68 $this->filepath .= '.' . $source->type;
69 $basename = $source->handler->getBasename($source);
70 if (!empty($basename)) {
71 $this->filepath .= '.' . $basename;
73 if ($_template->caching) {
74 $this->filepath .= '.cache';
76 $this->filepath .= '.php';
77 $this->timestamp = $this->exists = is_file($this->filepath);
79 $this->timestamp = filemtime($this->filepath);
84 * load compiled template or compile from source
86 * @param Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template
90 public function process(Smarty_Internal_Template $_smarty_tpl)
92 $source = &$_smarty_tpl->source;
93 $smarty = &$_smarty_tpl->smarty;
94 if ($source->handler->recompiled) {
95 $source->handler->process($_smarty_tpl);
96 } elseif (!$source->handler->uncompiled) {
97 if (!$this->exists || $smarty->force_compile ||
98 ($smarty->compile_check && $source->getTimeStamp() > $this->getTimeStamp())
100 $this->compileTemplateSource($_smarty_tpl);
101 $compileCheck = $smarty->compile_check;
102 $smarty->compile_check = false;
103 $this->loadCompiledTemplate($_smarty_tpl);
104 $smarty->compile_check = $compileCheck;
106 $_smarty_tpl->mustCompile = true;
107 @include($this->filepath);
108 if ($_smarty_tpl->mustCompile) {
109 $this->compileTemplateSource($_smarty_tpl);
110 $compileCheck = $smarty->compile_check;
111 $smarty->compile_check = false;
112 $this->loadCompiledTemplate($_smarty_tpl);
113 $smarty->compile_check = $compileCheck;
116 $_smarty_tpl->_subTemplateRegister();
117 $this->processed = true;
122 * Load fresh compiled template by including the PHP file
123 * HHVM requires a work around because of a PHP incompatibility
125 * @param \Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template
127 private function loadCompiledTemplate(Smarty_Internal_Template $_smarty_tpl)
129 if (function_exists('opcache_invalidate') && strlen(ini_get("opcache.restrict_api")) < 1) {
130 opcache_invalidate($this->filepath, true);
131 } elseif (function_exists('apc_compile_file')) {
132 apc_compile_file($this->filepath);
134 if (defined('HHVM_VERSION')) {
135 eval("?>" . file_get_contents($this->filepath));
137 include($this->filepath);
142 * render compiled template code
144 * @param Smarty_Internal_Template $_template
149 public function render(Smarty_Internal_Template $_template)
151 // checks if template exists
152 if (!$_template->source->exists) {
153 $type = $_template->source->isConfig ? 'config' : 'template';
154 throw new SmartyException("Unable to load {$type} '{$_template->source->type}:{$_template->source->name}'");
156 if ($_template->smarty->debugging) {
157 if (!isset($_template->smarty->_debug)) {
158 $_template->smarty->_debug = new Smarty_Internal_Debug();
160 $_template->smarty->_debug->start_render($_template);
162 if (!$this->processed) {
163 $this->process($_template);
165 if (isset($_template->cached)) {
166 $_template->cached->file_dependency =
167 array_merge($_template->cached->file_dependency, $this->file_dependency);
169 if ($_template->source->handler->uncompiled) {
170 $_template->source->handler->renderUncompiled($_template->source, $_template);
172 $this->getRenderedTemplateCode($_template);
174 if ($_template->caching && $this->has_nocache_code) {
175 $_template->cached->hashes[ $this->nocache_hash ] = true;
177 if ($_template->smarty->debugging) {
178 $_template->smarty->_debug->end_render($_template);
183 * compile template from source
185 * @param Smarty_Internal_Template $_template
189 public function compileTemplateSource(Smarty_Internal_Template $_template)
191 $this->file_dependency = array();
192 $this->includes = array();
193 $this->nocache_hash = null;
194 $this->unifunc = null;
196 $saved_timestamp = $_template->source->handler->recompiled ? false : $this->getTimeStamp();
197 if ($saved_timestamp) {
198 touch($this->filepath);
203 $_template->loadCompiler();
204 $this->write($_template, $_template->compiler->compileTemplate($_template));
206 catch (Exception $e) {
207 // restore old timestamp in case of error
208 if ($saved_timestamp) {
209 touch($this->filepath, $saved_timestamp);
211 unset($_template->compiler);
214 // release compiler object to free memory
215 unset($_template->compiler);
219 * Write compiled code by handler
221 * @param Smarty_Internal_Template $_template template object
222 * @param string $code compiled code
224 * @return boolean success
226 public function write(Smarty_Internal_Template $_template, $code)
228 if (!$_template->source->handler->recompiled) {
229 if ($_template->smarty->ext->_writeFile->writeFile($this->filepath, $code, $_template->smarty) === true) {
230 $this->timestamp = $this->exists = is_file($this->filepath);
232 $this->timestamp = filemtime($this->filepath);
242 * Read compiled content from handler
244 * @param Smarty_Internal_Template $_template template object
246 * @return string content
248 public function read(Smarty_Internal_Template $_template)
250 if (!$_template->source->handler->recompiled) {
251 return file_get_contents($this->filepath);
253 return isset($this->content) ? $this->content : false;