smarty_template_compiled.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. /**
  3. * Smarty Resource Data Object
  4. * Meta Data Container for Template Files
  5. *
  6. * @package Smarty
  7. * @subpackage TemplateResources
  8. * @author Rodney Rehm
  9. * @property string $content compiled content
  10. */
  11. class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
  12. {
  13. /**
  14. * nocache hash
  15. *
  16. * @var string|null
  17. */
  18. public $nocache_hash = null;
  19. /**
  20. * get a Compiled Object of this source
  21. *
  22. * @param Smarty_Internal_Template $_template template object
  23. *
  24. * @return Smarty_Template_Compiled compiled object
  25. */
  26. static function load($_template)
  27. {
  28. $compiled = new Smarty_Template_Compiled();
  29. if ($_template->source->handler->hasCompiledHandler) {
  30. $_template->source->handler->populateCompiledFilepath($compiled, $_template);
  31. } else {
  32. $compiled->populateCompiledFilepath($_template);
  33. }
  34. return $compiled;
  35. }
  36. /**
  37. * populate Compiled Object with compiled filepath
  38. *
  39. * @param Smarty_Internal_Template $_template template object
  40. **/
  41. public function populateCompiledFilepath(Smarty_Internal_Template $_template)
  42. {
  43. $source = &$_template->source;
  44. $smarty = &$_template->smarty;
  45. $this->filepath = $smarty->getCompileDir();
  46. if (isset($_template->compile_id)) {
  47. $this->filepath .= preg_replace('![^\w]+!', '_', $_template->compile_id) .
  48. ($smarty->use_sub_dirs ? DS : '^');
  49. }
  50. // if use_sub_dirs, break file into directories
  51. if ($smarty->use_sub_dirs) {
  52. $this->filepath .= $source->uid[ 0 ] . $source->uid[ 1 ] . DS . $source->uid[ 2 ] . $source->uid[ 3 ] . DS .
  53. $source->uid[ 4 ] . $source->uid[ 5 ] . DS;
  54. }
  55. $this->filepath .= $source->uid . '_';
  56. if ($source->isConfig) {
  57. $this->filepath .= (int) $smarty->config_read_hidden + (int) $smarty->config_booleanize * 2 +
  58. (int) $smarty->config_overwrite * 4;
  59. } else {
  60. $this->filepath .= (int) $smarty->merge_compiled_includes + (int) $smarty->escape_html * 2;
  61. }
  62. $this->filepath .= '.' . $source->type;
  63. $basename = $source->handler->getBasename($source);
  64. if (!empty($basename)) {
  65. $this->filepath .= '.' . $basename;
  66. }
  67. if ($_template->caching) {
  68. $this->filepath .= '.cache';
  69. }
  70. $this->filepath .= '.php';
  71. $this->timestamp = $this->exists = is_file($this->filepath);
  72. if ($this->exists) {
  73. $this->timestamp = filemtime($this->filepath);
  74. }
  75. }
  76. /**
  77. * load compiled template or compile from source
  78. *
  79. * @param Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template
  80. *
  81. * @throws Exception
  82. */
  83. public function process(Smarty_Internal_Template $_smarty_tpl)
  84. {
  85. $source = &$_smarty_tpl->source;
  86. $smarty = &$_smarty_tpl->smarty;
  87. if ($source->handler->recompiled) {
  88. $source->handler->process($_smarty_tpl);
  89. } elseif (!$source->handler->uncompiled) {
  90. if (!$this->exists || $smarty->force_compile ||
  91. ($smarty->compile_check && $source->getTimeStamp() > $this->getTimeStamp())
  92. ) {
  93. $this->compileTemplateSource($_smarty_tpl);
  94. $compileCheck = $smarty->compile_check;
  95. $smarty->compile_check = false;
  96. $this->loadCompiledTemplate($_smarty_tpl);
  97. $smarty->compile_check = $compileCheck;
  98. } else {
  99. $_smarty_tpl->mustCompile = true;
  100. @include($this->filepath);
  101. if ($_smarty_tpl->mustCompile) {
  102. $this->compileTemplateSource($_smarty_tpl);
  103. $compileCheck = $smarty->compile_check;
  104. $smarty->compile_check = false;
  105. $this->loadCompiledTemplate($_smarty_tpl);
  106. $smarty->compile_check = $compileCheck;
  107. }
  108. }
  109. $_smarty_tpl->_subTemplateRegister();
  110. $this->processed = true;
  111. }
  112. }
  113. /**
  114. * Load fresh compiled template by including the PHP file
  115. * HHVM requires a work around because of a PHP incompatibility
  116. *
  117. * @param \Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template
  118. */
  119. private function loadCompiledTemplate(Smarty_Internal_Template $_smarty_tpl)
  120. {
  121. if (function_exists('opcache_invalidate') && strlen(ini_get("opcache.restrict_api")) < 1) {
  122. opcache_invalidate($this->filepath, true);
  123. } elseif (function_exists('apc_compile_file')) {
  124. apc_compile_file($this->filepath);
  125. }
  126. if (defined('HHVM_VERSION')) {
  127. eval("?>" . file_get_contents($this->filepath));
  128. } else {
  129. include($this->filepath);
  130. }
  131. }
  132. /**
  133. * render compiled template code
  134. *
  135. * @param Smarty_Internal_Template $_template
  136. *
  137. * @return string
  138. * @throws Exception
  139. */
  140. public function render(Smarty_Internal_Template $_template)
  141. {
  142. // checks if template exists
  143. if (!$_template->source->exists) {
  144. $type = $_template->source->isConfig ? 'config' : 'template';
  145. throw new SmartyException("Unable to load {$type} '{$_template->source->type}:{$_template->source->name}'");
  146. }
  147. if ($_template->smarty->debugging) {
  148. if (!isset($_template->smarty->_debug)) {
  149. $_template->smarty->_debug = new Smarty_Internal_Debug();
  150. }
  151. $_template->smarty->_debug->start_render($_template);
  152. }
  153. if (!$this->processed) {
  154. $this->process($_template);
  155. }
  156. if (isset($_template->cached)) {
  157. $_template->cached->file_dependency =
  158. array_merge($_template->cached->file_dependency, $this->file_dependency);
  159. }
  160. if ($_template->source->handler->uncompiled) {
  161. $_template->source->handler->renderUncompiled($_template->source, $_template);
  162. } else {
  163. $this->getRenderedTemplateCode($_template);
  164. }
  165. if ($_template->caching && $this->has_nocache_code) {
  166. $_template->cached->hashes[ $this->nocache_hash ] = true;
  167. }
  168. if ($_template->smarty->debugging) {
  169. $_template->smarty->_debug->end_render($_template);
  170. }
  171. }
  172. /**
  173. * compile template from source
  174. *
  175. * @param Smarty_Internal_Template $_template
  176. *
  177. * @throws Exception
  178. */
  179. public function compileTemplateSource(Smarty_Internal_Template $_template)
  180. {
  181. $this->file_dependency = array();
  182. $this->includes = array();
  183. $this->nocache_hash = null;
  184. $this->unifunc = null;
  185. // compile locking
  186. if ($saved_timestamp = $this->getTimeStamp()) {
  187. touch($this->filepath);
  188. }
  189. // call compiler
  190. $_template->loadCompiler();
  191. $this->write($_template, $_template->compiler->compileTemplate($_template));
  192. // release compiler object to free memory
  193. unset($_template->compiler);
  194. }
  195. /**
  196. * Write compiled code by handler
  197. *
  198. * @param Smarty_Internal_Template $_template template object
  199. * @param string $code compiled code
  200. *
  201. * @return boolean success
  202. */
  203. public function write(Smarty_Internal_Template $_template, $code)
  204. {
  205. if (!$_template->source->handler->recompiled) {
  206. if ($_template->smarty->ext->_writeFile->writeFile($this->filepath, $code, $_template->smarty) === true) {
  207. $this->timestamp = $this->exists = is_file($this->filepath);
  208. if ($this->exists) {
  209. $this->timestamp = filemtime($this->filepath);
  210. return true;
  211. }
  212. }
  213. return false;
  214. }
  215. return true;
  216. }
  217. /**
  218. * Read compiled content from handler
  219. *
  220. * @param Smarty_Internal_Template $_template template object
  221. *
  222. * @return string content
  223. */
  224. public function read(Smarty_Internal_Template $_template)
  225. {
  226. if (!$_template->source->handler->recompiled) {
  227. return file_get_contents($this->filepath);
  228. }
  229. return isset($this->content) ? $this->content : false;
  230. }
  231. }