smarty_internal_extension_handler.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. * @property Smarty_Internal_Runtime_TplFunction $_tplFunction
  13. * @property Smarty_Internal_Runtime_Foreach $_foreach
  14. * @property Smarty_Internal_Runtime_WriteFile $_writeFile
  15. * @property Smarty_Internal_Runtime_CodeFrame $_codeFrame
  16. * @property Smarty_Internal_Runtime_FilterHandler $_filterHandler
  17. * @property Smarty_Internal_Runtime_GetIncludePath $_getIncludePath
  18. * @property Smarty_Internal_Runtime_UpdateScope $_updateScope
  19. * @property Smarty_Internal_Runtime_CacheModify $_cacheModify
  20. * @property Smarty_Internal_Runtime_UpdateCache $_updateCache
  21. * @property Smarty_Internal_Method_GetTemplateVars $getTemplateVars
  22. * @property Smarty_Internal_Method_Append $append
  23. * @property Smarty_Internal_Method_AppendByRef $appendByRef
  24. * @property Smarty_Internal_Method_AssignGlobal $assignGlobal
  25. * @property Smarty_Internal_Method_AssignByRef $assignByRef
  26. * @property Smarty_Internal_Method_LoadFilter $loadFilter
  27. * @property Smarty_Internal_Method_LoadPlugin $loadPlugin
  28. * @property Smarty_Internal_Method_RegisterFilter $registerFilter
  29. * @property Smarty_Internal_Method_RegisterObject $registerObject
  30. * @property Smarty_Internal_Method_RegisterPlugin $registerPlugin
  31. */
  32. class Smarty_Internal_Extension_Handler
  33. {
  34. public $objType = null;
  35. /**
  36. * Cache for property information from generic getter/setter
  37. * Preloaded with names which should not use with generic getter/setter
  38. *
  39. * @var array
  40. */
  41. private $_property_info = array('AutoloadFilters' => 0, 'DefaultModifiers' => 0, 'ConfigVars' => 0,
  42. 'DebugTemplate' => 0, 'RegisteredObject' => 0, 'StreamVariable' => 0,
  43. 'TemplateVars' => 0,);#
  44. private $resolvedProperties = array();
  45. /**
  46. * Call external Method
  47. *
  48. * @param \Smarty_Internal_Data $data
  49. * @param string $name external method names
  50. * @param array $args argument array
  51. *
  52. * @return mixed
  53. * @throws SmartyException
  54. */
  55. public function _callExternalMethod(Smarty_Internal_Data $data, $name, $args)
  56. {
  57. /* @var Smarty $data ->smarty */
  58. $smarty = isset($data->smarty) ? $data->smarty : $data;
  59. if (!isset($smarty->ext->$name)) {
  60. $class = 'Smarty_Internal_Method_' . ucfirst($name);
  61. if (preg_match('/^(set|get)([A-Z].*)$/', $name, $match)) {
  62. if (!isset($this->_property_info[ $prop = $match[ 2 ] ])) {
  63. // convert camel case to underscored name
  64. $this->resolvedProperties[ $prop ] = $pn = strtolower(join('_',
  65. preg_split('/([A-Z][^A-Z]*)/', $prop,
  66. - 1, PREG_SPLIT_NO_EMPTY |
  67. PREG_SPLIT_DELIM_CAPTURE)));
  68. $this->_property_info[ $prop ] = property_exists($data, $pn) ? 1 :
  69. ($data->_objType == 2 && property_exists($smarty, $pn) ? 2 : 0);
  70. }
  71. if ($this->_property_info[ $prop ]) {
  72. $pn = $this->resolvedProperties[ $prop ];
  73. if ($match[ 1 ] == 'get') {
  74. return $this->_property_info[ $prop ] == 1 ? $data->$pn : $data->smarty->$pn;
  75. } else {
  76. return $this->_property_info[ $prop ] == 1 ? $data->$pn = $args[ 0 ] :
  77. $data->smarty->$pn = $args[ 0 ];
  78. }
  79. } elseif (!class_exists($class)) {
  80. throw new SmartyException("property '$pn' does not exist.");
  81. }
  82. }
  83. if (class_exists($class)) {
  84. $callback = array($smarty->ext->$name = new $class(), $name);
  85. }
  86. } else {
  87. $callback = array($smarty->ext->$name, $name);
  88. }
  89. array_unshift($args, $data);
  90. if (isset($callback) && $callback[ 0 ]->objMap | $data->_objType) {
  91. return call_user_func_array($callback, $args);
  92. }
  93. return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), $args);
  94. }
  95. /**
  96. * set extension property
  97. *
  98. * @param string $property_name property name
  99. * @param mixed $value value
  100. *
  101. * @throws SmartyException
  102. */
  103. public function __set($property_name, $value)
  104. {
  105. $this->$property_name = $value;
  106. }
  107. /**
  108. * get extension object
  109. *
  110. * @param string $property_name property name
  111. *
  112. * @return mixed|Smarty_Template_Cached
  113. * @throws SmartyException
  114. */
  115. public function __get($property_name)
  116. {
  117. // object properties of runtime template extensions will start with '_'
  118. if ($property_name[ 0 ] == '_') {
  119. $class = 'Smarty_Internal_Runtime_' . ucfirst(substr($property_name, 1));
  120. } else {
  121. $class = 'Smarty_Internal_Method_' . ucfirst($property_name);
  122. }
  123. return $this->$property_name = new $class();
  124. }
  125. /**
  126. * Call error handler for undefined method
  127. *
  128. * @param string $name unknown method-name
  129. * @param array $args argument array
  130. *
  131. * @return mixed
  132. * @throws SmartyException
  133. */
  134. public function __call($name, $args)
  135. {
  136. return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), array($this));
  137. }
  138. }