PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/SmartyCustom.php

https://gitlab.com/staging06/myproject
PHP | 320 lines | 181 code | 29 blank | 110 comment | 42 complexity | 439dc2be281640630b5ca53a1bb0fd1b MD5 | raw file
  1. <?php
  2. /*
  3. * 2007-2015 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2015 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. class SmartyCustomCore extends Smarty
  27. {
  28. public function __construct()
  29. {
  30. parent::__construct();
  31. $this->template_class = 'Smarty_Custom_Template';
  32. }
  33. /**
  34. * Delete compiled template file (lazy delete if resource_name is not specified)
  35. *
  36. * @param string $resource_name template name
  37. * @param string $compile_id compile id
  38. * @param int $exp_time expiration time
  39. *
  40. * @return int number of template files deleted
  41. */
  42. public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
  43. {
  44. if ($resource_name == null) {
  45. Db::getInstance()->execute('REPLACE INTO `'._DB_PREFIX_.'smarty_last_flush` (`type`, `last_flush`) VALUES (\'compile\', FROM_UNIXTIME('.time().'))');
  46. return 0;
  47. } else {
  48. return parent::clearCompiledTemplate($resource_name, $compile_id, $exp_time);
  49. }
  50. }
  51. /**
  52. * Mark all template files to be regenerated
  53. *
  54. * @param int $exp_time expiration time
  55. * @param string $type resource type
  56. *
  57. * @return int number of cache files which needs to be updated
  58. */
  59. public function clearAllCache($exp_time = null, $type = null)
  60. {
  61. Db::getInstance()->execute('REPLACE INTO `'._DB_PREFIX_.'smarty_last_flush` (`type`, `last_flush`) VALUES (\'template\', FROM_UNIXTIME('.time().'))');
  62. return $this->delete_from_lazy_cache(null, null, null);
  63. }
  64. /**
  65. * Mark file to be regenerated for a specific template
  66. *
  67. * @param string $template_name template name
  68. * @param string $cache_id cache id
  69. * @param string $compile_id compile id
  70. * @param int $exp_time expiration time
  71. * @param string $type resource type
  72. *
  73. * @return int number of cache files which needs to be updated
  74. */
  75. public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
  76. {
  77. return $this->delete_from_lazy_cache($template_name, $cache_id, $compile_id);
  78. }
  79. /**
  80. * Check the compile cache needs to be invalidated (multi front + local cache compatible)
  81. */
  82. public function check_compile_cache_invalidation()
  83. {
  84. static $last_flush = null;
  85. if (!file_exists($this->getCompileDir().'last_flush')) {
  86. @touch($this->getCompileDir().'last_flush', time());
  87. } elseif (defined('_DB_PREFIX_')) {
  88. if ($last_flush === null) {
  89. $sql = 'SELECT UNIX_TIMESTAMP(last_flush) as last_flush FROM `'._DB_PREFIX_.'smarty_last_flush` WHERE type=\'compile\'';
  90. $last_flush = Db::getInstance()->getValue($sql, false);
  91. }
  92. if ((int)$last_flush && @filemtime($this->getCompileDir().'last_flush') < $last_flush) {
  93. @touch($this->getCompileDir().'last_flush', time());
  94. parent::clearCompiledTemplate();
  95. }
  96. }
  97. }
  98. /**
  99. * {@inheritDoc}
  100. */
  101. public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false)
  102. {
  103. $this->check_compile_cache_invalidation();
  104. return parent::fetch($template, $cache_id, $compile_id, $parent, $display, $merge_tpl_vars, $no_output_filter);
  105. }
  106. /**
  107. * {@inheritDoc}
  108. */
  109. public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
  110. {
  111. $this->check_compile_cache_invalidation();
  112. if ($this->caching) {
  113. $this->check_template_invalidation($template, $cache_id, $compile_id);
  114. return parent::createTemplate($template, $cache_id, $compile_id, $parent, $do_clone);
  115. } else {
  116. return parent::createTemplate($template, $cache_id, $compile_id, $parent, $do_clone);
  117. }
  118. }
  119. /**
  120. * Handle the lazy template cache invalidation
  121. *
  122. * @param string $template template name
  123. * @param string $cache_id cache id
  124. * @param string $compile_id compile id
  125. */
  126. public function check_template_invalidation($template, $cache_id, $compile_id)
  127. {
  128. static $last_flush = null;
  129. if (!file_exists($this->getCacheDir().'last_template_flush')) {
  130. @touch($this->getCacheDir().'last_template_flush', time());
  131. } elseif (defined('_DB_PREFIX_')) {
  132. if ($last_flush === null) {
  133. $sql = 'SELECT UNIX_TIMESTAMP(last_flush) as last_flush FROM `'._DB_PREFIX_.'smarty_last_flush` WHERE type=\'template\'';
  134. $last_flush = Db::getInstance()->getValue($sql, false);
  135. }
  136. if ((int)$last_flush && @filemtime($this->getCacheDir().'last_template_flush') < $last_flush) {
  137. @touch($this->getCacheDir().'last_template_flush', time());
  138. parent::clearAllCache();
  139. } else {
  140. if ($cache_id !== null && (is_object($cache_id) || is_array($cache_id))) {
  141. $cache_id = null;
  142. }
  143. if ($this->is_in_lazy_cache($template, $cache_id, $compile_id) === false) {
  144. // insert in cache before the effective cache creation to avoid nasty race condition
  145. $this->insert_in_lazy_cache($template, $cache_id, $compile_id);
  146. parent::clearCache($template, $cache_id, $compile_id);
  147. }
  148. }
  149. }
  150. }
  151. /**
  152. * Store the cache file path
  153. *
  154. * @param string $filepath cache file path
  155. * @param string $template template name
  156. * @param string $cache_id cache id
  157. * @param string $compile_id compile id
  158. */
  159. public function update_filepath($filepath, $template, $cache_id, $compile_id)
  160. {
  161. $template_md5 = md5($template);
  162. $sql = 'UPDATE `'._DB_PREFIX_.'smarty_lazy_cache`
  163. SET filepath=\''.pSQL($filepath).'\'
  164. WHERE `template_hash`=\''.pSQL($template_md5).'\'';
  165. $sql .= ' AND cache_id="'.pSQL((string)$cache_id).'"';
  166. if (strlen($compile_id) > 32) {
  167. $compile_id = md5($compile_id);
  168. }
  169. $sql .= ' AND compile_id="'.pSQL((string)$compile_id).'"';
  170. Db::getInstance()->execute($sql, false);
  171. }
  172. /**
  173. * Check if the current template is stored in the lazy cache
  174. * Entry in the lazy cache = no need to regenerate the template
  175. *
  176. * @param string $template template name
  177. * @param string $cache_id cache id
  178. * @param string $compile_id compile id
  179. *
  180. * @return bool
  181. */
  182. public function is_in_lazy_cache($template, $cache_id, $compile_id)
  183. {
  184. static $is_in_lazy_cache = array();
  185. $template_md5 = md5($template);
  186. if (strlen($compile_id) > 32) {
  187. $compile_id = md5($compile_id);
  188. }
  189. $key = md5($template_md5.'-'.$cache_id.'-'.$compile_id);
  190. if (isset($is_in_lazy_cache[$key])) {
  191. return $is_in_lazy_cache[$key];
  192. } else {
  193. $sql = 'SELECT UNIX_TIMESTAMP(last_update) as last_update, filepath FROM `'._DB_PREFIX_.'smarty_lazy_cache`
  194. WHERE `template_hash`=\''.pSQL($template_md5).'\'';
  195. $sql .= ' AND cache_id="'.pSQL((string)$cache_id).'"';
  196. $sql .= ' AND compile_id="'.pSQL((string)$compile_id).'"';
  197. $result = Db::getInstance()->getRow($sql, false);
  198. // If the filepath is not yet set, it means the cache update is in progress in another process.
  199. // In this case do not try to clear the cache again and tell to use the existing cache, if any
  200. if ($result !== false && $result['filepath'] == '') {
  201. // If the cache update is stalled for more than 1min, something should be wrong,
  202. // remove the entry from the lazy cache
  203. if ($result['last_update'] < time() - 60) {
  204. $this->delete_from_lazy_cache($template, $cache_id, $compile_id);
  205. }
  206. $return = true;
  207. } else {
  208. if ($result === false
  209. || @filemtime($this->getCacheDir().$result['filepath']) < $result['last_update']) {
  210. $return = false;
  211. } else {
  212. $return = $result['filepath'];
  213. }
  214. }
  215. $is_in_lazy_cache[$key] = $return;
  216. }
  217. return $return;
  218. }
  219. /**
  220. * Insert the current template in the lazy cache
  221. *
  222. * @param string $template template name
  223. * @param string $cache_id cache id
  224. * @param string $compile_id compile id
  225. *
  226. * @return bool
  227. */
  228. public function insert_in_lazy_cache($template, $cache_id, $compile_id)
  229. {
  230. $template_md5 = md5($template);
  231. $sql = 'INSERT IGNORE INTO `'._DB_PREFIX_.'smarty_lazy_cache`
  232. (`template_hash`, `cache_id`, `compile_id`, `last_update`)
  233. VALUES (\''.pSQL($template_md5).'\'';
  234. $sql .= ',"'.pSQL((string)$cache_id).'"';
  235. if (strlen($compile_id) > 32) {
  236. $compile_id = md5($compile_id);
  237. }
  238. $sql .= ',"'.pSQL((string)$compile_id).'"';
  239. $sql .= ', FROM_UNIXTIME('.time().'))';
  240. return Db::getInstance()->execute($sql, false);
  241. }
  242. /**
  243. * Delete the current template from the lazy cache or the whole cache if no template name is given
  244. *
  245. * @param string $template template name
  246. * @param string $cache_id cache id
  247. * @param string $compile_id compile id
  248. *
  249. * @return bool
  250. */
  251. public function delete_from_lazy_cache($template, $cache_id, $compile_id)
  252. {
  253. if (!$template) {
  254. return Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'smarty_lazy_cache`', false);
  255. }
  256. $template_md5 = md5($template);
  257. $sql = 'DELETE FROM `'._DB_PREFIX_.'smarty_lazy_cache`
  258. WHERE template_hash=\''.pSQL($template_md5).'\'';
  259. if ($cache_id != null) {
  260. $sql .= ' AND cache_id LIKE "'.pSQL((string)$cache_id).'%"';
  261. }
  262. if ($compile_id != null) {
  263. if (strlen($compile_id) > 32) {
  264. $compile_id = md5($compile_id);
  265. }
  266. $sql .= ' AND compile_id="'.pSQL((string)$compile_id).'"';
  267. }
  268. Db::getInstance()->execute($sql, false);
  269. return Db::getInstance()->Affected_Rows();
  270. }
  271. }
  272. class Smarty_Custom_Template extends Smarty_Internal_Template
  273. {
  274. /** @var SmartyCustom|null */
  275. public $smarty = null;
  276. public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false)
  277. {
  278. if ($this->smarty->caching) {
  279. $tpl = parent::fetch($template, $cache_id, $compile_id, $parent, $display, $merge_tpl_vars, $no_output_filter);
  280. if (property_exists($this, 'cached')) {
  281. $filepath = str_replace($this->smarty->getCacheDir(), '', $this->cached->filepath);
  282. if ($this->smarty->is_in_lazy_cache($this->template_resource, $this->cache_id, $this->compile_id) != $filepath) {
  283. $this->smarty->update_filepath($filepath, $this->template_resource, $this->cache_id, $this->compile_id);
  284. }
  285. }
  286. return $tpl;
  287. } else {
  288. return parent::fetch($template, $cache_id, $compile_id, $parent, $display, $merge_tpl_vars, $no_output_filter);
  289. }
  290. }
  291. }