From e205cb7a89099076748ee83d345cae7390291ec9 Mon Sep 17 00:00:00 2001 From: Uwe Tews Date: Sun, 2 Aug 2015 19:43:21 +0200 Subject: [PATCH] - optimization and code cleanup of {foreach} and {section} compiler --- change_log.txt | 3 + libs/Smarty.class.php | 2 +- .../smarty_internal_compile_foreach.php | 189 ++++++++---------- ...nternal_compile_private_foreachsection.php | 2 +- .../smarty_internal_compile_section.php | 100 ++++----- 5 files changed, 130 insertions(+), 166 deletions(-) diff --git a/change_log.txt b/change_log.txt index f033394c..a120bdbf 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,4 +1,7 @@  ===== 3.1.28-dev===== (xx.xx.2015) + 02.08.2015 + - optimization and code cleanup of {foreach} and {section} compiler + 01.08.2015 - update DateTime object can be instance of DateTimeImmutable since PHP5.5 https://github.com/smarty-php/smarty/pull/75 - improvement show resource type and start of template source instead of uid on eval: and string: resource (forum topic 25630) diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index d0d2d17b..8a27854c 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -111,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.28-dev/36'; + const SMARTY_VERSION = '3.1.28-dev/37'; /** * define variable scopes diff --git a/libs/sysplugins/smarty_internal_compile_foreach.php b/libs/sysplugins/smarty_internal_compile_foreach.php index ab37a63c..9c62e81d 100644 --- a/libs/sysplugins/smarty_internal_compile_foreach.php +++ b/libs/sysplugins/smarty_internal_compile_foreach.php @@ -59,14 +59,14 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_Fo * * @var array */ - public static $nameProperties = array('first','last','index','iteration','show','total'); + public static $nameProperties = array('first', 'last', 'index', 'iteration', 'show', 'total'); /** * Valid properties of $item@xxx variable * * @var array */ - public $itemProperties = array('first','last','index','iteration','show','total', 'key'); + public $itemProperties = array('first', 'last', 'index', 'iteration', 'show', 'total', 'key'); /** * Flag if tag had name attribute @@ -121,11 +121,11 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_Fo } } } - $attributes['no'] = $this->counter ++ . '_' . (isset($attributes['name']) ? $attributes['name'] : $attributes['item']); - $this->openTag($compiler, 'foreach', array('foreach', $compiler->nocache, $attributes, true)); - // maybe nocache because of nocache variables - $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + $itemVar = "\$_smarty_tpl->tpl_vars['{$item}']"; + $local = '$__foreach_' . (isset($attributes['name']) ? $attributes['name'] : $attributes['item']) . '_' . + $this->counter ++ . '_'; + $needIteration = false; // search for used tag attributes $itemAttr = array(); $namedAttr = array(); @@ -136,69 +136,62 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_Fo if (!empty($this->matchResults['named'])) { $namedAttr = $this->matchResults['named']; } - - if (!isset($itemAttr['index']) && (isset($itemAttr['first']) || isset($itemAttr['last']))) { - $itemAttr['iteration'] = true; - } if (isset($itemAttr['last'])) { - $itemAttr['total'] = true; + $needIteration = true; } - if ($this->isNamed) { - if (!isset($namedAttr['index']) && (isset($namedAttr['first']) || isset($namedAttr['last']))) { - $namedAttr['iteration'] = true; - } - if (isset($namedAttr['last'])) { - $namedAttr['total'] = true; - } + if (isset($namedAttr['last'])) { + $needIteration = true; } $keyTerm = ''; if (isset($itemAttr['key'])) { - $keyTerm = "\$_smarty_tpl->tpl_vars['{$item}']->key => "; + $keyTerm = "{$itemVar}->key => "; } elseif (isset($attributes['key'])) { $keyTerm = "\$_smarty_tpl->tpl_vars['{$key}']->value => "; } - // generate output code - $output = "tpl_vars['{$attributes[$a]}']) ? \$_smarty_tpl->tpl_vars['{$attributes[$a]}'] : false;\n"; + + $saveVars = array(); + $restoreVars = array(); + if ($this->isNamed) { + $foreachVar = "\$_smarty_tpl->tpl_vars['__smarty_foreach_{$attributes['name']}']"; + if (!empty($namedAttr)) { + $saveVars['saved'] = "isset({$foreachVar}) ? {$foreachVar} : false;"; + $restoreVars[] = "if ({$local}saved) {\n{$foreachVar} = {$local}saved;\n}\n"; } } - if (isset($attributes['name'])) { - $output .= "\$foreach_{$attributes['no']}_sav['s_name'] = isset(\$_smarty_tpl->tpl_vars['__foreach_{$attributes['name']}']) ? \$_smarty_tpl->tpl_vars['__foreach_{$attributes['name']}'] : false;\n"; + foreach (array('item', 'key') as $a) { + if (isset($attributes[$a])) { + $saveVars['saved_' . + $a] = "isset(\$_smarty_tpl->tpl_vars['{$attributes[$a]}']) ? \$_smarty_tpl->tpl_vars['{$attributes[$a]}'] : false;"; + $restoreVars[] = "if ({$local}saved_{$a}) {\n\$_smarty_tpl->tpl_vars['{$attributes[$a]}'] = {$local}saved_{$a};\n}\n"; + } } + $this->openTag($compiler, 'foreach', array('foreach', $compiler->nocache, $local, $restoreVars, $itemVar, + true)); + // maybe nocache because of nocache variables + $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + + // generate output code + $output = "tpl_vars['{$item}'] = new Smarty_Variable;\n"; - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->_loop = false;\n"; - if (isset($attributes['key'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$key}'] = new Smarty_Variable;\n"; + foreach ($saveVars as $k => $code) { + $output .= "{$local}{$k} = {$code}\n"; + } + $output .= "{$itemVar} = new Smarty_Variable();\n"; + $output .= "{$local}total = \$_smarty_tpl->_count(\$_from);\n"; + if (isset($itemAttr['show'])) { + $output .= "{$itemVar}->show = ({$local}total > 0);\n"; } if (isset($itemAttr['total'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->total= \$_smarty_tpl->_count(\$_from);\n"; - } - if (isset($itemAttr['iteration'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->iteration=0;\n"; - } - if (isset($itemAttr['index'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->index=-1;\n"; - } - if (isset($itemAttr['show'])) { - if (isset($itemAttr['total'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->show = (\$_smarty_tpl->tpl_vars['{$item}']->total > 0);\n"; - } else { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->show = (\$_smarty_tpl->_count(\$_from) > 0);\n"; - } + $output .= "{$itemVar}->total= {$local}total;\n"; } if ($this->isNamed) { $prop = array(); if (isset($namedAttr['total'])) { - $prop['total'] = "'total' => "; - $prop['total'] .= isset($namedAttr['show']) ? '$total = ' : ''; - $prop['total'] .= '$_smarty_tpl->_count($_from)'; + $prop['total'] = "'total' => {$local}total"; } if (isset($namedAttr['iteration'])) { $prop['iteration'] = "'iteration' => 0"; @@ -207,67 +200,66 @@ class Smarty_Internal_Compile_Foreach extends Smarty_Internal_Compile_Private_Fo $prop['index'] = "'index' => -1"; } if (isset($namedAttr['show'])) { - $prop['show'] = "'show' => "; - if (isset($namedAttr['total'])) { - $prop['show'] .= "(\$total > 0)"; - } else { - $prop['show'] .= "(\$_smarty_tpl->_count(\$_from) > 0)"; - } + $prop['show'] = "'show' => ({$local}total > 0)"; } if (!empty($namedAttr)) { $_vars = 'array(' . join(', ', $prop) . ')'; - $foreachVar = "'__foreach_{$attributes['name']}'"; - $output .= "\$_smarty_tpl->tpl_vars[$foreachVar] = new Smarty_Variable({$_vars});\n"; + $output .= "{$foreachVar} = new Smarty_Variable({$_vars});\n"; } } - $output .= "foreach (\$_from as {$keyTerm}\$_smarty_tpl->tpl_vars['{$item}']->value) {\n"; - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->_loop = true;\n"; - if (isset($attributes['key']) && isset($itemAttr['key'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$key}']->value = \$_smarty_tpl->tpl_vars['{$item}']->key;\n"; + $output .= "if ({$local}total) {\n"; + if (isset($attributes['key'])) { + $output .= "\$_smarty_tpl->tpl_vars['{$key}'] = new Smarty_Variable();\n"; + } + if (isset($namedAttr['first']) || isset($itemAttr['first'])) { + $output .= "{$local}first = true;\n"; } if (isset($itemAttr['iteration'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->iteration++;\n"; + $output .= "{$itemVar}->iteration=0;\n"; } if (isset($itemAttr['index'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->index++;\n"; + $output .= "{$itemVar}->index=-1;\n"; + } + if ($needIteration) { + $output .= "{$local}iteration=0;\n"; + } + $output .= "foreach (\$_from as {$keyTerm}{$itemVar}->value) {\n"; + if (isset($attributes['key']) && isset($itemAttr['key'])) { + $output .= "\$_smarty_tpl->tpl_vars['{$key}']->value = {$itemVar}->key;\n"; + } + if (isset($itemAttr['iteration'])) { + $output .= "{$itemVar}->iteration++;\n"; + } + if (isset($itemAttr['index'])) { + $output .= "{$itemVar}->index++;\n"; + } + if ($needIteration) { + $output .= "{$local}iteration++;\n"; } if (isset($itemAttr['first'])) { - if (isset($itemAttr['index'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->first = \$_smarty_tpl->tpl_vars['{$item}']->index == 0;\n"; - } else { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->first = \$_smarty_tpl->tpl_vars['{$item}']->iteration == 1;\n"; - } + $output .= "{$itemVar}->first = {$local}first;\n"; } if (isset($itemAttr['last'])) { - if (isset($itemAttr['index'])) { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->last = \$_smarty_tpl->tpl_vars['{$item}']->index + 1 == \$_smarty_tpl->tpl_vars['{$item}']->total;\n"; - } else { - $output .= "\$_smarty_tpl->tpl_vars['{$item}']->last = \$_smarty_tpl->tpl_vars['{$item}']->iteration == \$_smarty_tpl->tpl_vars['{$item}']->total;\n"; - } + $output .= "{$itemVar}->last = {$local}iteration == {$local}total;\n"; } if ($this->isNamed) { if (isset($namedAttr['iteration'])) { - $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['iteration']++;\n"; + $output .= "{$foreachVar}->value['iteration']++;\n"; } if (isset($namedAttr['index'])) { - $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['index']++;\n"; + $output .= "{$foreachVar}->value['index']++;\n"; } if (isset($namedAttr['first'])) { - if (isset($namedAttr['index'])) { - $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['first'] = \$_smarty_tpl->tpl_vars[$foreachVar]->value['index'] == 0;\n"; - } else { - $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['first'] = \$_smarty_tpl->tpl_vars[$foreachVar]->value['iteration'] == 1;\n"; - } + $output .= "{$foreachVar}->value['first'] = {$local}first;\n"; } if (isset($namedAttr['last'])) { - if (isset($namedAttr['index'])) { - $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['last'] = \$_smarty_tpl->tpl_vars[$foreachVar]->value['index'] + 1 == \$_smarty_tpl->tpl_vars[$foreachVar]->value['total'];\n"; - } else { - $output .= "\$_smarty_tpl->tpl_vars[$foreachVar]->value['last'] = \$_smarty_tpl->tpl_vars[$foreachVar]->value['iteration'] == \$_smarty_tpl->tpl_vars[$foreachVar]->value['total'];\n"; - } + $output .= "{$foreachVar}->value['last'] = {$local}iteration == {$local}total;\n"; + } + if (isset($namedAttr['first']) || isset($itemAttr['first'])) { + $output .= "{$local}first = false;\n"; } } - $output .= "\$foreach_{$attributes['no']}_sav['item'] = \$_smarty_tpl->tpl_vars['{$item}'];\n"; + $output .= "{$local}saved_local_item = {$itemVar};\n"; $output .= "?>"; return $output; @@ -296,12 +288,12 @@ class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase // check and get attributes $_attr = $this->getAttributes($compiler, $args); - list($openTag, $nocache, $attributes, $foo) = $this->closeTag($compiler, array('foreach')); - $this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $attributes, false)); + list($openTag, $nocache, $local, $restoreVars, $itemVar, $foo) = $this->closeTag($compiler, array('foreach')); + $this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $local, $restoreVars, $itemVar, false)); $output = "tpl_vars['{$attributes['item']}'] = \$foreach_{$attributes['no']}_sav['item'];\n"; + $output .= "{$itemVar} = {$local}saved_local_item;\n"; $output .= "}\n"; - $output .= "if (!\$_smarty_tpl->tpl_vars['{$attributes['item']}']->_loop) {\n?>"; + $output .= "} else {\n?>"; return $output; } } @@ -332,24 +324,17 @@ class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase $compiler->tag_nocache = true; } - list($openTag, $compiler->nocache, $attributes, $restore) = $this->closeTag($compiler, array('foreach', - 'foreachelse')); + list($openTag, $compiler->nocache, $local, $restoreVars, $itemVar, $restore) = $this->closeTag($compiler, array('foreach', + 'foreachelse')); $output = "tpl_vars['{$attributes['item']}'] = \$foreach_{$attributes['no']}_sav['item'];\n"; + $output .= "{$itemVar} = {$local}saved_local_item;\n"; + $output .= "}\n"; } $output .= "}\n"; - foreach (array('item', 'key') as $a) { - if (isset($attributes[$a])) { - $output .= "if (\$foreach_{$attributes['no']}_sav['s_{$a}']) {\n"; - $output .= "\$_smarty_tpl->tpl_vars['{$attributes[$a]}'] = \$foreach_{$attributes['no']}_sav['s_{$a}'];\n"; - $output .= "}\n"; - } - } - if (isset($attributes['name'])) { - $output .= "if (\$foreach_{$attributes['no']}_sav['s_name']) {\n"; - $output .= "\$_smarty_tpl->tpl_vars['__foreach_{$attributes['name']}'] = \$foreach_{$attributes['no']}_sav['s_name'];\n"; - $output .= "}\n"; + foreach ($restoreVars as $restore) { + $output .= $restore; } $output .= "?>"; diff --git a/libs/sysplugins/smarty_internal_compile_private_foreachsection.php b/libs/sysplugins/smarty_internal_compile_private_foreachsection.php index 4492d982..6f2710c8 100644 --- a/libs/sysplugins/smarty_internal_compile_private_foreachsection.php +++ b/libs/sysplugins/smarty_internal_compile_private_foreachsection.php @@ -232,7 +232,7 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com ) { $compiler->trigger_template_error("missing or illegal \$smarty.{$tag} property attribute", $compiler->lex->taglineno); } - $tagVar = "'__{$tag}_{$name}'"; + $tagVar = "'__smarty_{$tag}_{$name}'"; return "(isset(\$_smarty_tpl->tpl_vars[{$tagVar}]->value['{$property}']) ? \$_smarty_tpl->tpl_vars[{$tagVar}]->value['{$property}'] : null)"; } } \ No newline at end of file diff --git a/libs/sysplugins/smarty_internal_compile_section.php b/libs/sysplugins/smarty_internal_compile_section.php index 6f099a79..2a11a9ed 100644 --- a/libs/sysplugins/smarty_internal_compile_section.php +++ b/libs/sysplugins/smarty_internal_compile_section.php @@ -79,12 +79,13 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo /** * Compiles code for the {section} tag * - * @param array $args array with attributes from parser - * @param object $compiler compiler object + * @param array $args array with attributes from parser + * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object * * @return string compiled code + * @throws \SmartyCompilerException */ - public function compile($args, $compiler) + public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler) { // check and get attributes $_attr = $this->getAttributes($compiler, $args); @@ -95,19 +96,18 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo $compiler->trigger_template_error("'{$a}' attribute/variable has illegal value", $compiler->lex->taglineno); } } - $attributes['no'] = $this->counter ++ . '_' . $attributes['name']; - - $this->openTag($compiler, 'section', array('section', $compiler->nocache, $attributes)); + $local = "\$__section_{$attributes['name']}_" . $this->counter ++ . '_'; + $sectionVar = "\$_smarty_tpl->tpl_vars['__smarty_section_{$attributes['name']}']"; + $this->openTag($compiler, 'section', array('section', $compiler->nocache, $local, $sectionVar)); // maybe nocache because of nocache variables $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; - $sectionVar = "\$_smarty_tpl->tpl_vars['__section_{$attributes['name']}']->value"; - $local = "\$section_{$attributes['no']}_"; - $initLocal = array('saved' => "isset(\$_smarty_tpl->tpl_vars['__section_{$attributes['name']}']) ? \$_smarty_tpl->tpl_vars['__section_{$attributes['name']}'] : false",); + + $initLocal = array('saved' => "isset(\$_smarty_tpl->tpl_vars['__smarty_section_{$attributes['name']}']) ? \$_smarty_tpl->tpl_vars['__section_{$attributes['name']}'] : false",); $initNamedProperty = array(); $initFor = array(); $incFor = array(); $cmpFor = array(); - $propValue = array('index' => "{$sectionVar}['index']", 'show' => 'true', 'step' => 1, + $propValue = array('index' => "{$sectionVar}->value['index']", 'show' => 'true', 'step' => 1, 'iteration' => "{$local}iteration", ); @@ -132,7 +132,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo if (isset($namedAttr['loop'])) { $initNamedProperty['loop'] = "'loop' => {$v}"; if ($t == 1) { - $v = "{$sectionVar}['loop']"; + $v = "{$sectionVar}->value['loop']"; } } elseif ($t == 1) { $initLocal['loop'] = $v; @@ -182,21 +182,21 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo $initNamedProperty['step'] = $propValue['step']; } if (isset($namedAttr['iteration'])) { - $propValue['iteration'] = "{$sectionVar}['iteration']"; + $propValue['iteration'] = "{$sectionVar}->value['iteration']"; } $incFor['iteration'] = "{$propValue['iteration']}++"; $initFor['iteration'] = "{$propValue['iteration']} = 1"; if ($propType['step'] == 0) { if ($propValue['step'] == 1) { - $incFor['index'] = "{$sectionVar}['index']++"; + $incFor['index'] = "{$sectionVar}->value['index']++"; } elseif ($propValue['step'] > 1) { - $incFor['index'] = "{$sectionVar}['index'] += {$propValue['step']}"; + $incFor['index'] = "{$sectionVar}->value['index'] += {$propValue['step']}"; } else { - $incFor['index'] = "{$sectionVar}['index'] -= " . - $propValue['step']; + $incFor['index'] = "{$sectionVar}->value['index'] -= " . - $propValue['step']; } } else { - $incFor['index'] = "{$sectionVar}['index'] += {$propValue['step']}"; + $incFor['index'] = "{$sectionVar}->value['index'] += {$propValue['step']}"; } if (!isset($propValue['max'])) { @@ -278,7 +278,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo $propValue['start'] = "{$local}start"; } - $initFor['index'] = "{$sectionVar}['index'] = {$propValue['start']}"; + $initFor['index'] = "{$sectionVar}->value['index'] = {$propValue['start']}"; if (!isset($_attr['start']) && !isset($_attr['step']) && !isset($_attr['max'])) { $propValue['total'] = $propValue['loop']; @@ -287,7 +287,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo $propType['total'] = $propType['start'] + $propType['loop'] + $propType['step'] + $propType['max']; if ($propType['total'] == 0) { $propValue['total'] = min(ceil(($propValue['step'] > 0 ? $propValue['loop'] - - $propValue['start'] : $propValue['start'] + 1) / + $propValue['start'] : (int) $propValue['start'] + 1) / abs($propValue['step'])), $propValue['max']); } else { $total_code = array(1 => 'min(', 2 => 'ceil(', 3 => '(', 4 => "{$propValue['step']} > 0 ? ", @@ -302,7 +302,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo $total_code[6] = $total_code[7] = ''; } if ($propType['start'] == 0) { - $total_code[9] = $propValue['start'] + 1; + $total_code[9] = (int) $propValue['start'] + 1; $total_code[10] = ''; } if ($propType['step'] == 0) { @@ -326,7 +326,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo if (isset($namedAttr['total'])) { $initNamedProperty['total'] = "'total' => {$propValue['total']}"; if ($propType['total'] > 0) { - $propValue['total'] = "{$sectionVar}['total']"; + $propValue['total'] = "{$sectionVar}->value['total']"; } } elseif ($propType['total'] > 0) { $initLocal['total'] = $propValue['total']; @@ -340,7 +340,7 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo } $_vars = 'array(' . join(', ', $initNamedProperty) . ')'; - $output .= "\$_smarty_tpl->tpl_vars['__section_{$attributes['name']}'] = new Smarty_Variable({$_vars});\n"; + $output .= "{$sectionVar} = new Smarty_Variable({$_vars});\n"; $cond_code = "{$propValue['total']} != 0"; if ($propType['total'] == 0) { if ($propValue['total'] == 0) { @@ -362,49 +362,24 @@ class Smarty_Internal_Compile_Section extends Smarty_Internal_Compile_Private_Fo $jinc = join(', ', $incFor); $output .= "for ({$jinit}; {$jcmp}; {$jinc}){\n"; if (isset($namedAttr['rownum'])) { - $output .= "{$sectionVar}['rownum'] = {$propValue['iteration']};\n"; + $output .= "{$sectionVar}->value['rownum'] = {$propValue['iteration']};\n"; } if (isset($namedAttr['index_prev'])) { - $output .= "{$sectionVar}['index_prev'] = {$propValue['index']} - {$propValue['step']};\n"; + $output .= "{$sectionVar}->value['index_prev'] = {$propValue['index']} - {$propValue['step']};\n"; } if (isset($namedAttr['index_next'])) { - $output .= "{$sectionVar}['index_next'] = {$propValue['index']} + {$propValue['step']};\n"; + $output .= "{$sectionVar}->value['index_next'] = {$propValue['index']} + {$propValue['step']};\n"; } if (isset($namedAttr['first'])) { - $output .= "{$sectionVar}['first'] = ({$propValue['iteration']} == 1);\n"; + $output .= "{$sectionVar}->value['first'] = ({$propValue['iteration']} == 1);\n"; } if (isset($namedAttr['last'])) { - $output .= "{$sectionVar}['last'] = ({$propValue['iteration']} == {$propValue['total']});\n"; + $output .= "{$sectionVar}->value['last'] = ({$propValue['iteration']} == {$propValue['total']});\n"; } $output .= "?>"; return $output; } - - /** - * Compiles code for the {$smarty.section} tag - * - * @param array $args array with attributes from parser - * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object - * @param array $parameter array with compilation parameter - * - * @return string compiled code - * @throws \SmartyCompilerException - */ - public static function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter) - { - if (!isset($parameter[1]) || false === $name = $compiler->getId($parameter[1])) { - $compiler->trigger_template_error("missing or illegal \$Smarty.section name attribute", $compiler->lex->taglineno); - } - if ((!isset($parameter[2]) || false === $property = $compiler->getId($parameter[2])) || - !in_array(strtolower($property), array('first', 'last', 'index', 'iteration', 'show', 'total')) - ) { - $compiler->trigger_template_error("missing or illegal \$Smarty.section property attribute", $compiler->lex->taglineno); - } - $property = strtolower($property); - $sectionVar = "'__section_{$name}'"; - return "(isset(\$_smarty_tpl->tpl_vars[{$sectionVar}]->value['{$property}']) ? \$_smarty_tpl->tpl_vars[{$sectionVar}]->value['{$property}'] : null)"; - } } /** @@ -418,18 +393,18 @@ class Smarty_Internal_Compile_Sectionelse extends Smarty_Internal_CompileBase /** * Compiles code for the {sectionelse} tag * - * @param array $args array with attributes from parser - * @param object $compiler compiler object + * @param array $args array with attributes from parser + * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object * * @return string compiled code */ - public function compile($args, $compiler) + public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler) { // check and get attributes $_attr = $this->getAttributes($compiler, $args); - list($openTag, $nocache, $attributes) = $this->closeTag($compiler, array('section')); - $this->openTag($compiler, 'sectionelse', array('sectionelse', $nocache, $attributes)); + list($openTag, $nocache, $local, $sectionVar) = $this->closeTag($compiler, array('section')); + $this->openTag($compiler, 'sectionelse', array('sectionelse', $nocache, $local, $sectionVar)); return ""; } @@ -446,12 +421,12 @@ class Smarty_Internal_Compile_Sectionclose extends Smarty_Internal_CompileBase /** * Compiles code for the {/section} tag * - * @param array $args array with attributes from parser - * @param object $compiler compiler object + * @param array $args array with attributes from parser + * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object * * @return string compiled code */ - public function compile($args, $compiler) + public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler) { // check and get attributes $_attr = $this->getAttributes($compiler, $args); @@ -461,7 +436,8 @@ class Smarty_Internal_Compile_Sectionclose extends Smarty_Internal_CompileBase $compiler->tag_nocache = true; } - list($openTag, $compiler->nocache, $attributes) = $this->closeTag($compiler, array('section', 'sectionelse')); + list($openTag, $compiler->nocache, $local, $sectionVar) = $this->closeTag($compiler, array('section', + 'sectionelse')); $output = "tpl_vars['__section_{$attributes['name']}'] = \$section_{$attributes['no']}_saved;\n"; + $output .= "if ({$local}saved) {\n"; + $output .= "{$sectionVar} = {$local}saved;\n"; $output .= "}\n"; $output .= "?>";