diff --git a/common/framework/Template.php b/common/framework/Template.php index b1f60f60d..10574c1e5 100644 --- a/common/framework/Template.php +++ b/common/framework/Template.php @@ -215,7 +215,7 @@ class Template } elseif (is_object($vars)) { - $this->vars = $vars; + $this->vars = clone $vars; } else { @@ -223,6 +223,25 @@ class Template } } + /** + * Add vars. + * + * @param array|object $vars + * @return void + */ + public function addVars($vars): void + { + if (!isset($this->vars)) + { + $this->vars = new \stdClass; + } + + foreach (is_object($vars) ? get_object_vars($vars) : $vars as $key => $val) + { + $this->vars->$key = $val; + } + } + /** * Compile and execute a template file. * @@ -535,9 +554,13 @@ class Template } // Set variables. + if ($this->vars) + { + $template->setVars($this->vars); + } if ($vars !== null) { - $template->setVars($vars); + $template->addVars($vars); } // Compile and return. diff --git a/common/framework/parsers/template/TemplateParser_v2.php b/common/framework/parsers/template/TemplateParser_v2.php index abd5c3323..52499ed01 100644 --- a/common/framework/parsers/template/TemplateParser_v2.php +++ b/common/framework/parsers/template/TemplateParser_v2.php @@ -402,7 +402,8 @@ class TemplateParser_v2 // Generate the code to create a new Template object and compile it. $tpl = 'template->extension ?: 'auto') . '"); '; - $tpl .= !empty($attrs['vars']) ? '$__tpl->setVars(' . self::_convertVariableScope($attrs['vars']) . '); ' : ''; + $tpl .= 'if ($this->vars): $__tpl->setVars($this->vars); endif; '; + $tpl .= !empty($attrs['vars']) ? '$__tpl->addVars(' . self::_convertVariableScope($attrs['vars']) . '); ' : ''; $tpl .= 'echo $__tpl->compile(); ?>'; // Add conditions around the code. diff --git a/tests/_data/template/incl/scopetest1.html b/tests/_data/template/incl/scopetest1.html new file mode 100644 index 000000000..d6bf7e92d --- /dev/null +++ b/tests/_data/template/incl/scopetest1.html @@ -0,0 +1,3 @@ + +
{{ $foobar }}
+
{{ $globalonly }}
diff --git a/tests/_data/template/incl/scopetest2.html b/tests/_data/template/incl/scopetest2.html new file mode 100644 index 000000000..972382225 --- /dev/null +++ b/tests/_data/template/incl/scopetest2.html @@ -0,0 +1,5 @@ + +
{{ $foobar }}
+
+ +
diff --git a/tests/_data/template/v2varscope.executed.html b/tests/_data/template/v2varscope.executed.html new file mode 100644 index 000000000..a7b9b776b --- /dev/null +++ b/tests/_data/template/v2varscope.executed.html @@ -0,0 +1,18 @@ + +
+
Rhymix Template
+
Context Variable
+
+ +
+
Included #1
+
+
+ +
+
Included #2
+
+
Included #3
+
+
+
diff --git a/tests/_data/template/v2varscope.html b/tests/_data/template/v2varscope.html new file mode 100644 index 000000000..2845985fc --- /dev/null +++ b/tests/_data/template/v2varscope.html @@ -0,0 +1,18 @@ +@version(2) + +@php + $foobar = 'Rhymix Template'; + $globalonly = 'Context Variable'; +@endphp + +
+ @include ('incl/scopetest1.html') +
+ +
+ @include ('incl/scopetest1.html', ['foobar' => 'Included #1']) +
+ +
+ @include ('incl/scopetest2.html', ['foobar' => 'Included #2']) +
diff --git a/tests/unit/framework/parsers/TemplateParserV2Test.php b/tests/unit/framework/parsers/TemplateParserV2Test.php index 49d17fb35..ecb555958 100644 --- a/tests/unit/framework/parsers/TemplateParserV2Test.php +++ b/tests/unit/framework/parsers/TemplateParserV2Test.php @@ -50,42 +50,42 @@ class TemplateParserV2Test extends \Codeception\Test\Unit { // Basic usage $source = ''; - $target = 'relative_dirname, "foobar", "html"); echo $__tpl->compile(); ?>'; + $target = 'relative_dirname, "foobar", "html"); if ($this->vars): $__tpl->setVars($this->vars); endif; echo $__tpl->compile(); ?>'; $this->assertEquals($target, $this->_parse($source)); // Legacy 'target' attribute $source = ''; - $target = 'relative_dirname, "subdir/foobar", "html"); echo $__tpl->compile(); ?>'; + $target = 'relative_dirname, "subdir/foobar", "html"); if ($this->vars): $__tpl->setVars($this->vars); endif; echo $__tpl->compile(); ?>'; $this->assertEquals($target, $this->_parse($source)); // Conditional include $source = ''; - $target = 'relative_dirname, "../up/foobar", "html"); echo $__tpl->compile(); ?>'; + $target = 'relative_dirname, "../up/foobar", "html"); if ($this->vars): $__tpl->setVars($this->vars); endif; echo $__tpl->compile(); ?>'; $this->assertEquals($target, $this->_parse($source)); // Conditional include with legacy 'cond' attribute $source = ''; - $target = 'relative_dirname, "legacy/cond.statement.html", "html"); echo $__tpl->compile(); ?>'; + $target = 'relative_dirname, "legacy/cond.statement.html", "html"); if ($this->vars): $__tpl->setVars($this->vars); endif; echo $__tpl->compile(); ?>'; $this->assertEquals($target, $this->_parse($source)); // Path relative to Rhymix installation directory $source = ''; - $target = 'compile(); ?>'; + $target = 'vars): $__tpl->setVars($this->vars); endif; echo $__tpl->compile(); ?>'; $this->assertEquals($target, $this->_parse($source)); // Unless $source = ''; - $target = 'compile(); ?>'; + $target = 'vars): $__tpl->setVars($this->vars); endif; echo $__tpl->compile(); ?>'; $this->assertEquals($target, $this->_parse($source)); // With variables $source = ''; - $target = 'relative_dirname, "foobar", "html"); $__tpl->setVars($__Context->vars); echo $__tpl->compile(); ?>'; + $target = 'relative_dirname, "foobar", "html"); if ($this->vars): $__tpl->setVars($this->vars); endif; $__tpl->addVars($__Context->vars); echo $__tpl->compile(); ?>'; $this->assertEquals($target, $this->_parse($source)); // With array literal passed as variables $source = ''; - $target = 'relative_dirname, "foobar", "html"); $__tpl->setVars([\'foo\' => \'bar\']); echo $__tpl->compile(); ?>'; + $target = 'relative_dirname, "foobar", "html"); if ($this->vars): $__tpl->setVars($this->vars); endif; $__tpl->addVars([\'foo\' => \'bar\']); echo $__tpl->compile(); ?>'; $this->assertEquals($target, $this->_parse($source)); // Blade-style @include @@ -1071,7 +1071,7 @@ class TemplateParserV2Test extends \Codeception\Test\Unit // cond is OK in includes $source = ''; - $target = 'relative_dirname, "foo.html", "html"); echo $__tpl->compile(); ?>';; + $target = 'relative_dirname, "foo.html", "html"); if ($this->vars): $__tpl->setVars($this->vars); endif; echo $__tpl->compile(); ?>';; $this->assertEquals($target, $this->_parse($source)); // loop @@ -1171,6 +1171,18 @@ class TemplateParserV2Test extends \Codeception\Test\Unit $this->_normalizeWhitespace($expected), $this->_normalizeWhitespace($executed_output) ); + + // Variable scope check + $tmpl = new \Rhymix\Framework\Template('./tests/_data/template', 'v2varscope.html'); + $tmpl->disableCache(); + + $executed_output = $tmpl->compile(); + //Rhymix\Framework\Storage::write(\RX_BASEDIR . 'tests/_data/template/v2varscope.executed.html', $executed_output); + $expected = file_get_contents(\RX_BASEDIR . 'tests/_data/template/v2varscope.executed.html'); + $this->assertEquals( + $this->_normalizeWhitespace($expected), + $this->_normalizeWhitespace($executed_output) + ); } /**