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_extension_handler.php 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <?php
  2. /**
  3. * Smarty Extension handler
  4. *
  5. * Load extensions dynamically
  6. *
  7. *
  8. * @package Smarty
  9. * @subpackage PluginsInternal
  10. * @author Uwe Tews
  11. *
  12. * Runtime extensions
  13. * @property Smarty_Internal_Runtime_CacheModify $_cacheModify
  14. * @property Smarty_Internal_Runtime_CacheResourceFile $_cacheResourceFile
  15. * @property Smarty_Internal_Runtime_Capture $_capture
  16. * @property Smarty_Internal_Runtime_CodeFrame $_codeFrame
  17. * @property Smarty_Internal_Runtime_FilterHandler $_filterHandler
  18. * @property Smarty_Internal_Runtime_Foreach $_foreach
  19. * @property Smarty_Internal_Runtime_GetIncludePath $_getIncludePath
  20. * @property Smarty_Internal_Runtime_Make_Nocache $_make_nocache
  21. * @property Smarty_Internal_Runtime_UpdateCache $_updateCache
  22. * @property Smarty_Internal_Runtime_UpdateScope $_updateScope
  23. * @property Smarty_Internal_Runtime_TplFunction $_tplFunction
  24. * @property Smarty_Internal_Runtime_WriteFile $_writeFile
  25. *
  26. * Method extensions
  27. * @property Smarty_Internal_Method_GetTemplateVars $getTemplateVars
  28. * @property Smarty_Internal_Method_Append $append
  29. * @property Smarty_Internal_Method_AppendByRef $appendByRef
  30. * @property Smarty_Internal_Method_AssignGlobal $assignGlobal
  31. * @property Smarty_Internal_Method_AssignByRef $assignByRef
  32. * @property Smarty_Internal_Method_LoadFilter $loadFilter
  33. * @property Smarty_Internal_Method_LoadPlugin $loadPlugin
  34. * @property Smarty_Internal_Method_RegisterFilter $registerFilter
  35. * @property Smarty_Internal_Method_RegisterObject $registerObject
  36. * @property Smarty_Internal_Method_RegisterPlugin $registerPlugin
  37. * @property mixed|\Smarty_Template_Cached configLoad
  38. */
  39. class Smarty_Internal_Extension_Handler
  40. {
  41. public $objType = null;
  42. /**
  43. * Cache for property information from generic getter/setter
  44. * Preloaded with names which should not use with generic getter/setter
  45. *
  46. * @var array
  47. */
  48. private $_property_info = array('AutoloadFilters' => 0, 'DefaultModifiers' => 0, 'ConfigVars' => 0,
  49. 'DebugTemplate' => 0, 'RegisteredObject' => 0, 'StreamVariable' => 0,
  50. 'TemplateVars' => 0, 'Literals' => 'Literals',);#
  51. private $resolvedProperties = array();
  52. /**
  53. * Call external Method
  54. *
  55. * @param \Smarty_Internal_Data $data
  56. * @param string $name external method names
  57. * @param array $args argument array
  58. *
  59. * @return mixed
  60. * @throws SmartyException
  61. */
  62. public function _callExternalMethod(Smarty_Internal_Data $data, $name, $args)
  63. {
  64. /* @var Smarty $data ->smarty */
  65. $smarty = isset($data->smarty) ? $data->smarty : $data;
  66. if (!isset($smarty->ext->$name)) {
  67. if (preg_match('/^((set|get)|(.*?))([A-Z].*)$/', $name, $match)) {
  68. $basename = $this->upperCase($match[4]);
  69. if (!isset($smarty->ext->$basename) && isset($this->_property_info[ $basename ]) &&
  70. is_string($this->_property_info[ $basename ])) {
  71. $class = 'Smarty_Internal_Method_' . $this->_property_info[ $basename ];
  72. if (class_exists($class)) {
  73. $classObj = new $class();
  74. $methodes = get_class_methods($classObj);
  75. foreach ($methodes as $method) {
  76. $smarty->ext->$method = $classObj;
  77. }
  78. }
  79. }
  80. if (!empty($match[2]) && !isset($smarty->ext->$name)) {
  81. $class = 'Smarty_Internal_Method_' . $this->upperCase($name);
  82. if (!class_exists($class)) {
  83. $objType = $data->_objType;
  84. $propertyType = false;
  85. if (!isset($this->resolvedProperties[ $match[0] ][ $objType ])) {
  86. $property = isset($this->resolvedProperties['property'][ $basename ]) ?
  87. $this->resolvedProperties['property'][ $basename ] :
  88. $property = $this->resolvedProperties['property'][ $basename ] = strtolower(join('_',
  89. preg_split('/([A-Z][^A-Z]*)/',
  90. $basename,
  91. -1,
  92. PREG_SPLIT_NO_EMPTY |
  93. PREG_SPLIT_DELIM_CAPTURE)));
  94. if ($property !== false) {
  95. if (property_exists($data, $property)) {
  96. $propertyType = $this->resolvedProperties[ $match[0] ][ $objType ] = 1;
  97. } else if (property_exists($smarty, $property)) {
  98. $propertyType = $this->resolvedProperties[ $match[0] ][ $objType ] = 2;
  99. } else {
  100. $this->resolvedProperties['property'][ $basename ] = $property = false;
  101. }
  102. }
  103. } else {
  104. $propertyType = $this->resolvedProperties[ $match[0] ][ $objType ];
  105. $property = $this->resolvedProperties['property'][ $basename ];
  106. }
  107. if ($propertyType) {
  108. $obj = $propertyType === 1 ? $data : $smarty;
  109. if ($match[2] === 'get') {
  110. return $obj->$property;
  111. } else if ($match[2] === 'set') {
  112. return $obj->$property = $args[0];
  113. }
  114. }
  115. }
  116. }
  117. }
  118. }
  119. $callback = array($smarty->ext->$name, $name);
  120. array_unshift($args, $data);
  121. if (isset($callback) && $callback[0]->objMap | $data->_objType) {
  122. return call_user_func_array($callback, $args);
  123. }
  124. return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), $args);
  125. }
  126. /**
  127. * Make first character of name parts upper case
  128. *
  129. * @param string $name
  130. *
  131. * @return string
  132. */
  133. public function upperCase($name)
  134. {
  135. $_name = explode('_', $name);
  136. $_name = array_map('ucfirst', $_name);
  137. return implode('_', $_name);
  138. }
  139. /**
  140. * get extension object
  141. *
  142. * @param string $property_name property name
  143. *
  144. * @return mixed|Smarty_Template_Cached
  145. * @throws SmartyException
  146. */
  147. public function __get($property_name)
  148. {
  149. // object properties of runtime template extensions will start with '_'
  150. if ($property_name[0] === '_') {
  151. $class = 'Smarty_Internal_Runtime' . $this->upperCase($property_name);
  152. } else {
  153. $class = 'Smarty_Internal_Method_' . $this->upperCase($property_name);
  154. }
  155. if (!class_exists($class)) {
  156. return $this->$property_name = new Smarty_Internal_Undefined($class);
  157. }
  158. return $this->$property_name = new $class();
  159. }
  160. /**
  161. * set extension property
  162. *
  163. * @param string $property_name property name
  164. * @param mixed $value value
  165. *
  166. * @throws SmartyException
  167. */
  168. public function __set($property_name, $value)
  169. {
  170. $this->$property_name = $value;
  171. }
  172. /**
  173. * Call error handler for undefined method
  174. *
  175. * @param string $name unknown method-name
  176. * @param array $args argument array
  177. *
  178. * @return mixed
  179. * @throws SmartyException
  180. */
  181. public function __call($name, $args)
  182. {
  183. return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), array($this));
  184. }
  185. }