diff --git a/change_log.txt b/change_log.txt index 07c3890c..d13f422c 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,4 +1,7 @@  ===== 3.1.28-dev===== (xx.xx.2015) + 29.10.2015 + - improve template scope handling + 24.10.2015 - more optimizations of template processing - bugfix Error when using {include} within {capture} https://github.com/smarty-php/smarty/issues/100 diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 5746b665..9ceff2f7 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -87,21 +87,16 @@ if (!class_exists('Smarty_Autoloader', false)) { /** * Load always needed external class files */ - - -if (false) { - if (!class_exists('Smarty_Internal_Data', false)) { - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php'; - } - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_extension_handler.php'; - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php'; - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php'; - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php'; - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php'; - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php'; - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php'; - require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_resource_base.php'; +if (!class_exists('Smarty_Internal_Data', false)) { + require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php'; } +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_extension_handler.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php'; +require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_resource_base.php'; /** * This is the main Smarty class @@ -123,18 +118,24 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.28-dev/73'; + const SMARTY_VERSION = '3.1.28-dev/75'; /** * define variable scopes */ const SCOPE_LOCAL = 0; - const SCOPE_PARENT = 1; + const SCOPE_PARENT = 2; - const SCOPE_ROOT = 2; + const SCOPE_TPL_ROOT = 4; - const SCOPE_GLOBAL = 3; + const SCOPE_ROOT = 8; + + const SCOPE_SMARTY = 16; + + const SCOPE_GLOBAL = 32; + + const SCOPE_BUBBLE_UP = 64; /** * define caching modes @@ -262,7 +263,7 @@ class Smarty extends Smarty_Internal_TemplateBase */ /** - * auto literal on delimiters with whitspace + * auto literal on delimiters with whitespace * * @var boolean */ @@ -276,7 +277,7 @@ class Smarty extends Smarty_Internal_TemplateBase public $error_unassigned = false; /** - * look up relative filepaths in include_path + * look up relative file path in include_path * * @var boolean */ @@ -1070,7 +1071,9 @@ class Smarty extends Smarty_Internal_TemplateBase } else { $data = null; } - if ($this->caching && isset($this->_cache['isCached'][$_templateId = $this->_getTemplateId($template, $cache_id, $compile_id)])) { + if ($this->caching && + isset($this->_cache['isCached'][$_templateId = $this->_getTemplateId($template, $cache_id, $compile_id)]) + ) { $tpl = $do_clone ? clone $this->_cache['isCached'][$_templateId] : $this->_cache['isCached'][$_templateId]; $tpl->parent = $parent; $tpl->tpl_vars = array(); @@ -1119,6 +1122,7 @@ class Smarty extends Smarty_Internal_TemplateBase * @param string $template_name * @param null|mixed $cache_id * @param null|mixed $compile_id + * @param null $caching * * @return string */ @@ -1129,7 +1133,8 @@ class Smarty extends Smarty_Internal_TemplateBase $caching = (int) ($caching === null ? $this->caching : $caching); if ($this->allow_ambiguous_resources) { - $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template_name) . "#{$cache_id}#{$compile_id}#{$caching}"; + $_templateId = + Smarty_Resource::getUniqueTemplateName($this, $template_name) . "#{$cache_id}#{$compile_id}#{$caching}"; } else { $_templateId = $this->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}#{$caching}"; } @@ -1156,7 +1161,8 @@ class Smarty extends Smarty_Internal_TemplateBase if ($pattern == null) { $nds = DS == '/' ? '\\' : '/'; $ds = '\\' . DS; - $pattern = "#([{$ds}]+[^{$ds}]+[{$ds}]+[.]([{$ds}]+[.])*[.][{$ds}]+([.][{$ds}]+)*)|([{$ds}]+([.][{$ds}]+)+)|[{$ds}]{2,}#"; + $pattern = + "#([{$ds}]+[^{$ds}]+[{$ds}]+[.]([{$ds}]+[.])*[.][{$ds}]+([.][{$ds}]+)*)|([{$ds}]+([.][{$ds}]+)+)|[{$ds}]{2,}#"; } // normalize DS if (strpos($path, $nds) !== false) { @@ -1386,8 +1392,8 @@ class Smarty extends Smarty_Internal_TemplateBase if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) { $smarty_dir = realpath(SMARTY_DIR); if ($smarty_dir !== false) { - Smarty::$_muted_directories[SMARTY_DIR] = array('file' => $smarty_dir, - 'length' => strlen($smarty_dir),); + Smarty::$_muted_directories[SMARTY_DIR] = + array('file' => $smarty_dir, 'length' => strlen($smarty_dir),); } } @@ -1413,7 +1419,8 @@ class Smarty extends Smarty_Internal_TemplateBase // or the error was within smarty but masked to be ignored if (!$_is_muted_directory || ($errno && $errno & error_reporting())) { if (Smarty::$_previous_error_handler) { - return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext); + return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, + $errcontext); } else { return false; } diff --git a/libs/sysplugins/smarty_data.php b/libs/sysplugins/smarty_data.php index cc5f6c84..7cf18a43 100644 --- a/libs/sysplugins/smarty_data.php +++ b/libs/sysplugins/smarty_data.php @@ -37,13 +37,6 @@ class Smarty_Data extends Smarty_Internal_Data * @var Smarty */ public $smarty = null; - - /** - * This object type (Smarty = 1, template = 2, data = 4) - * - * @var int - */ - public $_objType = 4; /** * create Smarty data object diff --git a/libs/sysplugins/smarty_internal_compile_assign.php b/libs/sysplugins/smarty_internal_compile_assign.php index 50eaafe9..dd93a620 100644 --- a/libs/sysplugins/smarty_internal_compile_assign.php +++ b/libs/sysplugins/smarty_internal_compile_assign.php @@ -55,31 +55,30 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase $_scope = Smarty::SCOPE_ROOT; } elseif ($_attr['scope'] == 'global') { $_scope = Smarty::SCOPE_GLOBAL; + } elseif ($_attr['scope'] == 'smarty') { + $_scope = Smarty::SCOPE_SMARTY; + } elseif ($_attr['scope'] == 'tpl_root') { + $_scope = Smarty::SCOPE_TPL_ROOT; } else { $compiler->trigger_template_error('illegal value for "scope" attribute', null, true); } + $_scope += (isset($_attr['bubble_up']) && $_attr['bubble_up'] == 'false') ? 0 : Smarty::SCOPE_BUBBLE_UP; + } // compiled output if (isset($parameter['smarty_internal_index'])) { - $output = "smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, $_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];"; + $output = "smarty->ext->_var->createLocalArrayVariable(\$_smarty_tpl, $_attr[var], $_nocache);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];"; } else { // implement Smarty2's behaviour of variables assigned by reference if ($compiler->template->smarty instanceof SmartyBC) { $output = "tpl_vars[$_attr[var]])) {\$_smarty_tpl->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];"; - $output .= "\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value = $_attr[value]; \$_smarty_tpl->tpl_vars[$_attr[var]]->nocache = $_nocache; \$_smarty_tpl->tpl_vars[$_attr[var]]->scope = $_scope;"; - $output .= "\n} else \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache, $_scope);"; + $output .= "\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value = $_attr[value]; \$_smarty_tpl->tpl_vars[$_attr[var]]->nocache = $_nocache;"; + $output .= "\n} else \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache);"; } else { - $output = "tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache, $_scope);"; + $output = "tpl_vars[$_attr[var]] = new Smarty_Variable($_attr[value], $_nocache);"; } } - if ($_scope == Smarty::SCOPE_PARENT) { - $output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];"; - } elseif ($_scope == Smarty::SCOPE_ROOT || $_scope == Smarty::SCOPE_GLOBAL) { - $output .= "\n\$_ptr = \$_smarty_tpl->parent; while (\$_ptr != null) {\$_ptr->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]]; \$_ptr = \$_ptr->parent; }"; - } - if ($_scope == Smarty::SCOPE_GLOBAL) { - $output .= "\nSmarty::\$global_tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];"; - } + $output .= "\n\$_smarty_tpl->ext->_updateScope->updateScope(\$_smarty_tpl, $_attr[var], $_scope);"; $output .= '?>'; return $output; diff --git a/libs/sysplugins/smarty_internal_compile_include.php b/libs/sysplugins/smarty_internal_compile_include.php index c0713694..d3e46df1 100644 --- a/libs/sysplugins/smarty_internal_compile_include.php +++ b/libs/sysplugins/smarty_internal_compile_include.php @@ -43,7 +43,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase * @var array * @see Smarty_Internal_CompileBase */ - public $option_flags = array('nocache', 'inline', 'caching'); + public $option_flags = array('nocache', 'inline', 'caching', 'bubble_up'); /** * Attribute definition: Overwrites base class. @@ -113,10 +113,17 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $_parent_scope = Smarty::SCOPE_ROOT; } elseif ($_attr['scope'] == 'global') { $_parent_scope = Smarty::SCOPE_GLOBAL; + } elseif ($_attr['scope'] == 'smarty') { + $_parent_scope = Smarty::SCOPE_SMARTY; + } elseif ($_attr['scope'] == 'tpl_root') { + $_parent_scope = Smarty::SCOPE_TPL_ROOT; } } + if ($_attr['bubble_up'] === true) { + $_parent_scope = $_parent_scope + Smarty::SCOPE_BUBBLE_UP; + } - // + // set flag to cache subtemplate object when called within loop or template name is variable. if ($cache_tpl || $variable_template || $compiler->loopNesting > 0) { $_cache_tpl = 'true'; } else { @@ -215,7 +222,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase } } // delete {include} standard attributes - unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']); + unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline'], $_attr['bubble_up']); // remaining attributes must be assigned as smarty variable $_vars_nc = ''; if (!empty($_attr)) { @@ -248,9 +255,9 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase if (isset($_assign)) { $_output .= "ob_start();\n"; } - $_output .= "\$_smarty_tpl->smarty->ext->_inline->render(\$_smarty_tpl, {$fullResourceName}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['uid']}', '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func']}');\n"; + $_output .= "\$_smarty_tpl->smarty->ext->_subtemplate->render(\$_smarty_tpl, {$fullResourceName}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['uid']}', '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func']}');\n"; if (isset($_assign)) { - $_output .= "\$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(ob_get_clean());\n"; + $_output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean());\n"; } if ($update_compile_id) { $_output .= $compiler->makeNocacheCode("\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n"); @@ -273,7 +280,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase } $_output .= "\$_smarty_tpl->smarty->ext->_subtemplate->render(\$_smarty_tpl, {$fullResourceName}, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, {$_cache_tpl});\n"; if (isset($_assign)) { - $_output .= "\$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(ob_get_clean());\n"; + $_output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean());\n"; } if ($update_compile_id) { $_output .= "\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n"; diff --git a/libs/sysplugins/smarty_internal_data.php b/libs/sysplugins/smarty_internal_data.php index 20d0b56c..53f351b4 100644 --- a/libs/sysplugins/smarty_internal_data.php +++ b/libs/sysplugins/smarty_internal_data.php @@ -20,10 +20,17 @@ * @method Smarty_Internal_Data clearAllAssign() * @method Smarty_Internal_Data clearConfig(string $varName = null) * @method Smarty_Internal_Data configLoad(string $config_file, mixed $sections = null, string $scope = 'local') - * @property int $_objType + * @property int $scope */ class Smarty_Internal_Data { + /** + * This object type (Smarty = 1, template = 2, data = 4) + * + * @var int + */ + public $_objType = 4; + /** * name of class used for templates * @@ -34,7 +41,7 @@ class Smarty_Internal_Data /** * template variables * - * @var array + * @var Smarty_Variable[] */ public $tpl_vars = array(); @@ -48,7 +55,7 @@ class Smarty_Internal_Data /** * configuration settings * - * @var array + * @var string[] */ public $config_vars = array(); @@ -67,6 +74,7 @@ class Smarty_Internal_Data public function __construct() { $this->ext = new Smarty_Internal_Extension_Handler(); + $this->ext->objType = $this->_objType; } /** @@ -85,14 +93,19 @@ class Smarty_Internal_Data foreach ($tpl_var as $_key => $_val) { if ($_key != '') { $this->tpl_vars[$_key] = new Smarty_Variable($_val, $nocache); + if ($this->_objType == 2 && $this->scope) { + $this->ext->_updateScope->updateScope($this, $_key); + } } } } else { if ($tpl_var != '') { $this->tpl_vars[$tpl_var] = new Smarty_Variable($value, $nocache); + if ($this->_objType == 2 && $this->scope) { + $this->ext->_updateScope->updateScope($this, $tpl_var); + } } } - return $this; } @@ -127,7 +140,7 @@ class Smarty_Internal_Data public function assignGlobal($varName, $value = null, $nocache = false) { return $this->ext->assignGlobal->assignGlobal($this, $varName, $value, $nocache); - } + } /** * appends values to template variables by reference @@ -163,15 +176,15 @@ class Smarty_Internal_Data * @api Smarty::getTemplateVars() * @link http://www.smarty.net/docs/en/api.get.template.vars.tpl * - * @param string $varName variable name or null - * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $_ptr optional pointer to data object + * @param string $varName variable name or null + * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $_ptr optional pointer to data object * @param bool $searchParents include parent templates? * * @return mixed variable value or or array of variables */ public function getTemplateVars($varName = null, Smarty_Internal_Data $_ptr = null, $searchParents = true) { - return $this->ext->getTemplateVars->getTemplateVars($this, $varName, $_ptr, $searchParents); + return $this->ext->getTemplateVars->getTemplateVars($this, $varName, $_ptr, $searchParents); } /** @@ -179,7 +192,8 @@ class Smarty_Internal_Data * * @param \Smarty_Internal_Data|null $data */ - public function _mergeVars(Smarty_Internal_Data $data = null) { + public function _mergeVars(Smarty_Internal_Data $data = null) + { if (isset($data)) { if (!empty($this->tpl_vars)) { $data->tpl_vars = array_merge($this->tpl_vars, $data->tpl_vars); @@ -190,7 +204,7 @@ class Smarty_Internal_Data } else { $data = $this; } - if (isset($this->parent)) { + if (isset($this->parent)) { $this->parent->_mergeVars($data); } } diff --git a/libs/sysplugins/smarty_internal_extension_handler.php b/libs/sysplugins/smarty_internal_extension_handler.php index 14e359c9..e9f25dd9 100644 --- a/libs/sysplugins/smarty_internal_extension_handler.php +++ b/libs/sysplugins/smarty_internal_extension_handler.php @@ -10,36 +10,37 @@ * @subpackage PluginsInternal * @author Uwe Tews * - * @property Smarty_Internal_Runtime_Inheritance $_inheritance - * @property Smarty_Internal_Runtime_SubTemplate $_subTemplate - * @property Smarty_Internal_Runtime_Inline $_inline - * @property Smarty_Internal_Runtime_TplFunction $_tplFunction - * @property Smarty_Internal_Runtime_Var $_var - * @property Smarty_Internal_Runtime_Config $_config - * @property Smarty_Internal_Runtime_Foreach $_foreach - * @property Smarty_Internal_Runtime_Hhvm $_hhvm - * @property Smarty_Internal_Runtime_WriteFile $_writeFile + * @property Smarty_Internal_Runtime_Inheritance $_inheritance + * @property Smarty_Internal_Runtime_SubTemplate $_subTemplate + * @property Smarty_Internal_Runtime_TplFunction $_tplFunction + * @property Smarty_Internal_Runtime_Var $_var + * @property Smarty_Internal_Runtime_Config $_config + * @property Smarty_Internal_Runtime_Foreach $_foreach + * @property Smarty_Internal_Runtime_Hhvm $_hhvm + * @property Smarty_Internal_Runtime_WriteFile $_writeFile * @property Smarty_Internal_Runtime_ValidateCompiled $_validateCompiled - * @property Smarty_Internal_Runtime_CodeFrame $_codeFrame - * @property Smarty_Internal_Runtime_FilterHandler $_filterHandler - * @property Smarty_Internal_Runtime_GetIncludePath $_getIncludePath - * @property Smarty_Internal_Runtime_Source $_source - * @property Smarty_Internal_Runtime_IsCached $_isCached - * @property Smarty_Internal_Runtime_CacheModify $_cacheModify - * @property Smarty_Internal_Runtime_UpdateCache $_updateCache - * @property Smarty_Internal_Method_GetTemplateVars $getTemplateVars - * @property Smarty_Internal_Method_Append $append - * @property Smarty_Internal_Method_AppendByRef $appendByRef - * @property Smarty_Internal_Method_AssignGlobal $assignGlobal - * @property Smarty_Internal_Method_AssignByRef $assignByRef - * @property Smarty_Internal_Method_LoadFilter $loadFilter - * @property Smarty_Internal_Method_RegisterFilter $registerFilter - * @property Smarty_Internal_Method_RegisterObject $registerObject - * @property Smarty_Internal_Method_RegisterPlugin $registerPlugin + * @property Smarty_Internal_Runtime_CodeFrame $_codeFrame + * @property Smarty_Internal_Runtime_FilterHandler $_filterHandler + * @property Smarty_Internal_Runtime_GetIncludePath $_getIncludePath + * @property Smarty_Internal_Runtime_UpdateScope $_updateScope + * @property Smarty_Internal_Runtime_IsCached $_isCached + * @property Smarty_Internal_Runtime_CacheModify $_cacheModify + * @property Smarty_Internal_Runtime_UpdateCache $_updateCache + * @property Smarty_Internal_Method_GetTemplateVars $getTemplateVars + * @property Smarty_Internal_Method_Append $append + * @property Smarty_Internal_Method_AppendByRef $appendByRef + * @property Smarty_Internal_Method_AssignGlobal $assignGlobal + * @property Smarty_Internal_Method_AssignByRef $assignByRef + * @property Smarty_Internal_Method_LoadFilter $loadFilter + * @property Smarty_Internal_Method_RegisterFilter $registerFilter + * @property Smarty_Internal_Method_RegisterObject $registerObject + * @property Smarty_Internal_Method_RegisterPlugin $registerPlugin */ class Smarty_Internal_Extension_Handler { + public $objType = null; + /** * Cache for property information from generic getter/setter * Preloaded with names which should not use with generic getter/setter @@ -49,49 +50,50 @@ class Smarty_Internal_Extension_Handler private $_property_info = array('AutoloadFilters' => 0, 'DefaultModifiers' => 0, 'ConfigVars' => 0, 'DebugTemplate' => 0, 'RegisteredObject' => 0, 'StreamVariable' => 0, 'TemplateVars' => 0,);# - - private $resolvedProperties = array(); - + private $resolvedProperties = array(); /** * Call external Method - * + * * @param \Smarty_Internal_Data $data - * @param string $name external method names - * @param array $args argument array + * @param string $name external method names + * @param array $args argument array * * @return mixed * @throws SmartyException */ - public function _callExternalMethod(Smarty_Internal_Data $data, $name, $args) { - /* @var Smarty $data->smarty */ + public function _callExternalMethod(Smarty_Internal_Data $data, $name, $args) + { + /* @var Smarty $data ->smarty */ $smarty = isset($data->smarty) ? $data->smarty : $data; if (!isset($smarty->ext->$name)) { - $class = 'Smarty_Internal_Method_' . ucfirst($name); - if (preg_match('/^(set|get)([A-Z].*)$/', $name, $match)) { - if (!isset($this->_property_info[$prop = $match[2]])) { + $class = 'Smarty_Internal_Method_' . ucfirst($name); + if (preg_match('/^(set|get)([A-Z].*)$/', $name, $match)) { + if (!isset($this->_property_info[$prop = $match[2]])) { // convert camel case to underscored name - $this->resolvedProperties[$prop] = $pn = strtolower(join('_', preg_split('/([A-Z][^A-Z]*)/', $prop, - 1, PREG_SPLIT_NO_EMPTY | - PREG_SPLIT_DELIM_CAPTURE))); - $this->_property_info[$prop] = property_exists($data, $pn) ? 1 : ($data->_objType == 2 && - property_exists($smarty, $pn) ? 2 : 0); - } - if ($this->_property_info[$prop]) { - $pn = $this->resolvedProperties[$prop]; - if ($match[1] == 'get') { - return $this->_property_info[$prop] == 1 ? $data->$pn : $data->smarty->$pn; - } else { - return $this->_property_info[$prop] == - 1 ? $data->$pn = $args[0] : $data->smarty->$pn = $args[0]; + $this->resolvedProperties[$prop] = $pn = strtolower(join('_', + preg_split('/([A-Z][^A-Z]*)/', $prop, - 1, + PREG_SPLIT_NO_EMPTY | + PREG_SPLIT_DELIM_CAPTURE))); + $this->_property_info[$prop] = property_exists($data, $pn) ? 1 : + ($data->_objType == 2 && property_exists($smarty, $pn) ? 2 : 0); + } + if ($this->_property_info[$prop]) { + $pn = $this->resolvedProperties[$prop]; + if ($match[1] == 'get') { + return $this->_property_info[$prop] == 1 ? $data->$pn : $data->smarty->$pn; + } else { + return $this->_property_info[$prop] == 1 ? $data->$pn = $args[0] : + $data->smarty->$pn = $args[0]; + } + } elseif (!class_exists($class)) { + throw new SmartyException("property '$pn' does not exist."); } - } elseif (!class_exists($class)) { - throw new SmartyException("property '$pn' does not exist."); } - } - if (class_exists($class)) { - $callback = array($smarty->ext->$name = new $class(), $name); - } + if (class_exists($class)) { + $callback = array($smarty->ext->$name = new $class(), $name); + } } else { $callback = array($smarty->ext->$name, $name); } @@ -100,7 +102,7 @@ class Smarty_Internal_Extension_Handler return call_user_func_array($callback, $args); } return call_user_func_array(array(new Smarty_Internal_Undefined(), $name), $args); - } + } /** * set extension property @@ -112,7 +114,7 @@ class Smarty_Internal_Extension_Handler */ public function __set($property_name, $value) { - $this->$property_name = $value; + $this->$property_name = $value; } /** @@ -130,7 +132,6 @@ class Smarty_Internal_Extension_Handler $class = 'Smarty_Internal_Runtime_' . ucfirst(substr($property_name, 1)); } else { $class = 'Smarty_Internal_Method_' . ucfirst($property_name); - } if (class_exists($class)) { return $this->$property_name = new $class(); diff --git a/libs/sysplugins/smarty_internal_method_append.php b/libs/sysplugins/smarty_internal_method_append.php index 7bc320b1..43df8803 100644 --- a/libs/sysplugins/smarty_internal_method_append.php +++ b/libs/sysplugins/smarty_internal_method_append.php @@ -39,7 +39,7 @@ class Smarty_Internal_Method_Append // $tpl_var is an array, ignore $value foreach ($tpl_var as $_key => $_val) { if ($_key != '') { - self::append($data, $_key, $_val, $merge, $nocache); + $this->append($data, $_key, $_val, $merge, $nocache); } } } else { @@ -65,6 +65,9 @@ class Smarty_Internal_Method_Append $data->tpl_vars[$tpl_var]->value[] = $value; } } + if ($data->_objType == 2 && $data->scope) { + $data->ext->_updateScope->updateScope($data, $tpl_var); + } } return $data; } diff --git a/libs/sysplugins/smarty_internal_method_appendbyref.php b/libs/sysplugins/smarty_internal_method_appendbyref.php index d2ee9651..124bb803 100644 --- a/libs/sysplugins/smarty_internal_method_appendbyref.php +++ b/libs/sysplugins/smarty_internal_method_appendbyref.php @@ -41,6 +41,9 @@ class Smarty_Internal_Method_AppendByRef } else { $data->tpl_vars[$tpl_var]->value[] = &$value; } + if ($data->_objType == 2 && $data->scope) { + $data->ext->_updateScope->updateScope($data, $tpl_var); + } } return $data; } diff --git a/libs/sysplugins/smarty_internal_method_assignbyref.php b/libs/sysplugins/smarty_internal_method_assignbyref.php index cfa44939..a97125e3 100644 --- a/libs/sysplugins/smarty_internal_method_assignbyref.php +++ b/libs/sysplugins/smarty_internal_method_assignbyref.php @@ -16,9 +16,9 @@ class Smarty_Internal_Method_AssignByRef * assigns values to template variables by reference * * @param \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty $data - * @param string $tpl_var the template variable name - * @param $value - * @param boolean $nocache if true any output of this variable will be not cached + * @param string $tpl_var the template variable name + * @param $value + * @param boolean $nocache if true any output of this variable will be not cached * * @return \Smarty_Internal_Data|\Smarty_Internal_Template|\Smarty */ @@ -27,8 +27,10 @@ class Smarty_Internal_Method_AssignByRef if ($tpl_var != '') { $data->tpl_vars[$tpl_var] = new Smarty_Variable(null, $nocache); $data->tpl_vars[$tpl_var]->value = &$value; + if ($data->_objType == 2 && $data->scope) { + $data->ext->_updateScope->updateScope($data, $tpl_var); + } } - return $data; } } \ No newline at end of file diff --git a/libs/sysplugins/smarty_internal_runtime_inline.php b/libs/sysplugins/smarty_internal_runtime_inline.php deleted file mode 100644 index 730e88d3..00000000 --- a/libs/sysplugins/smarty_internal_runtime_inline.php +++ /dev/null @@ -1,85 +0,0 @@ -smarty->ext->_subTemplate->setupSubTemplate($parent, $template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, - $scope, $forceTplCache, $uid); - if ($parent->smarty->debugging) { - $parent->smarty->_debug->start_template($tpl); - $parent->smarty->_debug->start_render($tpl); - } - $tpl->compiled->getRenderedTemplateCode($tpl, $content_func); - if ($parent->smarty->debugging) { - $parent->smarty->_debug->end_template($tpl); - $parent->smarty->_debug->end_render($tpl); - } - if ($tpl->caching == 9999 && $tpl->compiled->has_nocache_code) { - $parent->cached->hashes[$tpl->compiled->nocache_hash] = true; - } - } - - /** - * Set source object of inline template by $uid - * - * @param \Smarty_Internal_Template $tpl - * @param string $uid - * - * @throws \SmartyException - */ - public function setSource(Smarty_Internal_Template $tpl, $uid = null) - { - // $uid is set if template is inline - if (isset($uid)) { - // inline templates have same compiled resource - $tpl->compiled = $tpl->parent->compiled; - if (isset($tpl->compiled->file_dependency[$uid])) { - list($filepath, $timestamp, $resource) = $tpl->compiled->file_dependency[$uid]; - $tpl->source = new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$resource]) ? - $tpl->smarty->_cache['resource_handlers'][$resource] : - Smarty_Resource::load($tpl->smarty, $resource), - $tpl->smarty, $filepath, $resource, $filepath); - $tpl->source->filepath = $filepath; - $tpl->source->timestamp = $timestamp; - $tpl->source->exists = true; - $tpl->source->uid = $uid; - } else { - $tpl->source = null; - } - } else { - $tpl->source = null; - unset($tpl->compiled); - } - if (!isset($tpl->source)) { - $tpl->source = Smarty_Template_Source::load($tpl); - } - } -} diff --git a/libs/sysplugins/smarty_internal_runtime_subtemplate.php b/libs/sysplugins/smarty_internal_runtime_subtemplate.php index 995d390b..252c89ab 100644 --- a/libs/sysplugins/smarty_internal_runtime_subtemplate.php +++ b/libs/sysplugins/smarty_internal_runtime_subtemplate.php @@ -11,8 +11,20 @@ class Smarty_Internal_Runtime_SubTemplate { + /** + * Subtemplate template object cache + * + * @var Smarty_Internal_Template[] + */ public $tplObjects = array(); + + /** + * Subtemplate call count + * + * @var int[] + */ public $subTplInfo = array(); + /** * Runtime function to render subtemplate * @@ -25,39 +37,20 @@ class Smarty_Internal_Runtime_SubTemplate * @param array $data passed parameter template variables * @param int $scope scope in which {include} should execute * @param bool $forceTplCache cache template object + * @param string $uid file dependency uid + * @param string $content_func function name * */ public function render(Smarty_Internal_Template $parent, $template, $cache_id, $compile_id, $caching, - $cache_lifetime, $data, $scope, $forceTplCache) - {$this->setupSubTemplate($parent, $template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, - $scope, $forceTplCache)->render(); - } - - /** - * Runtime function to get subtemplate object from cache or clone from parent - * - * @param \Smarty_Internal_Template $parent calling template - * @param string $template template name - * @param mixed $cache_id cache id - * @param mixed $compile_id compile id - * @param integer $caching cache mode - * @param integer $cache_lifetime life time of cache data - * @param array $data passed parameter template variables - * @param int $scope scope in which {include} should execute - * @param $forceTplCache - * @param string|null $uid source uid - * - * @return \Smarty_Internal_Template template object - */ - public function setupSubTemplate(Smarty_Internal_Template $parent, $template, $cache_id, $compile_id, $caching, - $cache_lifetime, $data, $scope, $forceTplCache, $uid = null) + $cache_lifetime, $data, $scope, $forceTplCache, $uid = null, $content_func = null) { // if there are cached template objects calculate $templateID - $_templateId = !empty($this->tplObjects) ? - $parent->smarty->_getTemplateId($template, $cache_id, $compile_id, $caching) : null; + $_templateId = + !empty($this->tplObjects) ? $parent->smarty->_getTemplateId($template, $cache_id, $compile_id, $caching) : + null; // already in template cache? /* @var Smarty_Internal_Template $tpl */ - if (isset($this->tplObjects[$_templateId])) { + if (isset($_templateId) && isset($this->tplObjects[$_templateId])) { // clone cached template object because of possible recursive call $tpl = clone $this->tplObjects[$_templateId]; $tpl->parent = $parent; @@ -66,10 +59,9 @@ class Smarty_Internal_Runtime_SubTemplate unset($tpl->compiled); } // get variables from calling scope - if ($scope == Smarty::SCOPE_LOCAL && $tpl->scope == Smarty::SCOPE_LOCAL) { $tpl->tpl_vars = $parent->tpl_vars; $tpl->config_vars = $parent->config_vars; - } + // get template functions $tpl->tpl_function = $parent->tpl_function; // copy inheritance object? if (isset($parent->ext->_inheritance)) { @@ -86,9 +78,27 @@ class Smarty_Internal_Runtime_SubTemplate $tpl->cache_id = $cache_id; $tpl->compile_id = $compile_id; if (isset($uid)) { - $tpl->ext->_inline->setSource($tpl, $uid); + // for inline templates we can get all resource information from file dependency + if (isset($tpl->compiled->file_dependency[$uid])) { + list($filepath, $timestamp, $resource) = $tpl->compiled->file_dependency[$uid]; + $tpl->source = + new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$resource]) ? + $tpl->smarty->_cache['resource_handlers'][$resource] : + Smarty_Resource::load($tpl->smarty, $resource), $tpl->smarty, + $filepath, $resource, $filepath); + $tpl->source->filepath = $filepath; + $tpl->source->timestamp = $timestamp; + $tpl->source->exists = true; + $tpl->source->uid = $uid; + } else { + $tpl->source = null; + } } else { - $this->setSource($tpl, $uid); + $tpl->source = null; + } + if (!isset($tpl->source)) { + $tpl->source = Smarty_Template_Source::load($tpl); + unset($tpl->compiled); } unset($tpl->cached); } @@ -98,37 +108,31 @@ class Smarty_Internal_Runtime_SubTemplate if ($caching == 9999) { $tpl->cached = $parent->cached; } - // get variables from calling scope - if ($scope != $tpl->scope) { - if ($tpl->scope != Smarty::SCOPE_LOCAL) { - //We must get rid of pointers - unset($tpl->tpl_vars, $tpl->config_vars); - $tpl->tpl_vars = array(); - $tpl->config_vars = array(); - } - if ($scope == Smarty::SCOPE_PARENT) { - $tpl->tpl_vars = &$parent->tpl_vars; - $tpl->config_vars = &$parent->config_vars; - } elseif ($scope == Smarty::SCOPE_GLOBAL) { - $tpl->tpl_vars = &Smarty::$global_tpl_vars; - $tpl->config_vars = $parent->config_vars; - } elseif ($scope == Smarty::SCOPE_ROOT) { - $ptr = $tpl->parent; - while (!empty($ptr->parent)) { - $ptr = $ptr->parent; - } - $tpl->tpl_vars = &$ptr->tpl_vars; - $tpl->config_vars = &$ptr->config_vars; + // set template scope + $tpl->scope = $scope; + $scopePtr = false; + if ($scope & ~Smarty::SCOPE_BUBBLE_UP) { + if ($scope == Smarty::SCOPE_GLOBAL) { + $tpl->tpl_vars = Smarty::$global_tpl_vars; + $scopePtr = true; + } elseif ($scope == Smarty::SCOPE_PARENT) { + $scopePtr = $parent; + } elseif ($scope == Smarty::SCOPE_SMARTY) { + $scopePtr = $tpl->smarty; } else { - $tpl->tpl_vars = $parent->tpl_vars; - $tpl->config_vars = $parent->config_vars; + $scopePtr = $tpl; + while (isset($scopePtr->parent)) { + if ($scopePtr->parent->_objType != 2 && $scope & Smarty::SCOPE_TPL_ROOT) { + break; + } + $scopePtr = $scopePtr->parent; + } } - $tpl->scope = $scope; + $tpl->tpl_vars = $scopePtr->tpl_vars; + $tpl->config_vars = $scopePtr->config_vars; } - if (!isset($this->tplObjects[$tpl->_getTemplateId()]) && - !$tpl->source->handler->recompiled - ) { + if (!isset($this->tplObjects[$tpl->_getTemplateId()]) && !$tpl->source->handler->recompiled) { // if template is called multiple times set flag to to cache template objects $forceTplCache = $forceTplCache || (isset($this->subTplInfo[$tpl->template_resource]) && $this->subTplInfo[$tpl->template_resource] > 1); @@ -147,40 +151,49 @@ class Smarty_Internal_Runtime_SubTemplate $tpl->tpl_vars[$_key] = new Smarty_Variable($_val); } } - return $tpl; - } - - /** - * Set source object of inline template by $uid - * - * @param \Smarty_Internal_Template $tpl - * @param string $uid - * - * @throws \SmartyException - */ - public function setSource(Smarty_Internal_Template $tpl, $uid = null) - { - //load source - $tpl->source = null; - unset($tpl->compiled); - if (!isset($tpl->source)) { - $tpl->source = Smarty_Template_Source::load($tpl); + if (isset($uid)) { + if ($parent->smarty->debugging) { + $parent->smarty->_debug->start_template($tpl); + $parent->smarty->_debug->start_render($tpl); + } + $tpl->compiled->getRenderedTemplateCode($tpl, $content_func); + if ($parent->smarty->debugging) { + $parent->smarty->_debug->end_template($tpl); + $parent->smarty->_debug->end_render($tpl); + } + if ($tpl->caching == 9999 && $tpl->compiled->has_nocache_code) { + $parent->cached->hashes[$tpl->compiled->nocache_hash] = true; + } + } else { + if (isset($tpl->compiled)) { + $tpl->compiled->render($tpl); + } else { + $tpl->render(); + } + } + if ($scopePtr) { + if ($scope == Smarty::SCOPE_GLOBAL) { + Smarty::$global_tpl_vars = $tpl->tpl_vars; + } else { + $scopePtr->tpl_vars = $tpl->tpl_vars; + $scopePtr->config_vars = $tpl->config_vars; + } } } /** - * Get called subtemplates and its call count from compiled template + * Get called subtemplates from compiled template and save call count * * @param \Smarty_Internal_Template $tpl */ public function registerSubTemplates(Smarty_Internal_Template $tpl) { - foreach ($tpl->compiled->includes as $name => $count) { - if (isset($this->subTplInfo[$name])) { - $this->subTplInfo[$name] += $count; - } else { - $this->subTplInfo[$name] = $count; + foreach ($tpl->compiled->includes as $name => $count) { + if (isset($this->subTplInfo[$name])) { + $this->subTplInfo[$name] += $count; + } else { + $this->subTplInfo[$name] = $count; + } } - } -} + } } diff --git a/libs/sysplugins/smarty_internal_runtime_var.php b/libs/sysplugins/smarty_internal_runtime_var.php index a8f6818f..fe4f94d9 100644 --- a/libs/sysplugins/smarty_internal_runtime_var.php +++ b/libs/sysplugins/smarty_internal_runtime_var.php @@ -16,18 +16,13 @@ class Smarty_Internal_Runtime_Var * @param \Smarty_Internal_Template $tpl template object * @param string $varName template variable name * @param bool $nocache cache mode of variable - * @param int $scope scope of variable */ - public function createLocalArrayVariable(\Smarty_Internal_Template $tpl, $varName, $nocache = false, - $scope = Smarty::SCOPE_LOCAL) + public function createLocalArrayVariable(\Smarty_Internal_Template $tpl, $varName, $nocache = false) { if (!isset($tpl->tpl_vars[$varName])) { - $tpl->tpl_vars[$varName] = new Smarty_Variable(array(), $nocache, $scope); + $tpl->tpl_vars[$varName] = new Smarty_Variable(array(), $nocache); } else { $tpl->tpl_vars[$varName] = clone $tpl->tpl_vars[$varName]; - if ($scope != Smarty::SCOPE_LOCAL) { - $tpl->tpl_vars[$varName]->scope = $scope; - } if (!(is_array($tpl->tpl_vars[$varName]->value) || $tpl->tpl_vars[$varName]->value instanceof ArrayAccess) ) { diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index 9e1a0c68..52c7391b 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -166,7 +166,8 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase // display or fetch if ($display) { if ($this->caching && $this->smarty->cache_modified_check) { - $this->smarty->ext->_cachemodify->cacheModifiedCheck($this->cached, $this, isset($content) ? $content : ob_get_clean()); + $this->smarty->ext->_cachemodify->cacheModifiedCheck($this->cached, $this, + isset($content) ? $content : ob_get_clean()); } else { if ((!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || @@ -324,8 +325,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase case 'compiled': case 'cached': case 'compiler': - case 'tpl_vars': - case 'config_vars': $this->$property_name = $value; return; default: diff --git a/libs/sysplugins/smarty_internal_templatebase.php b/libs/sysplugins/smarty_internal_templatebase.php index 1ecba224..9b4953de 100644 --- a/libs/sysplugins/smarty_internal_templatebase.php +++ b/libs/sysplugins/smarty_internal_templatebase.php @@ -14,12 +14,12 @@ * @package Smarty * @subpackage Template * + * @property Smarty $smarty * @method Smarty_Internal_TemplateBase setAutoloadFilters(mixed $filters, string $type = null) * @method Smarty_Internal_TemplateBase addAutoloadFilters(mixed $filters, string $type = null) * @method array getAutoloadFilters(string $type = null) * @local_method Smarty_Internal_TemplateBase registerFilter(string $type, callback $callback, string $name = null) * @method Smarty_Internal_TemplateBase unregisterFilter(string $type, mixed $callback) - * @local_method bool loadFilter(string $type, string $name) * @method Smarty_Internal_TemplateBase unloadFilter(string $type, string $name) * @method string getDebugTemplate() * @method Smarty_Internal_TemplateBase setDebugTemplate(string $tpl_name) @@ -31,11 +31,7 @@ * @method Smarty_Internal_TemplateBase unregisterResource(string $name) * @method Smarty_Internal_TemplateBase registerCacheResource(string $name, Smarty_CacheResource $resource_handler) * @method Smarty_Internal_TemplateBase unregisterCacheResource(string $name) - * @local_method Smarty_Internal_TemplateBase registerPlugin(string $type, string $name, callback $callback, bool - * $cacheable = true, mixed $cache_attr = null) * @method Smarty_Internal_TemplateBase unregisterPlugin(string $type, string $name) - * @local_method Smarty_Internal_TemplateBase registerObject(string $object_name, object $object, array - * $allowed_methods_properties = array(), bool $format = true, array $block_methods = array()) * @method Smarty_Internal_TemplateBase unregisterObject(string $object_name) * @method object getRegisteredObject(string $object_name) * @method Smarty_Internal_TemplateBase registerClass(string $class_name, string $class_impl) @@ -146,17 +142,19 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data */ private function _execute($template, $cache_id, $compile_id, $parent, $function) { - /* @var Smarty $this ->smarty */ $smarty = $this->_objType == 1 ? $this : $this->smarty; if ($template === null) { if ($this->_objType != 2) { throw new SmartyException($function . '():Missing \'$template\' parameter'); } else { - $template = $this; + $template = clone $this; } } elseif (is_object($template)) { if (!isset($template->_objType) || $template->_objType != 2) { throw new SmartyException($function . '():Template object expected'); + } else { + /* @var Smarty_Internal_Template $template */ + $template = clone $template; } } else { // get template object @@ -186,16 +184,11 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data } } else { ob_start(); - $save_tpl_vars = $template->tpl_vars; - $save_config_vars = $template->config_vars; $template->_mergeVars(); if (!empty(Smarty::$global_tpl_vars)) { $template->tpl_vars = array_merge(Smarty::$global_tpl_vars, $template->tpl_vars); } $result = $template->render(false, $function); - // restore local variables - $template->tpl_vars = $save_tpl_vars; - $template->config_vars = $save_config_vars; } if (isset($_smarty_old_error_level)) { error_reporting($_smarty_old_error_level); diff --git a/libs/sysplugins/smarty_internal_testinstall.php b/libs/sysplugins/smarty_internal_testinstall.php index dbd269f0..b23f5592 100644 --- a/libs/sysplugins/smarty_internal_testinstall.php +++ b/libs/sysplugins/smarty_internal_testinstall.php @@ -477,11 +477,11 @@ class Smarty_Internal_TestInstall 'smarty_internal_runtime_getincludepath.php' => true, 'smarty_internal_runtime_hhvm.php' => true, 'smarty_internal_runtime_inheritance.php' => true, - 'smarty_internal_runtime_inline.php' => true, 'smarty_internal_runtime_iscached.php' => true, 'smarty_internal_runtime_subtemplate.php' => true, 'smarty_internal_runtime_tplfunction.php' => true, 'smarty_internal_runtime_updatecache.php' => true, + 'smarty_internal_runtime_updatescope.php' => true, 'smarty_internal_runtime_validatecompiled.php' => true, 'smarty_internal_runtime_var.php' => true, 'smarty_internal_runtime_writefile.php' => true, diff --git a/libs/sysplugins/smarty_variable.php b/libs/sysplugins/smarty_variable.php index c1de93cb..a6504b18 100644 --- a/libs/sysplugins/smarty_variable.php +++ b/libs/sysplugins/smarty_variable.php @@ -21,25 +21,17 @@ class Smarty_Variable * @var boolean */ public $nocache = false; - /** - * the scope the variable will have (local,parent or root) - * - * @var int - */ - public $scope = Smarty::SCOPE_LOCAL; /** * create Smarty variable object * * @param mixed $value the value to assign * @param boolean $nocache if true any output of this variable will be not cached - * @param int $scope the scope the variable will have (local,parent or root) */ - public function __construct($value = null, $nocache = false, $scope = Smarty::SCOPE_LOCAL) + public function __construct($value = null, $nocache = false) { $this->value = $value; $this->nocache = $nocache; - $this->scope = $scope; } /**