- update/bugfix scope attribute handling reworked. Read the newfeatures.txt file

This commit is contained in:
uwetews
2016-02-09 23:27:07 +01:00
parent 37e6d26b23
commit 2f62b99173
20 changed files with 371 additions and 401 deletions

View File

@@ -4,6 +4,58 @@ This file contains a brief description of new features which have been added to
Smarty 3.1.30
Scope Attributes
================
The scope handling has been updated to cover all cases of variable assignments in templates.
A new option flag 'bubble_up' is introduced.
The tags {assign}, {append} direct assignments like {$foo = ...}, {$foo[...]= ...} support
the following optional scope attributes:
scope=parent - the variable will be assigned in the current template and if the template
was included by {include} the calling template
scope=tpl_root - the variable will be assigned in the current template and if the template
was included by {include} the outermost root template
scope=smarty - the variable will be assigned in the current template and the Smarty object
scope=global - the variable will be assigned in the current template and as Smarty object
global variable
scope=root - the variable will be assigned in the current template and if a data object was
used for variable definitions in the data object or in the Smarty object otherwise
scope=local - this scope has only a meaning if the tag is called within a template {function}.
The variable will be assigned in the local scope of the template function and the
template which did call the template function.
The scope attribute can be combined with the new option flag 'bubble_up' like
{$foo = 'bar' scope=global bubble_up}
In addition to the assignments according to the scope attributes tpl_root, smarty, global, root the varibale
will also be assigned in all templates in the call chain from template root to the current template,
including all local template function scopes of nested template function calls.
In combination with scope local it does update the nested template function scopes.
Example:
$smarty->display('main.tpl');
main.tpl:
{include 'sub.tpl'}
sub.tpl:
{$foo = 'bar' scope=global bubble_up}
Will assign the variable 'foo' with value 'bar' as Smarty global variable, in 'sub.tpl' and in
'main.tpl' because the 'bubble_up' option.
The {config_load} tag supports all of the above except the global scope.
The scope attribute and bubble_up option flag can be used also with the {include} tag.
Supported scope are parent, tpl_root, smarty, global and root.
A scope used together with the {include} tag will cause that with some exceptions any variable
assignment within that sub-template will update/assign the variable in other scopes according
to the above rules. It does include also variables assigned by plugins, tags supporting the assign=foo
attribute and direct assignments in {if} and {while} like {if $foo=$bar}.
Excluded are the key and value variables of {foreach}, {for} loop variables , variables passed by attributes
in {include} and direct increments/decrements like {$foo++}, {$foo--}
Caching
=======
Caching does now observe the template_dir setting and will create separate cache files if required

View File

@@ -2,6 +2,7 @@
09.02.2016
- move some code from parser into compiler
- reformat all code for unique style
- update/bugfix scope attribute handling reworked. Read the newfeatures.txt file
05.02.2016
- improvement internal compiler changes

View File

@@ -121,12 +121,12 @@ class Smarty extends Smarty_Internal_TemplateBase
/**
* smarty version
*/
const SMARTY_VERSION = '3.1.30-dev/30';
const SMARTY_VERSION = '3.1.30-dev/31';
/**
* define variable scopes
*/
const SCOPE_LOCAL = 0;
const SCOPE_LOCAL = 1;
const SCOPE_PARENT = 2;
@@ -134,6 +134,8 @@ class Smarty extends Smarty_Internal_TemplateBase
const SCOPE_ROOT = 8;
const SCOPE_SMARTY = 16;
const SCOPE_GLOBAL = 32;
const SCOPE_BUBBLE_UP = 64;

View File

@@ -16,13 +16,22 @@
*/
class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase
{
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $option_flags = array('nocache', 'bubble_up');
/**
* Valid scope names
*
* @var array
*/
public $valid_scopes = array('local' => true, 'parent' => true, 'root' => true, 'global' => true,
'tpl_root' => true);
public $valid_scopes = array('local' => Smarty::SCOPE_LOCAL, 'parent' => Smarty::SCOPE_PARENT,
'root' => Smarty::SCOPE_ROOT, 'global' => Smarty::SCOPE_GLOBAL,
'tpl_root' => Smarty::SCOPE_TPL_ROOT, 'smarty' => Smarty::SCOPE_SMARTY);
/**
* Compiles code for the {assign} tag
@@ -39,60 +48,41 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase
// the following must be assigned at runtime because it will be overwritten in Smarty_Internal_Compile_Append
$this->required_attributes = array('var', 'value');
$this->shorttag_order = array('var', 'value');
$this->optional_attributes = array('scope', 'bubble_up');
$_nocache = 'null';
$this->optional_attributes = array('scope');
$_nocache = false;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
// nocache ?
if ($_var = $compiler->getId($_attr[ 'var' ])) {
$_var = "'{$_var}'";
} else {
$_var = $_attr[ 'var' ];
}
if ($compiler->tag_nocache || $compiler->nocache) {
$_nocache = 'true';
$_nocache = true;
// create nocache var to make it know for further compiling
if (isset($compiler->template->tpl_vars[ trim($_attr[ 'var' ], "'") ])) {
$compiler->template->tpl_vars[ trim($_attr[ 'var' ], "'") ]->nocache = true;
} else {
$compiler->template->tpl_vars[ trim($_attr[ 'var' ], "'") ] = new Smarty_Variable(null, true);
}
$compiler->setNocacheInVariable($_attr[ 'var' ]);
}
// scope setup
$_scope = Smarty::SCOPE_LOCAL;
if (isset($_attr[ 'scope' ])) {
$_attr[ 'scope' ] = trim($_attr[ 'scope' ], "'\"");
if (!isset($this->valid_scopes[ $_attr[ 'scope' ] ])) {
$compiler->trigger_template_error("illegal value '{$_attr['scope']}' for \"scope\" attribute", null,
true);
}
if ($_attr[ 'scope' ] != 'local') {
if ($_attr[ 'scope' ] == 'parent') {
$_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr[ 'scope' ] == 'root') {
$_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr[ 'scope' ] == 'global') {
$_scope = Smarty::SCOPE_GLOBAL;
} elseif ($_attr[ 'scope' ] == 'tpl_root') {
$_scope = Smarty::SCOPE_TPL_ROOT;
}
$_scope += (isset($_attr[ 'bubble_up' ]) && $_attr[ 'bubble_up' ] == 'false') ? 0 :
Smarty::SCOPE_BUBBLE_UP;
}
$_scope = $compiler->convertScope($_attr, $this->valid_scopes);
// optional parameter
$_params = "";
if ($_nocache || $_scope) {
$_params .= ' ,' . var_export($_nocache, true);
}
if ($_scope) {
$_params .= ' ,' . $_scope;
}
if (isset($parameter[ 'smarty_internal_index' ])) {
$output = "<?php \$_smarty_tpl->_createLocalArrayVariable({$_attr['var']}, {$_nocache});\n";
$output .= "\$_smarty_tpl->tpl_vars[{$_attr['var']}]->value{$parameter['smarty_internal_index']} = {$_attr['value']};\n";
if ($_scope != Smarty::SCOPE_LOCAL) {
$output .= "\$_smarty_tpl->ext->_updateScope->updateScope(\$_smarty_tpl, {$_attr['var']}, {$_scope});\n";
} else {
$output .= "if (\$_smarty_tpl->scope & Smarty::SCOPE_BUBBLE_UP) {\n";
$output .= "\$_smarty_tpl->ext->_updateScope->updateScope(\$_smarty_tpl, {$_attr['var']});\n}\n";
}
$output .= '?>';
} else {
if ($compiler->template->smarty instanceof SmartyBC) {
$_smartyBC = 'true';
} else {
$_smartyBC = 'false';
}
$output =
"<?php \$_smarty_tpl->_assignInScope({$_attr['var']}, {$_attr['value']}, {$_nocache}, {$_scope}, {$_smartyBC});\n?>";
"<?php \$_tmp_array = isset(\$_smarty_tpl->tpl_vars[{$_var}]) ? \$_smarty_tpl->tpl_vars[{$_var}]->value : array();\n";
$output .= "if (!is_array(\$_tmp_array) || \$_tmp_array instanceof ArrayAccess) {\n";
$output .= "settype(\$_tmp_array, 'array');\n";
$output .= "}\n";
$output .= "\$_tmp_array{$parameter['smarty_internal_index']} = {$_attr['value']};\n";
$output .= "\$_smarty_tpl->_assignInScope({$_var}, \$_tmp_array{$_params});\n?>";
} else {
$output = "<?php \$_smarty_tpl->_assignInScope({$_var}, {$_attr['value']}{$_params});\n?>";
}
return $output;
}

View File

@@ -212,7 +212,7 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php\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";
}
//$output .= "/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
$output .= "\$_smarty_tpl->ext->_inheritance->blockNesting--;\n";

View File

@@ -38,14 +38,24 @@ class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('section', 'scope', 'bubble_up');
public $optional_attributes = array('section', 'scope');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $option_flags = array('nocache', 'bubble_up');
/**
* Valid scope names
*
* @var array
*/
public $valid_scopes = array('local' => true, 'parent' => true, 'root' => true, 'tpl_root' => true);
public $valid_scopes = array('local' => Smarty::SCOPE_LOCAL, 'parent' => Smarty::SCOPE_PARENT,
'root' => Smarty::SCOPE_ROOT, 'tpl_root' => Smarty::SCOPE_TPL_ROOT,
'smarty' => Smarty::SCOPE_SMARTY);
/**
* Compiles code for the {config_load} tag
@@ -72,25 +82,8 @@ class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase
} else {
$section = 'null';
}
$_scope = Smarty::SCOPE_LOCAL;
if (isset($_attr[ 'scope' ])) {
$_attr[ 'scope' ] = trim($_attr[ 'scope' ], "'\"");
if (!isset($this->valid_scopes[ $_attr[ 'scope' ] ])) {
$compiler->trigger_template_error("illegal value '{$_attr['scope']}' for \"scope\" attribute", null,
true);
}
if ($_attr[ 'scope' ] != 'local') {
if ($_attr[ 'scope' ] == 'parent') {
$_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr[ 'scope' ] == 'root') {
$_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr[ 'scope' ] == 'tpl_root') {
$_scope = Smarty::SCOPE_TPL_ROOT;
}
$_scope += (isset($_attr[ 'bubble_up' ]) && $_attr[ 'bubble_up' ] == 'false') ? 0 :
Smarty::SCOPE_BUBBLE_UP;
}
}
// scope setup
$_scope = $compiler->convertScope($_attr, $this->valid_scopes);
// create config object
$_output =

View File

@@ -148,23 +148,20 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
$output .= "ob_start();\n";
$output .= "\$_smarty_tpl->compiled->has_nocache_code = true;\n";
$output .= $_paramsCode;
$output .= "\$_smarty_tpl->_cache['saved_tpl_vars'][] = \$_smarty_tpl->tpl_vars;\n";
$output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value);\n}";
$output .= "\$params = var_export(\$params, true);\n";
$output .= "echo \"/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/<?php ";
$output .= "\\\$saved_tpl_vars = \\\$_smarty_tpl->tpl_vars;\nforeach (\$params as \\\$key => \\\$value) {\n\\\$_smarty_tpl->tpl_vars[\\\$key] = new Smarty_Variable(\\\$value);\n}\n?>";
$output .= "\\\$_smarty_tpl->smarty->ext->_tplFunction->saveTemplateVariables(\\\$_smarty_tpl, '{$_name}');\nforeach (\$params as \\\$key => \\\$value) {\n\\\$_smarty_tpl->tpl_vars[\\\$key] = new Smarty_Variable(\\\$value);\n}\n?>";
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n\";?>";
$compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php echo \"/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/<?php ";
$output .= "foreach (Smarty::\\\$global_tpl_vars as \\\$key => \\\$value){\n";
$output .= "if (!isset(\\\$_smarty_tpl->tpl_vars[\\\$key]) || \\\$_smarty_tpl->tpl_vars[\\\$key] === \\\$value) \\\$saved_tpl_vars[\\\$key] = \\\$value;\n}\n";
$output .= "\\\$_smarty_tpl->tpl_vars = \\\$saved_tpl_vars;?>\n";
$output .= "\\\$_smarty_tpl->smarty->ext->_tplFunction->restoreTemplateVariables(\\\$_smarty_tpl, '{$_name}');?>\n";
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\";\n?>";
$output .= "<?php echo str_replace('{$compiler->template->compiled->nocache_hash}', \$_smarty_tpl->compiled->nocache_hash, ob_get_clean());\n";
$output .= "\$_smarty_tpl->tpl_vars = array_pop(\$_smarty_tpl->_cache['saved_tpl_vars']);\n}\n}\n";
$output .= "}\n}\n";
$output .= "/*/ {$_funcName}_nocache */\n\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser,
@@ -181,16 +178,13 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
$output .= "/* {$_funcName} */\n";
$output .= "if (!function_exists('{$_funcName}')) {\n";
$output .= "function {$_funcName}(\$_smarty_tpl,\$params) {\n";
$output .= "\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;\n";
$output .= $_paramsCode;
$output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value);\n}?>";
$compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php foreach (Smarty::\$global_tpl_vars as \$key => \$value){\n";
$output .= "if (!isset(\$_smarty_tpl->tpl_vars[\$key]) || \$_smarty_tpl->tpl_vars[\$key] === \$value) \$saved_tpl_vars[\$key] = \$value;\n}\n";
$output .= "\$_smarty_tpl->tpl_vars = \$saved_tpl_vars;\n}\n}\n";
$output = "<?php\n}}\n";
$output .= "/*/ {$_funcName} */\n\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser,

View File

@@ -40,38 +40,26 @@ class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase
if (is_array($parameter[ 'if condition' ])) {
if ($compiler->nocache) {
$_nocache = ',true';
// create nocache var to make it know for further compiling
if (is_array($parameter[ 'if condition' ][ 'var' ])) {
$var = trim($parameter[ 'if condition' ][ 'var' ][ 'var' ], "'");
$var = $parameter[ 'if condition' ][ 'var' ][ 'var' ];
} else {
$var = trim($parameter[ 'if condition' ][ 'var' ], "'");
$var = $parameter[ 'if condition' ][ 'var' ];
}
if (isset($compiler->template->tpl_vars[ $var ])) {
$compiler->template->tpl_vars[ $var ]->nocache = true;
} else {
$compiler->template->tpl_vars[ $var ] = new Smarty_Variable(null, true);
}
} else {
$_nocache = '';
$compiler->setNocacheInVariable($var);
}
$assignCompiler = new Smarty_Internal_Compile_Assign();
$assignAttr = array();
$assignAttr[][ 'value' ] = $parameter[ 'if condition' ][ 'value' ];
if (is_array($parameter[ 'if condition' ][ 'var' ])) {
$_output =
"<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]->value)) \$_smarty_tpl->_createLocalArrayVariable(" .
$parameter[ 'if condition' ][ 'var' ][ 'var' ] . "$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]->value" . $parameter[ 'if condition' ][ 'var' ][ 'smarty_internal_index' ] . " = " .
$parameter[ 'if condition' ][ 'value' ] . ") {?>";
$assignAttr[][ 'var' ] = $parameter[ 'if condition' ][ 'var' ][ 'var' ];
$_output = $assignCompiler->compile($assignAttr, $compiler,
array('smarty_internal_index' => $parameter[ 'if condition' ][ 'var' ][ 'smarty_internal_index' ]));
} else {
$_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] .
"])) \$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] .
"] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] . "]->value = " .
$parameter[ 'if condition' ][ 'value' ] . ") {?>";
$assignAttr[][ 'var' ] = $parameter[ 'if condition' ][ 'var' ];
$_output = $assignCompiler->compile($assignAttr, $compiler, array());
}
$_output .= "<?php if (" . $parameter[ 'if condition' ][ 'value' ] . ") {?>";
return $_output;
} else {
return "<?php if ({$parameter['if condition']}) {?>";
@@ -134,89 +122,53 @@ class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase
$compiler->trigger_template_error("missing elseif condition", null, true);
}
$assignCode = '';
if (is_array($parameter[ 'if condition' ])) {
$condition_by_assign = true;
if ($compiler->nocache) {
$_nocache = ',true';
// create nocache var to make it know for further compiling
if (is_array($parameter[ 'if condition' ][ 'var' ])) {
$var = trim($parameter[ 'if condition' ][ 'var' ][ 'var' ], "'");
$var = $parameter[ 'if condition' ][ 'var' ][ 'var' ];
} else {
$var = trim($parameter[ 'if condition' ][ 'var' ], "'");
}
if (isset($compiler->template->tpl_vars[ $var ])) {
$compiler->template->tpl_vars[ $var ]->nocache = true;
} else {
$compiler->template->tpl_vars[ $var ] = new Smarty_Variable(null, true);
$var = $parameter[ 'if condition' ][ 'var' ];
}
$compiler->setNocacheInVariable($var);
}
$assignCompiler = new Smarty_Internal_Compile_Assign();
$assignAttr = array();
$assignAttr[][ 'value' ] = $parameter[ 'if condition' ][ 'value' ];
if (is_array($parameter[ 'if condition' ][ 'var' ])) {
$assignAttr[][ 'var' ] = $parameter[ 'if condition' ][ 'var' ][ 'var' ];
$assignCode = $assignCompiler->compile($assignAttr, $compiler,
array('smarty_internal_index' => $parameter[ 'if condition' ][ 'var' ][ 'smarty_internal_index' ]));
} else {
$_nocache = '';
$assignAttr[][ 'var' ] = $parameter[ 'if condition' ][ 'var' ];
$assignCode = $assignCompiler->compile($assignAttr, $compiler, array());
}
} else {
$condition_by_assign = false;
}
if (empty($compiler->prefix_code)) {
$prefixCode = $compiler->getPrefixCode();
if (empty($prefixCode)) {
if ($condition_by_assign) {
$this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
if (is_array($parameter[ 'if condition' ][ 'var' ])) {
$_output = "<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" .
$parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]) || !is_array(\$_smarty_tpl->tpl_vars[" .
$parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]->value)) \$_smarty_tpl->_createLocalArrayVariable(" .
$parameter[ 'if condition' ][ 'var' ][ 'var' ] . "$_nocache);\n";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]->value" . $parameter[ 'if condition' ][ 'var' ][ 'smarty_internal_index' ] . " = " .
$parameter[ 'if condition' ][ 'value' ] . ") {?>";
} else {
$_output =
"<?php } else { if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] .
"])) \$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] .
"] = new Smarty_Variable(null{$_nocache});";
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] . "]->value = " .
$parameter[ 'if condition' ][ 'value' ] . ") {?>";
}
return $_output;
$_output = $compiler->appendCode("<?php } else {\n?>", $assignCode);
return $compiler->appendCode($_output,
"<?php if (" . $parameter[ 'if condition' ][ 'value' ] . ") {\n?>");
} else {
$this->openTag($compiler, 'elseif', array($nesting, $compiler->tag_nocache));
return "<?php } elseif ({$parameter['if condition']}) {?>";
}
} else {
$tmp = '';
foreach ($compiler->prefix_code as $code) {
$tmp = $compiler->appendCode($tmp, $code);
}
$compiler->prefix_code = array();
$tmp = $compiler->appendCode("<?php } else {?>", $tmp);
$_output = $compiler->appendCode("<?php } else {\n?>", $prefixCode);
$this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache));
if ($condition_by_assign) {
if (is_array($parameter[ 'if condition' ][ 'var' ])) {
$_output = $compiler->appendCode($tmp, "<?php if (!isset(\$_smarty_tpl->tpl_vars[" .
$parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]) || !is_array(\$_smarty_tpl->tpl_vars[" .
$parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]->value)) \$_smarty_tpl->_createLocalArrayVariable(" .
$parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"$_nocache);\n");
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]->value" . $parameter[ 'if condition' ][ 'var' ][ 'smarty_internal_index' ] . " = " .
$parameter[ 'if condition' ][ 'value' ] . ") {?>";
} else {
$_output = $compiler->appendCode($tmp, "<?php if (!isset(\$_smarty_tpl->tpl_vars[" .
$parameter[ 'if condition' ][ 'var' ] .
"])) \$_smarty_tpl->tpl_vars[" .
$parameter[ 'if condition' ][ 'var' ] .
"] = new Smarty_Variable(null{$_nocache});");
$_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] . "]->value = " .
$parameter[ 'if condition' ][ 'value' ] . ") {?>";
}
return $_output;
$_output = $compiler->appendCode($_output, $assignCode);
return $compiler->appendCode($_output,
"<?php if (" . $parameter[ 'if condition' ][ 'value' ] . ") {\n?>");
} else {
return $compiler->appendCode($tmp, "<?php if ({$parameter['if condition']}) {?>");
return $compiler->appendCode($_output, "<?php if ({$parameter['if condition']}) {?>");
}
}
}

View File

@@ -58,7 +58,9 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
*
* @var array
*/
public $valid_scopes = array('local' => true, 'parent' => true, 'root' => true, 'tpl_root' => true);
public $valid_scopes = array('parent' => Smarty::SCOPE_PARENT, 'root' => Smarty::SCOPE_ROOT,
'global' => Smarty::SCOPE_GLOBAL, 'tpl_root' => Smarty::SCOPE_TPL_ROOT,
'smarty' => Smarty::SCOPE_SMARTY);
/**
* Compiles code for the {include} tag
@@ -106,31 +108,8 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
$variable_template = true;
}
if (isset($_attr[ 'assign' ])) {
// output will be stored in a smarty variable instead of being displayed
$_assign = $_attr[ 'assign' ];
}
// scope setup
$_scope = Smarty::SCOPE_LOCAL;
if (isset($_attr[ 'scope' ])) {
$_attr[ 'scope' ] = trim($_attr[ 'scope' ], "'\"");
if (!isset($this->valid_scopes[ $_attr[ 'scope' ] ])) {
$compiler->trigger_template_error("illegal value '{$_attr['scope']}' for \"scope\" attribute", null,
true);
}
if ($_attr[ 'scope' ] != 'local') {
if ($_attr[ 'scope' ] == 'parent') {
$_scope = Smarty::SCOPE_PARENT;
} elseif ($_attr[ 'scope' ] == 'root') {
$_scope = Smarty::SCOPE_ROOT;
} elseif ($_attr[ 'scope' ] == 'tpl_root') {
$_scope = Smarty::SCOPE_TPL_ROOT;
}
$_scope += (isset($_attr[ 'bubble_up' ]) && $_attr[ 'bubble_up' ] == 'false') ? 0 :
Smarty::SCOPE_BUBBLE_UP;
}
}
$_scope = $compiler->convertScope($_attr, $this->valid_scopes);
// set flag to cache subtemplate object when called within loop or template name is variable.
if ($cache_tpl || $variable_template || $compiler->loopNesting > 0) {
@@ -156,28 +135,14 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
$merge_compiled_includes = ($compiler->smarty->merge_compiled_includes || $_attr[ 'inline' ] === true) &&
!$compiler->template->source->handler->recompiled;
if ($merge_compiled_includes && $_attr[ 'inline' ] !== true) {
if ($merge_compiled_includes) {
// variable template name ?
if ($variable_template) {
$merge_compiled_includes = false;
if ($compiler->template->caching) {
// must use individual cache file
//$_attr['caching'] = 1;
}
}
// variable compile_id?
if (isset($_attr[ 'compile_id' ])) {
if (!((substr_count($_attr[ 'compile_id' ], '"') == 2 ||
substr_count($_attr[ 'compile_id' ], "'") == 2 || is_numeric($_attr[ 'compile_id' ]))) ||
substr_count($_attr[ 'compile_id' ], '(') != 0 ||
substr_count($_attr[ 'compile_id' ], '$_smarty_tpl->') != 0
) {
$merge_compiled_includes = false;
if ($compiler->template->caching) {
// must use individual cache file
//$_attr['caching'] = 1;
}
}
if (isset($_attr[ 'compile_id' ]) && $compiler->isVariable($_attr[ 'compile_id' ])) {
$merge_compiled_includes = false;
}
}
@@ -217,6 +182,19 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
if ($compiler->template->caching && $call_nocache) {
$merge_compiled_includes = false;
}
// assign attribute
if (isset($_attr[ 'assign' ])) {
// output will be stored in a smarty variable instead of being displayed
if ($_assign = $compiler->getId($_attr[ 'assign' ])) {
$_assign = "'{$_assign}'";
if ($compiler->tag_nocache || $compiler->nocache || $call_nocache) {
// create nocache var to make it know for further compiling
$compiler->setNocacheInVariable($_attr[ 'assign' ]);
}
} else {
$_assign = $_attr[ 'assign' ];
}
}
$has_compiled_template = false;
if ($merge_compiled_includes) {
@@ -235,20 +213,14 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
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 = '';
$_vars = 'array()';
if (!empty($_attr)) {
if ($_scope == Smarty::SCOPE_LOCAL) {
$_pairs = array();
// create variables
foreach ($_attr as $key => $value) {
$_pairs[] = "'$key'=>$value";
$_vars_nc .= "\$_smarty_tpl->tpl_vars['$key'] = new Smarty_Variable($value);\n";
}
$_vars = 'array(' . join(',', $_pairs) . ')';
} else {
$compiler->trigger_template_error('variable passing not allowed in parent/global scope', null, true);
$_pairs = array();
// create variables
foreach ($_attr as $key => $value) {
$_pairs[] = "'$key'=>$value";
}
} else {
$_vars = 'array()';
$_vars = 'array(' . join(',', $_pairs) . ')';
}
$update_compile_id = $compiler->template->caching && !$compiler->tag_nocache && !$compiler->nocache &&
$_compile_id != '$_smarty_tpl->compile_id';
@@ -257,10 +229,11 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
if ($update_compile_id) {
$_output .= $compiler->makeNocacheCode("\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n");
}
if (!empty($_vars_nc) && $_caching == 9999 && $compiler->template->caching) {
//$compiler->suppressNocacheProcessing = false;
if (!empty($_attr) && $_caching == 9999 && $compiler->template->caching) {
$_vars_nc = "foreach ($_vars as \$ik => \$iv) {\n";
$_vars_nc .= "\$_smarty_tpl->tpl_vars[\$ik] = new Smarty_Variable(\$iv);\n";
$_vars_nc .= "}\n";
$_output .= substr($compiler->processNocacheCode('<?php ' . $_vars_nc . "?>\n", true), 6, - 3);
//$compiler->suppressNocacheProcessing = true;
}
if (isset($_assign)) {
$_output .= "ob_start();\n";

View File

@@ -39,44 +39,37 @@ class Smarty_Internal_Compile_While extends Smarty_Internal_CompileBase
// maybe nocache because of nocache variables
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
$_output = "<?php\n";
if (is_array($parameter[ 'if condition' ])) {
if ($compiler->nocache) {
$_nocache = ',true';
// create nocache var to make it know for further compiling
if (is_array($parameter[ 'if condition' ][ 'var' ])) {
$var = trim($parameter[ 'if condition' ][ 'var' ][ 'var' ], "'");
$var = $parameter[ 'if condition' ][ 'var' ][ 'var' ];
} else {
$var = trim($parameter[ 'if condition' ][ 'var' ], "'");
}
if (isset($compiler->template->tpl_vars[ $var ])) {
$compiler->template->tpl_vars[ $var ]->nocache = true;
} else {
$compiler->template->tpl_vars[ $var ] = new Smarty_Variable(null, true);
$var = $parameter[ 'if condition' ][ 'var' ];
}
$compiler->setNocacheInVariable($var);
} else {
$_nocache = '';
}
$assignCompiler = new Smarty_Internal_Compile_Assign();
$assignAttr = array();
$assignAttr[][ 'value' ] = $parameter[ 'if condition' ][ 'value' ];
if (is_array($parameter[ 'if condition' ][ 'var' ])) {
$_output .= "if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]) || !is_array(\$_smarty_tpl->tpl_vars[" .
$parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]->value)) \$_smarty_tpl->_createLocalArrayVariable(" .
$parameter[ 'if condition' ][ 'var' ][ 'var' ] . "$_nocache);\n";
$_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ][ 'var' ] .
"]->value" . $parameter[ 'if condition' ][ 'var' ][ 'smarty_internal_index' ] . " = " .
$parameter[ 'if condition' ][ 'value' ] . ") {?>";
$assignAttr[][ 'var' ] = $parameter[ 'if condition' ][ 'var' ][ 'var' ];
$_output = "<?php while (" . $parameter[ 'if condition' ][ 'value' ] . ") {?>";
$_output .= $assignCompiler->compile($assignAttr, $compiler,
array('smarty_internal_index' => $parameter[ 'if condition' ][ 'var' ][ 'smarty_internal_index' ]));
} else {
$_output .= "if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] .
"])) \$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] .
"] = new Smarty_Variable(null{$_nocache});";
$_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter[ 'if condition' ][ 'var' ] . "]->value = " .
$parameter[ 'if condition' ][ 'value' ] . ") {?>";
$assignAttr[][ 'var' ] = $parameter[ 'if condition' ][ 'var' ];
$_output = "<?php while (" . $parameter[ 'if condition' ][ 'value' ] . ") {?>";
$_output .= $assignCompiler->compile($assignAttr, $compiler, array());
}
return $_output;
} else {
$_output .= "while ({$parameter['if condition']}) {?>";
return "<?php\n while ({$parameter['if condition']}) {?>";
}
return $_output;
}
}

View File

@@ -96,17 +96,16 @@ class Smarty_Internal_Data
if (is_array($tpl_var)) {
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);
}
$this->assign($_key, $_val, $nocache);
}
}
} 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);
if ($this->_objType == 2) {
/** @var Smarty_Internal_Template $this */
$this->_assignInScope($tpl_var, $value, $nocache);
} else {
$this->tpl_vars[ $tpl_var ] = new Smarty_Variable($value, $nocache);
}
}
}

View File

@@ -66,7 +66,7 @@ class Smarty_Internal_Method_Append
}
}
if ($data->_objType == 2 && $data->scope) {
$data->ext->_updateScope->updateScope($data, $tpl_var);
$data->ext->_updateScope->_updateScope($data, $tpl_var);
}
}
return $data;

View File

@@ -42,7 +42,7 @@ class Smarty_Internal_Method_AppendByRef
$data->tpl_vars[ $tpl_var ]->value[] = &$value;
}
if ($data->_objType == 2 && $data->scope) {
$data->ext->_updateScope->updateScope($data, $tpl_var);
$data->ext->_updateScope->_updateScope($data, $tpl_var);
}
}
return $data;

View File

@@ -28,7 +28,7 @@ class Smarty_Internal_Method_AssignByRef
$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);
$data->ext->_updateScope->_updateScope($data, $tpl_var);
}
}
return $data;

View File

@@ -34,7 +34,7 @@ class Smarty_Internal_Method_ConfigLoad
*/
public function configLoad(Smarty_Internal_Data $data, $config_file, $sections = null)
{
$this->_loadConfigFile($data, $config_file, $sections, 0);
$this->_loadConfigFile($data, $config_file, $sections, null);
return $data;
}
@@ -82,39 +82,15 @@ class Smarty_Internal_Method_ConfigLoad
public function _loadConfigVars(Smarty_Internal_Template $tpl, $_config_vars)
{
$this->_assignConfigVars($tpl->parent, $tpl, $_config_vars);
$scope = $tpl->source->scope;
$scopes = array();
if ($scope) {
$scopes[] = $scope;
}
if ($tpl->scope) {
$scopes[] = $tpl->scope;
}
if (empty($scopes)) {
return;
}
foreach ($scopes as $s) {
$s = ($bubble_up = $s >= Smarty::SCOPE_BUBBLE_UP) ? $s - Smarty::SCOPE_BUBBLE_UP : $s;
if ($bubble_up && $s) {
$ptr = $tpl->parent->parent;
if (isset($ptr)) {
if ($tpl->parent->_objType == 2 && ($tpl->source->scope || $tpl->parent->scope)) {
$scope = $tpl->source->scope | $tpl->scope;
if ($scope) {
// update scopes
foreach ($tpl->smarty->ext->_updateScope->_getAffectedScopes($tpl->parent, $scope) as $ptr) {
$this->_assignConfigVars($ptr, $tpl, $_config_vars);
$ptr = $ptr->parent;
}
if ($s == Smarty::SCOPE_PARENT) {
continue;
}
while (isset($ptr) && $ptr->_objType == 2) {
$this->_assignConfigVars($ptr, $tpl, $_config_vars);
$ptr = $ptr->parent;
}
if ($s == Smarty::SCOPE_TPL_ROOT) {
continue;
} elseif ($s == Smarty::SCOPE_ROOT) {
while (isset($ptr->parent)) {
$ptr = $ptr->parent;
$this->_assignConfigVars($ptr, $tpl, $_config_vars);
}
if ($scope & Smarty::SCOPE_LOCAL) {
//$this->_updateVarStack($tpl, $varName);
}
}
}

View File

@@ -33,12 +33,16 @@ class Smarty_Internal_Runtime_TplFunction
}
}
if (function_exists($function)) {
$this->saveTemplateVariables($tpl, $name);
$function ($tpl, $params);
$this->restoreTemplateVariables($tpl, $name);
return;
}
// try to load template function dynamically
if ($this->addTplFuncToCache($tpl, $name, $function)) {
$this->saveTemplateVariables($tpl, $name);
$function ($tpl, $params);
$this->restoreTemplateVariables($tpl, $name);
return;
}
}
@@ -86,7 +90,7 @@ class Smarty_Internal_Runtime_TplFunction
$tplPtr->smarty->ext->_updateCache->write($cache, $tplPtr,
preg_replace('/\s*\?>\s*$/', "\n", $content) .
"\n" . preg_replace(array('/^\s*<\?php\s+/',
'/\s*\?>\s*$/'), "\n",
'/\s*\?>\s*$/',), "\n",
$match[ 0 ]));
}
}
@@ -96,4 +100,31 @@ class Smarty_Internal_Runtime_TplFunction
}
return false;
}
/**
* Save current template variables on stack
*
* @param \Smarty_Internal_Template $tpl
* @param string $name stack name
*/
public function saveTemplateVariables(Smarty_Internal_Template $tpl, $name)
{
$tpl->_cache[ 'varStack' ][] =
array('tpl' => $tpl->tpl_vars, 'config' => $tpl->config_vars, 'name' => "_tplFunction_{$name}");
}
/**
* Restore saved variables into template objects
*
* @param \Smarty_Internal_Template $tpl
* @param string $name stack name
*/
public function restoreTemplateVariables(Smarty_Internal_Template $tpl, $name)
{
if (isset($tpl->_cache[ 'varStack' ])) {
$vars = array_pop($tpl->_cache[ 'varStack' ]);
$tpl->tpl_vars = $vars[ 'tpl' ];
$tpl->config_vars = $vars[ 'config' ];
}
}
}

View File

@@ -10,65 +10,101 @@
**/
class Smarty_Internal_Runtime_UpdateScope
{
/**
* Update new assigned template variable in other effected scopes
* Update new assigned template or config variable in other effected scopes
*
* @param Smarty_Internal_Template $tpl data object
* @param string|null $varName variable name
* @param int $scope scope to which bubble up variable value
*
* @param \Smarty_Internal_Data $tpl data object
* @param string $varName variable name
* @param int $scope scope to which bubble up variable value
*/
public function updateScope(Smarty_Internal_Data $tpl, $varName, $scope = Smarty::SCOPE_LOCAL)
public function _updateScope(Smarty_Internal_Template $tpl, $varName, $scope = 0)
{
$scopes = array();
$scope = $scope | $tpl->scope;
if ($scope) {
$scopes[] = $scope;
}
if ($tpl->scope) {
$scopes[] = $tpl->scope;
}
if (empty($scopes)) {
return;
}
/* @var Smarty_Internal_Data $ptr */
$ptr = null;
foreach ($scopes as $s) {
$s = ($bubble_up = $s >= Smarty::SCOPE_BUBBLE_UP) ? $s - Smarty::SCOPE_BUBBLE_UP : $s;
if ($bubble_up && $s) {
$oldGlobal = null;
if ($s == Smarty::SCOPE_GLOBAL) {
$oldGlobal =
isset(Smarty::$global_tpl_vars[ $varName ]) ? Smarty::$global_tpl_vars[ $varName ] : null;
Smarty::$global_tpl_vars[ $varName ] = $tpl->tpl_vars[ $varName ];
}
if (isset($tpl->parent) && $tpl->parent->_objType == 2) {
$ptr = $tpl->parent;
if ($s == Smarty::SCOPE_GLOBAL && isset($oldGlobal) && isset($ptr->tpl_vars[ $varName ]) &&
$ptr->tpl_vars[ $varName ] !== $oldGlobal
) {
continue;
}
$ptr->tpl_vars[ $varName ] = $tpl->tpl_vars[ $varName ];
if (isset($ptr->parent)) {
$ptr = $ptr->parent;
}
} elseif (isset($tpl->parent)) {
$ptr = $tpl->parent;
}
if ($s == Smarty::SCOPE_PARENT) {
continue;
}
while (isset($ptr) && $ptr->_objType == 2) {
$ptr->tpl_vars[ $varName ] = $tpl->tpl_vars[ $varName ];
$ptr = $ptr->parent;
}
if ($s == Smarty::SCOPE_TPL_ROOT) {
continue;
}
while (isset($ptr) && $s != Smarty::SCOPE_GLOBAL) {
$ptr->tpl_vars[ $varName ] = $tpl->tpl_vars[ $varName ];
$ptr = isset($ptr->parent) ? $ptr->parent : null;
}
if ($scope & Smarty::SCOPE_GLOBAL && $varName) {
Smarty::$global_tpl_vars[ $varName ] = $tpl->tpl_vars[ $varName ];
}
// update scopes
foreach ($this->_getAffectedScopes($tpl, $scope) as $ptr) {
$this->_updateObject($ptr, $tpl, $varName);
}
if ($scope & Smarty::SCOPE_LOCAL) {
$this->_updateVarStack($tpl, $varName);
}
}
}
/**
* Get array of objects which needs to be updated by given scope value
*
* @param Smarty_Internal_Template $tpl
* @param int $scope scope to which bubble up variable value
*
* @return array
*/
public function _getAffectedScopes(Smarty_Internal_Template $tpl, $scope)
{
$_stack = array();
$ptr = $tpl->parent;
while (isset($ptr) && $ptr->_objType == 2) {
if (($scope & Smarty::SCOPE_BUBBLE_UP) || ($scope & Smarty::SCOPE_PARENT)) {
$_stack[] = $ptr;
$scope = $scope & ~Smarty::SCOPE_PARENT;
} elseif (($scope & Smarty::SCOPE_TPL_ROOT) && (!isset($ptr->parent) || $ptr->parent->_objType != 2)) {
$_stack[] = $ptr;
}
$ptr = $ptr->parent;
}
if ($scope & Smarty::SCOPE_SMARTY) {
if (isset($tpl->smarty)) {
$_stack[] = $tpl->smarty;
}
} elseif ($scope & Smarty::SCOPE_ROOT) {
while (isset($ptr)) {
if ($ptr->_objType != 2) {
$_stack[] = $ptr;
break;
}
$ptr = $ptr->parent;
}
}
return $_stack;
}
/**
* Update variable in object
*
* @param \Smarty_Internal_Data $to
* @param \Smarty_Internal_Template $from
* @param string|null $varName variable name
*/
public function _updateObject(Smarty_Internal_Data $to, Smarty_Internal_Template $from, $varName)
{
if (!isset($to->tpl_vars[ $varName ])) {
$to->tpl_vars[ $varName ] = clone $from->tpl_vars[ $varName ];
} else {
$to->tpl_vars[ $varName ] = clone $to->tpl_vars[ $varName ];
$to->tpl_vars[ $varName ]->value = $from->tpl_vars[ $varName ]->value;
}
if ($to->_objType == 2) {
$this->_updateVarStack($to, $varName);
}
}
/**
* Update variable in template local variable stack
*
* @param \Smarty_Internal_Template $tpl
* @param string|null $varName variable name or null for config variables
*/
public function _updateVarStack(Smarty_Internal_Template $tpl, $varName)
{
$i = 0;
while (isset($tpl->_cache[ 'varStack' ][ $i ])) {
$tpl->_cache[ 'varStack' ][ $i ][ 'tpl' ][ $varName ] = $tpl->tpl_vars[ $varName ];
$i ++;
}
}
}

View File

@@ -75,7 +75,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
public $tpl_function = array();
/**
* Scope in which template is rendered
* Scope in which variables shall be assigned
*
* @var int
*/
@@ -295,23 +295,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
}
// set template scope
$tpl->scope = $scope;
$scopePtr = false;
$scope = $scope & ~Smarty::SCOPE_BUBBLE_UP;
if ($scope) {
if ($scope == Smarty::SCOPE_PARENT) {
$scopePtr = $this;
} else {
$scopePtr = $tpl;
while (isset($scopePtr->parent)) {
if (!$scopePtr->_isParentTemplate() && $scope & Smarty::SCOPE_TPL_ROOT) {
break;
}
$scopePtr = $scopePtr->parent;
}
}
$tpl->tpl_vars = $scopePtr->tpl_vars;
$tpl->config_vars = $scopePtr->config_vars;
}
if (!isset($tpl->smarty->_cache[ 'tplObjects' ][ $tpl->templateId ]) && !$tpl->source->handler->recompiled) {
// if template is called multiple times set flag to to cache template objects
$forceTplCache = $forceTplCache ||
@@ -351,10 +334,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
$tpl->render();
}
}
if ($scopePtr) {
$scopePtr->tpl_vars = $tpl->tpl_vars;
$scopePtr->config_vars = $tpl->config_vars;
}
$i = 0;
}
/**
@@ -385,45 +365,25 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
/**
* Assign variable in scope
*
* @param string $varName variable name
* @param mixed $value value
* @param bool $nocache nocache flag
* @param int $scope scope into which variable shall be assigned
* @param bool $smartyBC true if called in Smarty bc class
* @param string $varName variable name
* @param mixed $value value
* @param bool $nocache nocache flag
* @param int $scope scope into which variable shall be assigned
*
* @throws \SmartyException
*/
public function _assignInScope($varName, $value, $nocache, $scope, $smartyBC)
public function _assignInScope($varName, $value, $nocache = false, $scope = 0)
{
if ($smartyBC && isset($this->tpl_vars[ $varName ])) {
if (isset($this->tpl_vars[ $varName ])) {
$this->tpl_vars[ $varName ] = clone $this->tpl_vars[ $varName ];
$this->tpl_vars[ $varName ]->value = $value;
$this->tpl_vars[ $varName ]->nocache = $nocache;
if ($nocache) {
$this->tpl_vars[ $varName ]->nocache = $nocache;
}
} else {
$this->tpl_vars[ $varName ] = new Smarty_Variable($value, $nocache);
}
if ($scope || $this->scope & Smarty::SCOPE_BUBBLE_UP) {
$this->ext->_updateScope->updateScope($this, $varName, $scope);
}
}
/**
* Template code runtime function to create a local Smarty variable for array assignments
*
* @param string $varName template variable name
* @param bool $nocache cache mode of variable
*/
public function _createLocalArrayVariable($varName, $nocache = false)
{
if (!isset($this->tpl_vars[ $varName ])) {
$this->tpl_vars[ $varName ] = new Smarty_Variable(array(), $nocache);
} else {
$this->tpl_vars[ $varName ] = clone $this->tpl_vars[ $varName ];
if (!(is_array($this->tpl_vars[ $varName ]->value) ||
$this->tpl_vars[ $varName ]->value instanceof ArrayAccess)
) {
settype($this->tpl_vars[ $varName ]->value, 'array');
}
if (isset($scope) || isset($this->scope)) {
$this->smarty->ext->_updateScope->_updateScope($this, $varName, $scope);
}
}

View File

@@ -384,7 +384,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
// add file dependency
$this->parent_compiler->template->compiled->file_dependency[ $this->template->source->uid ] =
array($this->template->source->filepath, $this->template->source->getTimeStamp(),
$this->template->source->type);
$this->template->source->type,);
$this->smarty->_current_file = $this->template->source->filepath;
// get template source
if (!empty($this->template->source->components)) {
@@ -563,7 +563,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
}
}
// check if tag is registered
foreach (array(Smarty::PLUGIN_COMPILER, Smarty::PLUGIN_FUNCTION, Smarty::PLUGIN_BLOCK) as $plugin_type)
foreach (array(Smarty::PLUGIN_COMPILER, Smarty::PLUGIN_FUNCTION, Smarty::PLUGIN_BLOCK,) as $plugin_type)
{
if (isset($this->smarty->registered_plugins[ $plugin_type ][ $tag ])) {
// if compiler function plugin call it now
@@ -817,7 +817,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
'#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1\2',
// remove spaces between attributes (but not in attribute values!)
'#(([a-z0-9]\s*=\s*("[^"]*?")|(\'[^\']*?\'))|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \5',
'#^\s+<#Ss' => '<', '#>\s+$#Ss' => '>', $this->stripRegEx => '');
'#^\s+<#Ss' => '<', '#>\s+$#Ss' => '>', $this->stripRegEx => '',);
$text = preg_replace(array_keys($expressions), array_values($expressions), $text);
$_offset = 0;
@@ -960,7 +960,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
$script = null;
$cacheable = true;
$result = call_user_func_array($this->smarty->default_plugin_handler_func,
array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable));
array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable,));
if ($result) {
$this->tag_nocache = $this->tag_nocache || !$cacheable;
if ($script !== null) {
@@ -1118,7 +1118,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
*/
public function convertScope($_attr, $validScopes)
{
$_scope = Smarty::SCOPE_LOCAL;
$_scope = 0;
if (isset($_attr[ 'scope' ])) {
$_scopeName = trim($_attr[ 'scope' ], "'\"");
if (is_numeric($_scopeName) && in_array($_scopeName, $validScopes)) {
@@ -1133,7 +1133,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
$err = var_export($_scopeName, true);
$this->trigger_template_error("illegal value '{$err}' for \"scope\" attribute", null, true);
}
if (isset($_attr[ 'bubble_up' ]) && $_attr[ 'bubble_up' ]) {
if (isset($_attr[ 'bubble_up' ]) && $_attr[ 'bubble_up' ] && $_scope > 2) {
$_scope += Smarty::SCOPE_BUBBLE_UP;
}
}
@@ -1291,4 +1291,22 @@ abstract class Smarty_Internal_TemplateCompilerBase
{
$this->prefix_code[] = $code;
}
/**
* get prefix code string
*
* @return string
*/
public function getPrefixCode()
{
$code = '';
$prefixArray = array_merge($this->prefix_code, array_pop($this->prefixCodeStack));
$this->prefixCodeStack[] = array();
foreach ($prefixArray as $c) {
$code = $this->appendCode($code, $c);
}
$this->prefix_code = array();
return $code;
}
}

View File

@@ -28,9 +28,9 @@ class Smarty_Template_Config extends Smarty_Template_Source
/**
* scope into which the config variables shall be loaded
*
* @var string
* @var int
*/
public $scope = 'local';
public $scope = 0;
/**
* Flag that source is a config file