diff --git a/src/Compile/Tag/ForTag.php b/src/Compile/Tag/ForTag.php index fdf71b681..ee78c59b6 100644 --- a/src/Compile/Tag/ForTag.php +++ b/src/Compile/Tag/ForTag.php @@ -51,8 +51,9 @@ public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = $var = $_statement['var']; $index = ''; } - $output .= "\$_smarty_tpl->assign($var, null);\n"; - $output .= "\$_smarty_tpl->tpl_vars[$var]->value{$index} = {$_statement['value']};\n"; + $itemVar = "\$_smarty_tpl->getVariable({$var})"; + $output .= "\$_smarty_tpl->assign($var, []);\n"; + $output .= "{$itemVar}->value{$index} = {$_statement['value']};\n"; } if (is_array($_attr['var'])) { $var = $_attr['var']['var']; @@ -61,7 +62,8 @@ public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = $var = $_attr['var']; $index = ''; } - $output .= "if ($_attr[ifexp]) {\nfor (\$_foo=true;$_attr[ifexp]; \$_smarty_tpl->tpl_vars[$var]->value{$index}$_attr[step]) {\n"; + $itemVar = "\$_smarty_tpl->getVariable({$var})"; + $output .= "if ($_attr[ifexp]) {\nfor (\$_foo=true;$_attr[ifexp]; {$itemVar}->value{$index}$_attr[step]) {\n"; } else { $_statement = $_attr['start']; if (is_array($_statement['var'])) { @@ -71,21 +73,22 @@ public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = $var = $_statement['var']; $index = ''; } - $output .= "\$_smarty_tpl->assign($var, null);"; + $itemVar = "\$_smarty_tpl->getVariable({$var})"; + $output .= "\$_smarty_tpl->assign($var, []);"; if (isset($_attr['step'])) { - $output .= "\$_smarty_tpl->tpl_vars[$var]->step = $_attr[step];"; + $output .= "{$itemVar}->step = $_attr[step];"; } else { - $output .= "\$_smarty_tpl->tpl_vars[$var]->step = 1;"; + $output .= "{$itemVar}->step = 1;"; } if (isset($_attr['max'])) { - $output .= "\$_smarty_tpl->tpl_vars[$var]->total = (int) min(ceil((\$_smarty_tpl->tpl_vars[$var]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$var]->step)),$_attr[max]);\n"; + $output .= "{$itemVar}->total = (int) min(ceil(({$itemVar}->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs({$itemVar}->step)),$_attr[max]);\n"; } else { - $output .= "\$_smarty_tpl->tpl_vars[$var]->total = (int) ceil((\$_smarty_tpl->tpl_vars[$var]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$var]->step));\n"; + $output .= "{$itemVar}->total = (int) ceil(({$itemVar}->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs({$itemVar}->step));\n"; } - $output .= "if (\$_smarty_tpl->tpl_vars[$var]->total > 0) {\n"; - $output .= "for (\$_smarty_tpl->tpl_vars[$var]->value{$index} = $_statement[value], \$_smarty_tpl->tpl_vars[$var]->iteration = 1;\$_smarty_tpl->tpl_vars[$var]->iteration <= \$_smarty_tpl->tpl_vars[$var]->total;\$_smarty_tpl->tpl_vars[$var]->value{$index} += \$_smarty_tpl->tpl_vars[$var]->step, \$_smarty_tpl->tpl_vars[$var]->iteration++) {\n"; - $output .= "\$_smarty_tpl->tpl_vars[$var]->first = \$_smarty_tpl->tpl_vars[$var]->iteration === 1;"; - $output .= "\$_smarty_tpl->tpl_vars[$var]->last = \$_smarty_tpl->tpl_vars[$var]->iteration === \$_smarty_tpl->tpl_vars[$var]->total;"; + $output .= "if ({$itemVar}->total > 0) {\n"; + $output .= "for ({$itemVar}->value{$index} = $_statement[value], {$itemVar}->iteration = 1;{$itemVar}->iteration <= {$itemVar}->total;{$itemVar}->value{$index} += {$itemVar}->step, {$itemVar}->iteration++) {\n"; + $output .= "{$itemVar}->first = {$itemVar}->iteration === 1;"; + $output .= "{$itemVar}->last = {$itemVar}->iteration === {$itemVar}->total;"; } $output .= '?>'; diff --git a/tests/UnitTests/TemplateSource/TagTests/For/CompileForTest.php b/tests/UnitTests/TemplateSource/TagTests/For/CompileForTest.php index 21d997d60..9fae9a9c5 100644 --- a/tests/UnitTests/TemplateSource/TagTests/For/CompileForTest.php +++ b/tests/UnitTests/TemplateSource/TagTests/For/CompileForTest.php @@ -197,4 +197,65 @@ public function dataTestSpacing() array("{for \$x=-1;\$x>=0;\$x--}{\$x}{forelse}{\$buh}{/for}", "buh", 'T14', $i++), ); } + + /** + * Test for inside extended template issue #1036 + */ + public function testForWithExtendedTemplate() : void + { + $this->smarty->caching = false; + $tpl = $this->smarty->createTemplate( 'extends:string:{block name="content"}{/block}|string:{block name="content"}{for $i=0 to 3}{$i}{/for}{/block}' ); + $this->assertEquals( "0123", $this->smarty->fetch( $tpl ) ); + } + + /** + * Test for inside extended template issue #1036 + */ + public function testForWithExtendedTemplateWithStep() : void + { + $this->smarty->caching = false; + $tpl = $this->smarty->createTemplate( 'extends:string:{block name="content"}{/block}|string:{block name="content"}{for $i=0 to 3 step 2}{$i}{/for}{/block}' ); + $this->assertEquals( "02", $this->smarty->fetch( $tpl ) ); + } + + /** + * Test for inside extended template issue #1036 + */ + public function testForWithExtendedTemplateWithMax() : void + { + $this->smarty->caching = false; + $tpl = $this->smarty->createTemplate( 'extends:string:{block name="content"}{/block}|string:{block name="content"}{for $i=0 to 30 max=3}{$i}{/for}{/block}' ); + $this->assertEquals( "012", $this->smarty->fetch( $tpl ) ); + } + + /** + * Test for inside extended template issue #1036 + */ + public function testNestedForWithExtendedTemplate() : void + { + $this->smarty->caching = false; + $tpl = $this->smarty->createTemplate( 'extends:string:{block name="content"}{/block}|string:{block name="content"}{for $i=0 to 1}{for $y=0 to 3}{$y}{/for}{/for}{/block}' ); + $this->assertEquals( "01230123", $this->smarty->fetch( $tpl ) ); + } + + /** + * Test for inside extended template issue #1036 + */ + public function testForLegacySyntaxWithExtendedTemplate() : void + { + $this->smarty->caching = false; + $tpl = $this->smarty->createTemplate( 'extends:string:{block name="content"}{/block}|string:{block name="content"}{for $i=0; $i<4; $i++}{$i}{/for}{/block}' ); + $this->assertEquals( "0123", $this->smarty->fetch( $tpl ) ); + } + + /** + * Test for inside extended template issue #1036 + */ + public function testForLegacySyntaxTemplate() : void + { + $this->smarty->caching = false; + $tpl = $this->smarty->createTemplate('string:{for $i=0; $i<4; $i++}{$i}{/for}'); + $this->assertEquals("0123", $this->smarty->fetch($tpl)); + } + }