From 9651dafbce1db76211fe73894014121cb8574cf9 Mon Sep 17 00:00:00 2001 From: Simon Wisselink Date: Tue, 10 Jan 2023 14:46:33 +0100 Subject: [PATCH] WIP replacing direct access tpl_vars with proper getter/setters. --- src/Compile/Tag/Assign.php | 2 +- src/Compile/Tag/ForeachTag.php | 22 ++++++- src/Compiler/Template.php | 16 +---- src/Data.php | 9 +++ src/Parser/TemplateParser.y | 16 ++++- src/Smarty.php | 2 +- src/TemplateBase.php | 2 +- src/Variable.php | 59 +++++++++++++++++++ .../TagTests/If/CompileIfTest.php | 2 +- 9 files changed, 105 insertions(+), 25 deletions(-) diff --git a/src/Compile/Tag/Assign.php b/src/Compile/Tag/Assign.php index 997eaa79..02589063 100644 --- a/src/Compile/Tag/Assign.php +++ b/src/Compile/Tag/Assign.php @@ -88,7 +88,7 @@ class Assign extends Base } if (isset($parameter[ 'smarty_internal_index' ])) { $output = - "tpl_vars[{$_var}]) ? \$_smarty_tpl->tpl_vars[{$_var}]->value : array();\n"; + "getValue({$_var}) ?? [];\n"; $output .= "if (!(is_array(\$_tmp_array) || \$_tmp_array instanceof ArrayAccess)) {\n"; $output .= "settype(\$_tmp_array, 'array');\n"; $output .= "}\n"; diff --git a/src/Compile/Tag/ForeachTag.php b/src/Compile/Tag/ForeachTag.php index 19efdc3a..335fd2b2 100644 --- a/src/Compile/Tag/ForeachTag.php +++ b/src/Compile/Tag/ForeachTag.php @@ -88,14 +88,14 @@ class ForeachTag extends ForeachSection { $from = $_attr['from']; $item = $compiler->getId($_attr['item']); if ($item === false) { - $item = $compiler->getVariableName($_attr['item']); + $item = $this->getVariableName($_attr['item']); } $key = $name = null; $attributes = ['item' => $item]; if (isset($_attr['key'])) { $key = $compiler->getId($_attr['key']); if ($key === false) { - $key = $compiler->getVariableName($_attr['key']); + $key = $this->getVariableName($_attr['key']); } $attributes['key'] = $key; } @@ -108,7 +108,7 @@ class ForeachTag extends ForeachSection { $compiler->trigger_template_error("'{$a}' attribute/variable has illegal value", null, true); } } - $fromName = $compiler->getVariableName($_attr['from']); + $fromName = $this->getVariableName($_attr['from']); if ($fromName) { foreach (['item', 'key'] as $a) { if (isset($attributes[$a]) && $attributes[$a] === $fromName) { @@ -251,6 +251,22 @@ class ForeachTag extends ForeachSection { return $output; } + /** + * Get variable name from string + * + * @param string $input + * + * @return bool|string + * + * @TODO: this may no longer work if we add a getter for tpl_vars, recheck this! + */ + private function getVariableName($input) { + if (preg_match('~^[$]_smarty_tpl->tpl_vars\[[\'"]*([0-9]*[a-zA-Z_]\w*)[\'"]*\]->value$~', $input, $match)) { + return $match[1]; + } + return false; + } + /** * Compiles code for to restore saved template variables * diff --git a/src/Compiler/Template.php b/src/Compiler/Template.php index 964ca812..50a35187 100644 --- a/src/Compiler/Template.php +++ b/src/Compiler/Template.php @@ -514,7 +514,7 @@ class Template extends BaseCompiler { false )->nocache; } - return '$_smarty_tpl->tpl_vars[' . $variable . ']->value'; + return '$_smarty_tpl->getValue(' . $variable . ')'; } /** @@ -758,20 +758,6 @@ class Template extends BaseCompiler { return false; } - /** - * Get variable name from string - * - * @param string $input - * - * @return bool|string - */ - public function getVariableName($input) { - if (preg_match('~^[$]_smarty_tpl->tpl_vars\[[\'"]*([0-9]*[a-zA-Z_]\w*)[\'"]*\]->value$~', $input, $match)) { - return $match[1]; - } - return false; - } - /** * Set nocache flag in variable or create new variable * diff --git a/src/Data.php b/src/Data.php index cd98dcc4..3e750bc0 100644 --- a/src/Data.php +++ b/src/Data.php @@ -304,6 +304,15 @@ abstract class Data return new UndefinedVariable; } + /** + * Returns the value of the Smarty\Variable given by $varName, or null if the variable does not exist. + * @return mixed|null + */ + public function getValue($varName) { + $variable = $this->_getVariable($varName); + return isset($variable) ? $variable->getValue() : null; + } + /** * Follow the parent chain an merge template and config variables * diff --git a/src/Parser/TemplateParser.y b/src/Parser/TemplateParser.y index b5c58c14..605a84b7 100644 --- a/src/Parser/TemplateParser.y +++ b/src/Parser/TemplateParser.y @@ -199,7 +199,7 @@ class TemplateParser * * @return Tag */ - public function mergePrefixCode($code) + private function mergePrefixCode($code) { $tmp = ''; foreach ($this->compiler->prefix_code as $preCode) { @@ -626,6 +626,16 @@ expr(res) ::= ternary(v). { res = v; } + // ++$a / --$a +expr(res) ::= INCDEC(i2) DOLLARID(i). { + res = '$_smarty_tpl->_getVariable(\''. substr(i,1) .'\')->preIncDec(\'' . i2 . '\')'; +} + + // $a++ / $a-- +expr(res) ::= DOLLARID(i) INCDEC(i2). { + res = '$_smarty_tpl->_getVariable(\''. substr(i,1) .'\')->postIncDec(\'' . i2 . '\')'; +} + // resources/streams expr(res) ::= DOLLARID(i) COLON ID(i2). { res = '$_smarty_tpl->getStreamVariable(\''.substr(i,1).'://' . i2 . '\')'; @@ -839,7 +849,7 @@ variable(res) ::= varindexed(vi). { // variable with property variable(res) ::= varvar(v) AT ID(p). { - res = '$_smarty_tpl->tpl_vars['. v .']->'.p; + res = '$_smarty_tpl->_getVariable('. v .')->'.p; } // object @@ -1260,7 +1270,7 @@ doublequotedcontent(res) ::= BACKTICK expr(e) BACKTICK. { } doublequotedcontent(res) ::= DOLLARID(i). { - res = new Code('(string)$_smarty_tpl->tpl_vars[\''. substr(i,1) .'\']->value'); + res = new Code('(string)$_smarty_tpl->getValue(\''. substr(i,1) .'\')'); } doublequotedcontent(res) ::= LDEL variable(v) RDEL. { diff --git a/src/Smarty.php b/src/Smarty.php index d5554ae1..f241ae33 100644 --- a/src/Smarty.php +++ b/src/Smarty.php @@ -1017,7 +1017,7 @@ class Smarty extends \Smarty\TemplateBase $tpl = new \Smarty\Template($template, $this, null, $cache_id, $compile_id, null, null); $tpl->templateId = $_templateId; - $tpl->parent = $parent ? $parent : $this; + $tpl->parent = $parent ?: $this; // fill data if present if (!empty($data) && is_array($data)) { // set up variable values diff --git a/src/TemplateBase.php b/src/TemplateBase.php index 10fde43b..6bada619 100644 --- a/src/TemplateBase.php +++ b/src/TemplateBase.php @@ -159,7 +159,7 @@ abstract class TemplateBase extends Data { } else { // get template object $saveVars = false; - $template = $smarty->createTemplate($template, $cache_id, $compile_id, $parent ? $parent : $this, false); + $template = $smarty->createTemplate($template, $cache_id, $compile_id, $parent ?: $this, false); if ($this->_objType === 1) { // set caching in template object $template->caching = $this->caching; diff --git a/src/Variable.php b/src/Variable.php index b5fabd47..bd66b872 100644 --- a/src/Variable.php +++ b/src/Variable.php @@ -19,6 +19,13 @@ class Variable */ public $value = null; + /** + * @param mixed|null $value + */ + public function setValue($value): void { + $this->value = $value; + } + /** * if true any output of this variable will be not cached * @@ -26,6 +33,13 @@ class Variable */ public $nocache = false; + /** + * @param bool $nocache + */ + public function setNocache(bool $nocache): void { + $this->nocache = $nocache; + } + /** * create Smarty variable object * @@ -51,4 +65,49 @@ class Variable { return (string)$this->value; } + + /** + * Handles ++$a and --$a in templates. + * + * @param $operator '++' or '--', defaults to '++' + * + * @return int|mixed + * @throws Exception + */ + public function preIncDec($operator = '++') { + if ($operator == '--') { + return --$this->value; + } elseif ($operator == '++') { + return ++$this->value; + } else { + throw new Exception("Invalid incdec operator. Use '--' or '++'."); + } + return $this->value; + } + + /** + * Handles $a++ and $a-- in templates. + * + * @param $operator '++' or '--', defaults to '++' + * + * @return int|mixed + * @throws Exception + */ + public function postIncDec($operator = '++') { + if ($operator == '--') { + return $this->value--; + } elseif ($operator == '++') { + return $this->value++; + } else { + throw new Exception("Invalid incdec operator. Use '--' or '++'."); + } + } + + /** + * @return bool + */ + public function isNocache(): bool { + return $this->nocache; + } + } diff --git a/tests/UnitTests/TemplateSource/TagTests/If/CompileIfTest.php b/tests/UnitTests/TemplateSource/TagTests/If/CompileIfTest.php index 9a4dd184..9d4debde 100644 --- a/tests/UnitTests/TemplateSource/TagTests/If/CompileIfTest.php +++ b/tests/UnitTests/TemplateSource/TagTests/If/CompileIfTest.php @@ -165,7 +165,7 @@ class CompileIfTest extends PHPUnit_Smarty $this->smarty->assign($var, $value, true); $this->smarty->assign($var . '2', $value); $this->assertEquals($result, $this->strip($this->smarty->fetch('run_code_caching.tpl')), - "testIfNocahe - {$code} - {$testName}"); + "testIfNocache - {$code} - {$testName}"); } /*