You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

smarty_internal_runtime_tplfunction.php 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. /**
  3. * TplFunction Runtime Methods callTemplateFunction
  4. *
  5. * @package Smarty
  6. * @subpackage PluginsInternal
  7. * @author Uwe Tews
  8. *
  9. **/
  10. class Smarty_Internal_Runtime_TplFunction
  11. {
  12. /**
  13. * Call template function
  14. *
  15. * @param \Smarty_Internal_Template $tpl template object
  16. * @param string $name template function name
  17. * @param array $params parameter array
  18. * @param bool $nocache true if called nocache
  19. *
  20. * @throws \SmartyException
  21. */
  22. public function callTemplateFunction(Smarty_Internal_Template $tpl, $name, $params, $nocache)
  23. {
  24. $funcParam = isset($tpl->tplFunctions[ $name ]) ? $tpl->tplFunctions[ $name ] :
  25. (isset($tpl->smarty->tplFunctions[ $name ]) ? $tpl->smarty->tplFunctions[ $name ] : null);
  26. if (isset($funcParam)) {
  27. if (!$tpl->caching || ($tpl->caching && $nocache)) {
  28. $function = $funcParam[ 'call_name' ];
  29. } else {
  30. if (isset($funcParam[ 'call_name_caching' ])) {
  31. $function = $funcParam[ 'call_name_caching' ];
  32. } else {
  33. $function = $funcParam[ 'call_name' ];
  34. }
  35. }
  36. if (function_exists($function)) {
  37. $this->saveTemplateVariables($tpl, $name);
  38. $function ($tpl, $params);
  39. $this->restoreTemplateVariables($tpl, $name);
  40. return;
  41. }
  42. // try to load template function dynamically
  43. if ($this->addTplFuncToCache($tpl, $name, $function)) {
  44. $this->saveTemplateVariables($tpl, $name);
  45. $function ($tpl, $params);
  46. $this->restoreTemplateVariables($tpl, $name);
  47. return;
  48. }
  49. }
  50. throw new SmartyException("Unable to find template function '{$name}'");
  51. }
  52. /**
  53. * Register template functions defined by template
  54. *
  55. * @param \Smarty|\Smarty_Internal_Template|\Smarty_Internal_TemplateBase $obj
  56. * @param array $tplFunctions source information array of template functions defined in template
  57. * @param bool $override if true replace existing functions with same name
  58. */
  59. public function registerTplFunctions(Smarty_Internal_TemplateBase $obj, $tplFunctions, $override = true)
  60. {
  61. $obj->tplFunctions =
  62. $override ? array_merge($obj->tplFunctions, $tplFunctions) : array_merge($tplFunctions, $obj->tplFunctions);
  63. // make sure that the template functions are known in parent templates
  64. if ($obj->_isSubTpl()) {
  65. $obj->smarty->ext->_tplFunction->registerTplFunctions($obj->parent, $tplFunctions, false);
  66. } else {
  67. $obj->smarty->tplFunctions = $override ? array_merge($obj->smarty->tplFunctions, $tplFunctions) :
  68. array_merge($tplFunctions, $obj->smarty->tplFunctions);
  69. }
  70. }
  71. /**
  72. * Return source parameter array for single or all template functions
  73. *
  74. * @param \Smarty_Internal_Template $tpl template object
  75. * @param null|string $name template function name
  76. *
  77. * @return array|bool|mixed
  78. */
  79. public function getTplFunction(Smarty_Internal_Template $tpl, $name = null)
  80. {
  81. if (isset($name)) {
  82. return isset($tpl->tplFunctions[ $name ]) ? $tpl->tplFunctions[ $name ] :
  83. (isset($tpl->smarty->tplFunctions[ $name ]) ? $tpl->smarty->tplFunctions[ $name ] : false);
  84. } else {
  85. return empty($tpl->tplFunctions) ? $tpl->smarty->tplFunctions : $tpl->tplFunctions;
  86. }
  87. }
  88. /**
  89. *
  90. * Add template function to cache file for nocache calls
  91. *
  92. * @param Smarty_Internal_Template $tpl
  93. * @param string $_name template function name
  94. * @param string $_function PHP function name
  95. *
  96. * @return bool
  97. */
  98. public function addTplFuncToCache(Smarty_Internal_Template $tpl, $_name, $_function)
  99. {
  100. $funcParam = $tpl->tplFunctions[ $_name ];
  101. if (is_file($funcParam[ 'compiled_filepath' ])) {
  102. // read compiled file
  103. $code = file_get_contents($funcParam[ 'compiled_filepath' ]);
  104. // grab template function
  105. if (preg_match("/\/\* {$_function} \*\/([\S\s]*?)\/\*\/ {$_function} \*\//", $code, $match)) {
  106. // grab source info from file dependency
  107. preg_match("/\s*'{$funcParam['uid']}'([\S\s]*?)\),/", $code, $match1);
  108. unset($code);
  109. // make PHP function known
  110. eval($match[ 0 ]);
  111. if (function_exists($_function)) {
  112. // search cache file template
  113. $tplPtr = $tpl;
  114. while (!isset($tplPtr->cached) && isset($tplPtr->parent)) {
  115. $tplPtr = $tplPtr->parent;
  116. }
  117. // add template function code to cache file
  118. if (isset($tplPtr->cached)) {
  119. $content = $tplPtr->cached->read($tplPtr);
  120. if ($content) {
  121. // check if we must update file dependency
  122. if (!preg_match("/'{$funcParam['uid']}'(.*?)'nocache_hash'/", $content, $match2)) {
  123. $content = preg_replace("/('file_dependency'(.*?)\()/", "\\1{$match1[0]}", $content);
  124. }
  125. $tplPtr->smarty->ext->_updateCache->write($tplPtr,
  126. preg_replace('/\s*\?>\s*$/', "\n", $content) .
  127. "\n" . preg_replace(array('/^\s*<\?php\s+/',
  128. '/\s*\?>\s*$/',), "\n",
  129. $match[ 0 ]));
  130. }
  131. }
  132. return true;
  133. }
  134. }
  135. }
  136. return false;
  137. }
  138. /**
  139. * Save current template variables on stack
  140. *
  141. * @param \Smarty_Internal_Template $tpl
  142. * @param string $name stack name
  143. */
  144. public function saveTemplateVariables(Smarty_Internal_Template $tpl, $name)
  145. {
  146. $tpl->_cache[ 'varStack' ][] =
  147. array('tpl' => $tpl->tpl_vars, 'config' => $tpl->config_vars, 'name' => "_tplFunction_{$name}");
  148. }
  149. /**
  150. * Restore saved variables into template objects
  151. *
  152. * @param \Smarty_Internal_Template $tpl
  153. * @param string $name stack name
  154. */
  155. public function restoreTemplateVariables(Smarty_Internal_Template $tpl, $name)
  156. {
  157. if (isset($tpl->_cache[ 'varStack' ])) {
  158. $vars = array_pop($tpl->_cache[ 'varStack' ]);
  159. $tpl->tpl_vars = $vars[ 'tpl' ];
  160. $tpl->config_vars = $vars[ 'config' ];
  161. }
  162. }
  163. }