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