From fd369a7115cc350bfac75950f4de527311e8cc9c Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Thu, 26 Dec 2024 17:59:29 +0900 Subject: [PATCH] Smarty Update to v5.4.3 --- ReadMe.md | 24 +- src/BlockHandler/BlockPluginWrapper.php | 2 +- src/Cacheresource/Base.php | 2 +- src/Cacheresource/Custom.php | 2 +- src/Cacheresource/File.php | 2 +- src/Cacheresource/KeyValueStore.php | 2 +- src/Compiler/CodeFrame.php | 2 +- src/Compiler/Template.php | 14 +- src/CompilerException.php | 4 +- src/Extension/CallbackWrapper.php | 2 +- src/FunctionHandler/HtmlBase.php | 6 +- src/Parser/TemplateParser.php | 1912 +++++++++-------- src/Parser/TemplateParser.y | 140 +- src/Resource/BasePlugin.php | 2 +- src/Resource/CustomPlugin.php | 2 +- src/Resource/ExtendsPlugin.php | 8 +- src/Resource/FilePlugin.php | 2 +- src/Resource/StreamPlugin.php | 2 +- src/Resource/StringPlugin.php | 2 +- src/Runtime/DefaultPluginHandlerRuntime.php | 4 +- src/Runtime/InheritanceRuntime.php | 2 +- src/Smarty.php | 2 +- src/Template.php | 6 +- src/Template/Source.php | 8 +- src/TemplateBase.php | 2 +- update/ReadMe.md | 15 + update/src/BlockHandler/T.php | 238 ++ update/src/Extensions/DefaultExtension.php | 760 +++++++ update/src/FunctionHandler/HtmlCheckboxes.php | 198 ++ update/src/FunctionHandler/HtmlOptions.php | 236 ++ update/src/FunctionHandler/Popup.php | 123 ++ update/src/FunctionHandler/PopupInit.php | 36 + 32 files changed, 2785 insertions(+), 977 deletions(-) create mode 100644 update/ReadMe.md create mode 100644 update/src/BlockHandler/T.php create mode 100644 update/src/Extensions/DefaultExtension.php create mode 100644 update/src/FunctionHandler/HtmlCheckboxes.php create mode 100644 update/src/FunctionHandler/HtmlOptions.php create mode 100644 update/src/FunctionHandler/Popup.php create mode 100644 update/src/FunctionHandler/PopupInit.php diff --git a/ReadMe.md b/ReadMe.md index 29ba133..7882e28 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -33,17 +33,19 @@ Alternative setup composer local zip file repot: 1) Located in `Smarty/Smarty-Composer/vendor/smarty/smarty/src/` 2) Alternative is to checkout master branch from git 1) Located in `Smarty/Smarty-git/src/` -3) copy over the following into `src/BlockHandler/`: - 1) T.php -4) copy over the following into `src/FunctionHandler`: - 1) Popup.php - 2) PopupInit.php -5) Upate the global `src/Extensions/DefaultExtension.php`: - 1) `getFunctionHandler`: popup_init, popup - 2) `getBlockHandler`: t -6) check either `src/FunctionHander/HtmlCheckboxes.php` and `src/FunctionHander/HtmlOptions.php` have changed - 1) Update and leep the label/pos changes -7) Create new release version as official relase number +3) Copy the `src/` folder as is over the `Smarty/Smarty-Extended/src` folder +4) From the `update/` folder copy + 1) copy over the following into `src/BlockHandler/`: + 1) T.php + 2) copy over the following into `src/FunctionHandler`: + 1) Popup.php + 2) PopupInit.php + 3) Upate the global `src/Extensions/DefaultExtension.php`: + 1) `getFunctionHandler`: popup_init, popup + 2) `getBlockHandler`: t + 4) check either `src/FunctionHander/HtmlCheckboxes.php` and `src/FunctionHander/HtmlOptions.php` have changed + 1) Update and leep the label/pos changes +5) Create new release version as official relase number ## Updated files (different from master) diff --git a/src/BlockHandler/BlockPluginWrapper.php b/src/BlockHandler/BlockPluginWrapper.php index 4700594..b6236a6 100644 --- a/src/BlockHandler/BlockPluginWrapper.php +++ b/src/BlockHandler/BlockPluginWrapper.php @@ -14,6 +14,6 @@ class BlockPluginWrapper extends Base { } public function handle($params, $content, Template $template, &$repeat) { - return call_user_func_array($this->callback, [$params, $content, &$template, &$repeat]); + return \call_user_func_array($this->callback, [$params, $content, &$template, &$repeat]); } } \ No newline at end of file diff --git a/src/Cacheresource/Base.php b/src/Cacheresource/Base.php index 54a1419..41c4f6b 100644 --- a/src/Cacheresource/Base.php +++ b/src/Cacheresource/Base.php @@ -44,7 +44,7 @@ abstract class Base */ abstract public function process( Template $_template, - Cached $cached = null, + ?Cached $cached = null, $update = false ); diff --git a/src/Cacheresource/Custom.php b/src/Cacheresource/Custom.php index c049246..f9eb858 100644 --- a/src/Cacheresource/Custom.php +++ b/src/Cacheresource/Custom.php @@ -139,7 +139,7 @@ abstract class Custom extends Base */ public function process( Template $_smarty_tpl, - \Smarty\Template\Cached $cached = null, + ?\Smarty\Template\Cached $cached = null, $update = false ) { if (!$cached) { diff --git a/src/Cacheresource/File.php b/src/Cacheresource/File.php index 538f010..4b4198e 100644 --- a/src/Cacheresource/File.php +++ b/src/Cacheresource/File.php @@ -99,7 +99,7 @@ class File extends Base */ public function process( Template $_smarty_tpl, - Cached $cached = null, + ?Cached $cached = null, $update = false ) { $_smarty_tpl->getCached()->setValid(false); diff --git a/src/Cacheresource/KeyValueStore.php b/src/Cacheresource/KeyValueStore.php index 733d277..1953bb2 100644 --- a/src/Cacheresource/KeyValueStore.php +++ b/src/Cacheresource/KeyValueStore.php @@ -103,7 +103,7 @@ abstract class KeyValueStore extends Base */ public function process( Template $_smarty_tpl, - Cached $cached = null, + ?Cached $cached = null, $update = false ) { if (!$cached) { diff --git a/src/Compiler/CodeFrame.php b/src/Compiler/CodeFrame.php index 5e78215..d0e1cc1 100644 --- a/src/Compiler/CodeFrame.php +++ b/src/Compiler/CodeFrame.php @@ -41,7 +41,7 @@ class CodeFrame $content = '', $functions = '', $cache = false, - \Smarty\Compiler\Template $compiler = null + ?\Smarty\Compiler\Template $compiler = null ) { // build property code $properties[ 'version' ] = \Smarty\Smarty::SMARTY_VERSION; diff --git a/src/Compiler/Template.php b/src/Compiler/Template.php index 9b2c1a1..237407c 100644 --- a/src/Compiler/Template.php +++ b/src/Compiler/Template.php @@ -374,7 +374,7 @@ class Template extends BaseCompiler { * @throws CompilerException * @throws Exception */ - public function compileTemplateSource(\Smarty\Template $template, \Smarty\Compiler\Template $parent_compiler = null) { + public function compileTemplateSource(\Smarty\Template $template, ?\Smarty\Compiler\Template $parent_compiler = null) { try { // save template object in compiler class $this->template = $template; @@ -505,7 +505,7 @@ class Template extends BaseCompiler { * * @return string */ - public function compileVariable($variable) { + public function triggerTagNoCache($variable): void { if (!strpos($variable, '(')) { // not a variable variable $var = trim($variable, '\''); @@ -516,7 +516,6 @@ class Template extends BaseCompiler { false )->isNocache(); } - return '$_smarty_tpl->getValue(' . $variable . ')'; } /** @@ -665,7 +664,7 @@ class Template extends BaseCompiler { $script = null; $cacheable = true; - $result = call_user_func_array( + $result = \call_user_func_array( $defaultPluginHandlerFunc, [ $tag, @@ -1281,9 +1280,10 @@ class Template extends BaseCompiler { } // call post compile callbacks foreach ($this->postCompileCallbacks as $cb) { - $parameter = $cb; - $parameter[0] = $this; - call_user_func_array($cb[0], $parameter); + $callbackFunction = $cb[0]; + $parameters = $cb; + $parameters[0] = $this; + $callbackFunction(...$parameters); } // return compiled code return $this->prefixCompiledCode . $this->parser->retvalue . $this->postfixCompiledCode; diff --git a/src/CompilerException.php b/src/CompilerException.php index e3d67b4..60af9db 100644 --- a/src/CompilerException.php +++ b/src/CompilerException.php @@ -16,14 +16,14 @@ class CompilerException extends Exception { * @param int $code The Exception code. * @param string|null $filename The filename where the exception is thrown. * @param int|null $line The line number where the exception is thrown. - * @param Throwable|null $previous The previous exception used for the exception chaining. + * @param \Throwable|null $previous The previous exception used for the exception chaining. */ public function __construct( string $message = "", int $code = 0, ?string $filename = null, ?int $line = null, - Throwable $previous = null + ?\Throwable $previous = null ) { parent::__construct($message, $code, $previous); diff --git a/src/Extension/CallbackWrapper.php b/src/Extension/CallbackWrapper.php index 827dd78..193fc13 100644 --- a/src/Extension/CallbackWrapper.php +++ b/src/Extension/CallbackWrapper.php @@ -26,7 +26,7 @@ class CallbackWrapper { public function handle(...$params) { try { - return call_user_func_array($this->callback, $params); + return ($this->callback)(...$params); } catch (\ArgumentCountError $e) { throw new Exception("Invalid number of arguments to modifier " . $this->modifierName); } diff --git a/src/FunctionHandler/HtmlBase.php b/src/FunctionHandler/HtmlBase.php index f321b84..99f8e6c 100644 --- a/src/FunctionHandler/HtmlBase.php +++ b/src/FunctionHandler/HtmlBase.php @@ -15,7 +15,6 @@ class HtmlBase extends Base { * @param $separator * @param $labels * @param $label_ids - * @param $pos * @param bool $escape * * @return string @@ -31,7 +30,6 @@ class HtmlBase extends Base { $separator, $labels, $label_ids, - $pos, $escape = true ) { @@ -85,7 +83,7 @@ class HtmlBase extends Base { } $_output .= ' 74, 1 => 3 ), array( 0 => 91, 1 => 1 ), array( 0 => 91, 1 => 1 ), + array( 0 => 95, 1 => 3 ), + array( 0 => 95, 1 => 3 ), + array( 0 => 95, 1 => 1 ), + array( 0 => 95, 1 => 1 ), + array( 0 => 95, 1 => 0 ), + array( 0 => 96, 1 => 1 ), + array( 0 => 96, 1 => 1 ), + array( 0 => 96, 1 => 3 ), + array( 0 => 96, 1 => 1 ), + array( 0 => 98, 1 => 3 ), + array( 0 => 98, 1 => 4 ), + array( 0 => 98, 1 => 3 ), + array( 0 => 98, 1 => 4 ), array( 0 => 73, 1 => 1 ), array( 0 => 73, 1 => 1 ), - array( 0 => 73, 1 => 3 ), - array( 0 => 73, 1 => 1 ), - array( 0 => 73, 1 => 3 ), - array( 0 => 73, 1 => 4 ), - array( 0 => 73, 1 => 3 ), - array( 0 => 73, 1 => 4 ), array( 0 => 70, 1 => 2 ), array( 0 => 70, 1 => 2 ), - array( 0 => 96, 1 => 2 ), - array( 0 => 96, 1 => 0 ), - array( 0 => 97, 1 => 2 ), - array( 0 => 97, 1 => 2 ), - array( 0 => 97, 1 => 4 ), - array( 0 => 97, 1 => 2 ), - array( 0 => 97, 1 => 2 ), - array( 0 => 97, 1 => 4 ), - array( 0 => 97, 1 => 3 ), - array( 0 => 97, 1 => 5 ), - array( 0 => 97, 1 => 3 ), - array( 0 => 97, 1 => 3 ), - array( 0 => 97, 1 => 3 ), - array( 0 => 97, 1 => 3 ), - array( 0 => 97, 1 => 3 ), - array( 0 => 97, 1 => 3 ), - array( 0 => 97, 1 => 2 ), + array( 0 => 99, 1 => 2 ), + array( 0 => 99, 1 => 0 ), + array( 0 => 100, 1 => 2 ), + array( 0 => 100, 1 => 2 ), + array( 0 => 100, 1 => 4 ), + array( 0 => 100, 1 => 2 ), + array( 0 => 100, 1 => 2 ), + array( 0 => 100, 1 => 4 ), + array( 0 => 100, 1 => 3 ), + array( 0 => 100, 1 => 5 ), + array( 0 => 100, 1 => 3 ), + array( 0 => 100, 1 => 3 ), + array( 0 => 100, 1 => 3 ), + array( 0 => 100, 1 => 3 ), + array( 0 => 100, 1 => 3 ), + array( 0 => 100, 1 => 3 ), + array( 0 => 100, 1 => 2 ), array( 0 => 80, 1 => 1 ), array( 0 => 80, 1 => 1 ), array( 0 => 80, 1 => 2 ), - array( 0 => 98, 1 => 1 ), - array( 0 => 98, 1 => 1 ), - array( 0 => 98, 1 => 3 ), - array( 0 => 95, 1 => 2 ), - array( 0 => 99, 1 => 1 ), - array( 0 => 99, 1 => 2 ), - array( 0 => 100, 1 => 3 ), - array( 0 => 100, 1 => 3 ), - array( 0 => 100, 1 => 5 ), - array( 0 => 100, 1 => 6 ), - array( 0 => 100, 1 => 2 ), - array( 0 => 90, 1 => 4 ), - array( 0 => 101, 1 => 4 ), - array( 0 => 101, 1 => 4 ), - array( 0 => 102, 1 => 3 ), + array( 0 => 101, 1 => 1 ), + array( 0 => 101, 1 => 1 ), + array( 0 => 101, 1 => 3 ), + array( 0 => 97, 1 => 2 ), array( 0 => 102, 1 => 1 ), - array( 0 => 102, 1 => 0 ), + array( 0 => 102, 1 => 2 ), + array( 0 => 103, 1 => 3 ), + array( 0 => 103, 1 => 3 ), + array( 0 => 103, 1 => 5 ), + array( 0 => 103, 1 => 6 ), + array( 0 => 103, 1 => 2 ), + array( 0 => 90, 1 => 4 ), + array( 0 => 104, 1 => 4 ), + array( 0 => 104, 1 => 4 ), + array( 0 => 105, 1 => 3 ), + array( 0 => 105, 1 => 1 ), + array( 0 => 105, 1 => 0 ), array( 0 => 76, 1 => 3 ), array( 0 => 76, 1 => 2 ), - array( 0 => 103, 1 => 3 ), - array( 0 => 103, 1 => 2 ), + array( 0 => 106, 1 => 3 ), + array( 0 => 106, 1 => 2 ), array( 0 => 81, 1 => 2 ), array( 0 => 81, 1 => 0 ), - array( 0 => 104, 1 => 2 ), - array( 0 => 104, 1 => 3 ), - array( 0 => 104, 1 => 2 ), + array( 0 => 107, 1 => 2 ), + array( 0 => 107, 1 => 3 ), + array( 0 => 107, 1 => 2 ), array( 0 => 93, 1 => 1 ), array( 0 => 93, 1 => 2 ), array( 0 => 93, 1 => 1 ), @@ -1916,23 +1975,23 @@ public static $yy_action = array( array( 0 => 87, 1 => 1 ), array( 0 => 94, 1 => 3 ), array( 0 => 94, 1 => 3 ), - array( 0 => 105, 1 => 1 ), - array( 0 => 105, 1 => 3 ), - array( 0 => 105, 1 => 0 ), - array( 0 => 106, 1 => 3 ), - array( 0 => 106, 1 => 3 ), - array( 0 => 106, 1 => 1 ), + array( 0 => 108, 1 => 1 ), + array( 0 => 108, 1 => 3 ), + array( 0 => 108, 1 => 0 ), + array( 0 => 109, 1 => 3 ), + array( 0 => 109, 1 => 3 ), + array( 0 => 109, 1 => 1 ), array( 0 => 92, 1 => 2 ), array( 0 => 92, 1 => 3 ), - array( 0 => 107, 1 => 2 ), - array( 0 => 107, 1 => 1 ), - array( 0 => 108, 1 => 3 ), - array( 0 => 108, 1 => 3 ), - array( 0 => 108, 1 => 1 ), - array( 0 => 108, 1 => 3 ), - array( 0 => 108, 1 => 3 ), - array( 0 => 108, 1 => 1 ), - array( 0 => 108, 1 => 1 ), + array( 0 => 110, 1 => 2 ), + array( 0 => 110, 1 => 1 ), + array( 0 => 111, 1 => 3 ), + array( 0 => 111, 1 => 3 ), + array( 0 => 111, 1 => 1 ), + array( 0 => 111, 1 => 3 ), + array( 0 => 111, 1 => 3 ), + array( 0 => 111, 1 => 1 ), + array( 0 => 111, 1 => 1 ), ); public static $yyReduceMap = array( @@ -1961,9 +2020,9 @@ public static $yy_action = array( 103 => 6, 104 => 6, 106 => 6, - 111 => 6, - 175 => 6, - 180 => 6, + 122 => 6, + 182 => 6, + 187 => 6, 7 => 7, 8 => 8, 9 => 9, @@ -2003,18 +2062,21 @@ public static $yy_action = array( 48 => 48, 49 => 49, 58 => 49, - 153 => 49, - 157 => 49, - 161 => 49, - 163 => 49, + 110 => 49, + 111 => 49, + 160 => 49, + 164 => 49, + 168 => 49, + 170 => 49, 50 => 50, - 154 => 50, - 160 => 50, + 112 => 50, + 161 => 50, + 167 => 50, 51 => 51, 52 => 52, 53 => 52, 54 => 54, - 138 => 54, + 145 => 54, 57 => 57, 59 => 59, 60 => 60, @@ -2040,7 +2102,7 @@ public static $yy_action = array( 84 => 84, 86 => 84, 87 => 84, - 118 => 84, + 125 => 84, 85 => 85, 90 => 90, 91 => 91, @@ -2055,42 +2117,40 @@ public static $yy_action = array( 105 => 105, 107 => 107, 108 => 108, - 109 => 109, - 110 => 110, - 112 => 112, + 109 => 108, + 159 => 108, 113 => 113, 114 => 114, 115 => 115, 116 => 116, 117 => 117, + 118 => 118, 119 => 119, - 177 => 119, 120 => 120, 121 => 121, - 122 => 122, 123 => 123, 124 => 124, - 125 => 125, - 133 => 125, 126 => 126, + 184 => 126, 127 => 127, 128 => 128, - 129 => 128, - 131 => 128, - 132 => 128, + 129 => 129, 130 => 130, + 131 => 131, + 132 => 132, + 140 => 132, + 133 => 133, 134 => 134, 135 => 135, - 136 => 136, - 181 => 136, + 136 => 135, + 138 => 135, + 139 => 135, 137 => 137, - 139 => 139, - 140 => 140, 141 => 141, 142 => 142, 143 => 143, + 188 => 143, 144 => 144, - 145 => 145, 146 => 146, 147 => 147, 148 => 148, @@ -2098,35 +2158,41 @@ public static $yy_action = array( 150 => 150, 151 => 151, 152 => 152, + 153 => 153, + 154 => 154, 155 => 155, 156 => 156, + 157 => 157, 158 => 158, - 159 => 159, 162 => 162, - 164 => 164, + 163 => 163, 165 => 165, 166 => 166, - 167 => 167, - 168 => 168, 169 => 169, - 170 => 170, 171 => 171, 172 => 172, 173 => 173, - 174 => 173, + 174 => 174, + 175 => 175, 176 => 176, + 177 => 177, 178 => 178, 179 => 179, - 182 => 182, + 180 => 180, + 181 => 180, 183 => 183, - 184 => 184, 185 => 185, - 188 => 185, 186 => 186, - 189 => 186, - 187 => 187, + 189 => 189, 190 => 190, 191 => 191, + 192 => 192, + 195 => 192, + 193 => 193, + 196 => 193, + 194 => 194, + 197 => 197, + 198 => 198, ); // line 245 "src/Parser/TemplateParser.y" public function yy_r0(){ @@ -2187,9 +2253,10 @@ public static $yy_action = array( $attributes[] = 'nocache'; $var = $match[1]; } - $this->_retvalue = $this->compiler->compilePrintExpression($this->compiler->compileVariable('\''.$var.'\''), $attributes); + $this->compiler->triggerTagNoCache($var); + $this->_retvalue = $this->compiler->compilePrintExpression('$_smarty_tpl->getValue(\''.$var.'\')', $attributes); } -// line 313 "src/Parser/TemplateParser.y" +// line 314 "src/Parser/TemplateParser.y" public function yy_r12(){ $tag = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength())); if ($tag == 'strip') { @@ -2210,7 +2277,7 @@ public static $yy_action = array( } } } -// line 334 "src/Parser/TemplateParser.y" +// line 335 "src/Parser/TemplateParser.y" public function yy_r13(){ $j = strrpos($this->yystack[$this->yyidx + 0]->minor,'.'); if ($this->yystack[$this->yyidx + 0]->minor[$j+1] == 'c') { @@ -2221,35 +2288,35 @@ public static $yy_action = array( $this->_retvalue = $this->compiler->compileParentBlock(); } } -// line 345 "src/Parser/TemplateParser.y" +// line 346 "src/Parser/TemplateParser.y" public function yy_r14(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; } -// line 349 "src/Parser/TemplateParser.y" +// line 350 "src/Parser/TemplateParser.y" public function yy_r15(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; } -// line 353 "src/Parser/TemplateParser.y" +// line 354 "src/Parser/TemplateParser.y" public function yy_r16(){ $this->_retvalue = $this->compiler->compilePrintExpression($this->yystack[$this->yyidx + 0]->minor[0], $this->yystack[$this->yyidx + 0]->minor[1]); } -// line 362 "src/Parser/TemplateParser.y" +// line 363 "src/Parser/TemplateParser.y" public function yy_r17(){ $this->_retvalue = $this->compiler->compileTag('assign',array_merge(array(array('value'=>$this->yystack[$this->yyidx + 0]->minor[0]),array('var'=>'\''.substr($this->yystack[$this->yyidx + -1]->minor,1).'\'')),$this->yystack[$this->yyidx + 0]->minor[1])); } -// line 366 "src/Parser/TemplateParser.y" +// line 367 "src/Parser/TemplateParser.y" public function yy_r18(){ $this->_retvalue = $this->compiler->compileTag('assign',array_merge(array(array('value'=>$this->yystack[$this->yyidx + 0]->minor[0]),array('var'=>$this->yystack[$this->yyidx + -1]->minor['var'])),$this->yystack[$this->yyidx + 0]->minor[1]),array('smarty_internal_index'=>$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index'])); } -// line 370 "src/Parser/TemplateParser.y" +// line 371 "src/Parser/TemplateParser.y" public function yy_r19(){ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; } -// line 374 "src/Parser/TemplateParser.y" +// line 375 "src/Parser/TemplateParser.y" public function yy_r20(){ $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor); } -// line 389 "src/Parser/TemplateParser.y" +// line 390 "src/Parser/TemplateParser.y" public function yy_r24(){ if (defined($this->yystack[$this->yyidx + -1]->minor)) { if ($this->security) { @@ -2260,7 +2327,7 @@ public static $yy_action = array( $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor); } } -// line 399 "src/Parser/TemplateParser.y" +// line 400 "src/Parser/TemplateParser.y" public function yy_r25(){ if (defined($this->yystack[$this->yyidx + 0]->minor)) { if ($this->security) { @@ -2271,7 +2338,7 @@ public static $yy_action = array( $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + 0]->minor,array()); } } -// line 412 "src/Parser/TemplateParser.y" +// line 413 "src/Parser/TemplateParser.y" public function yy_r26(){ if (defined($this->yystack[$this->yyidx + -2]->minor)) { if ($this->security) { @@ -2282,66 +2349,66 @@ public static $yy_action = array( $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor,$this->yystack[$this->yyidx + 0]->minor, array('modifierlist'=>$this->yystack[$this->yyidx + -1]->minor)); } } -// line 424 "src/Parser/TemplateParser.y" +// line 425 "src/Parser/TemplateParser.y" public function yy_r27(){ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor,$this->yystack[$this->yyidx + 0]->minor,array('object_method'=>$this->yystack[$this->yyidx + -1]->minor)); } -// line 429 "src/Parser/TemplateParser.y" +// line 430 "src/Parser/TemplateParser.y" public function yy_r28(){ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -4]->minor,$this->yystack[$this->yyidx + 0]->minor,array('modifierlist'=>$this->yystack[$this->yyidx + -1]->minor, 'object_method'=>$this->yystack[$this->yyidx + -2]->minor)); } -// line 434 "src/Parser/TemplateParser.y" +// line 435 "src/Parser/TemplateParser.y" public function yy_r29(){ $tag = trim(substr($this->yystack[$this->yyidx + -1]->minor,$this->compiler->getLdelLength())); $this->_retvalue = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,array(),array('if condition'=>$this->yystack[$this->yyidx + 0]->minor)); } -// line 439 "src/Parser/TemplateParser.y" +// line 440 "src/Parser/TemplateParser.y" public function yy_r30(){ $tag = trim(substr($this->yystack[$this->yyidx + -2]->minor,$this->compiler->getLdelLength())); $this->_retvalue = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,$this->yystack[$this->yyidx + 0]->minor,array('if condition'=>$this->yystack[$this->yyidx + -1]->minor)); } -// line 444 "src/Parser/TemplateParser.y" +// line 445 "src/Parser/TemplateParser.y" public function yy_r31(){ $tag = trim(substr($this->yystack[$this->yyidx + -1]->minor,$this->compiler->getLdelLength())); $this->_retvalue = $this->compiler->compileTag(($tag === 'else if')? 'elseif' : $tag,array(),array('if condition'=>$this->yystack[$this->yyidx + 0]->minor)); } -// line 455 "src/Parser/TemplateParser.y" +// line 456 "src/Parser/TemplateParser.y" public function yy_r33(){ $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('start'=>$this->yystack[$this->yyidx + -6]->minor),array('ifexp'=>$this->yystack[$this->yyidx + -4]->minor),array('var'=>$this->yystack[$this->yyidx + -2]->minor),array('step'=>$this->yystack[$this->yyidx + -1]->minor))),1); } -// line 459 "src/Parser/TemplateParser.y" +// line 460 "src/Parser/TemplateParser.y" public function yy_r34(){ $this->_retvalue = '='.$this->yystack[$this->yyidx + 0]->minor; } -// line 467 "src/Parser/TemplateParser.y" +// line 468 "src/Parser/TemplateParser.y" public function yy_r36(){ $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('start'=>$this->yystack[$this->yyidx + -3]->minor),array('to'=>$this->yystack[$this->yyidx + -1]->minor))),0); } -// line 471 "src/Parser/TemplateParser.y" +// line 472 "src/Parser/TemplateParser.y" public function yy_r37(){ $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('start'=>$this->yystack[$this->yyidx + -5]->minor),array('to'=>$this->yystack[$this->yyidx + -3]->minor),array('step'=>$this->yystack[$this->yyidx + -1]->minor))),0); } -// line 476 "src/Parser/TemplateParser.y" +// line 477 "src/Parser/TemplateParser.y" public function yy_r38(){ $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('from'=>$this->yystack[$this->yyidx + -3]->minor),array('item'=>$this->yystack[$this->yyidx + -1]->minor)))); } -// line 480 "src/Parser/TemplateParser.y" +// line 481 "src/Parser/TemplateParser.y" public function yy_r39(){ $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + 0]->minor,array(array('from'=>$this->yystack[$this->yyidx + -5]->minor),array('item'=>$this->yystack[$this->yyidx + -1]->minor),array('key'=>$this->yystack[$this->yyidx + -3]->minor)))); } -// line 483 "src/Parser/TemplateParser.y" +// line 484 "src/Parser/TemplateParser.y" public function yy_r40(){ $this->_retvalue = $this->compiler->compileTag('foreach',$this->yystack[$this->yyidx + 0]->minor); } -// line 488 "src/Parser/TemplateParser.y" +// line 489 "src/Parser/TemplateParser.y" public function yy_r41(){ $this->_retvalue = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array(array_merge(array($this->yystack[$this->yyidx + -1]->minor),$this->yystack[$this->yyidx + 0]->minor)))); } -// line 492 "src/Parser/TemplateParser.y" +// line 493 "src/Parser/TemplateParser.y" public function yy_r42(){ $this->_retvalue = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array_merge(array(array_merge(array($this->yystack[$this->yyidx + -2]->minor),$this->yystack[$this->yyidx + -1]->minor)),$this->yystack[$this->yyidx + 0]->minor))); } -// line 498 "src/Parser/TemplateParser.y" +// line 499 "src/Parser/TemplateParser.y" public function yy_r43(){ $tag = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' /'); if ($tag === 'strip') { @@ -2351,36 +2418,36 @@ public static $yy_action = array( $this->_retvalue = $this->compiler->compileTag($tag.'close',array()); } } -// line 507 "src/Parser/TemplateParser.y" +// line 508 "src/Parser/TemplateParser.y" public function yy_r44(){ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + 0]->minor.'close',array()); } -// line 511 "src/Parser/TemplateParser.y" +// line 512 "src/Parser/TemplateParser.y" public function yy_r45(){ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor.'close',array(),array('modifier_list'=>$this->yystack[$this->yyidx + 0]->minor)); } -// line 516 "src/Parser/TemplateParser.y" +// line 517 "src/Parser/TemplateParser.y" public function yy_r46(){ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor.'close',array(),array('object_method'=>$this->yystack[$this->yyidx + 0]->minor)); } -// line 520 "src/Parser/TemplateParser.y" +// line 521 "src/Parser/TemplateParser.y" public function yy_r47(){ $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor.'close',array(),array('object_method'=>$this->yystack[$this->yyidx + -1]->minor, 'modifier_list'=>$this->yystack[$this->yyidx + 0]->minor)); } -// line 528 "src/Parser/TemplateParser.y" +// line 529 "src/Parser/TemplateParser.y" public function yy_r48(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; $this->_retvalue[] = $this->yystack[$this->yyidx + 0]->minor; } -// line 534 "src/Parser/TemplateParser.y" +// line 535 "src/Parser/TemplateParser.y" public function yy_r49(){ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor); } -// line 539 "src/Parser/TemplateParser.y" +// line 540 "src/Parser/TemplateParser.y" public function yy_r50(){ $this->_retvalue = array(); } -// line 544 "src/Parser/TemplateParser.y" +// line 545 "src/Parser/TemplateParser.y" public function yy_r51(){ if (defined($this->yystack[$this->yyidx + 0]->minor)) { if ($this->security) { @@ -2391,64 +2458,64 @@ public static $yy_action = array( $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>'\''.$this->yystack[$this->yyidx + 0]->minor.'\''); } } -// line 555 "src/Parser/TemplateParser.y" +// line 556 "src/Parser/TemplateParser.y" public function yy_r52(){ $this->_retvalue = array(trim($this->yystack[$this->yyidx + -1]->minor," =\n\r\t")=>$this->yystack[$this->yyidx + 0]->minor); } -// line 563 "src/Parser/TemplateParser.y" +// line 564 "src/Parser/TemplateParser.y" public function yy_r54(){ $this->_retvalue = '\''.$this->yystack[$this->yyidx + 0]->minor.'\''; } -// line 575 "src/Parser/TemplateParser.y" +// line 576 "src/Parser/TemplateParser.y" public function yy_r57(){ $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>$this->yystack[$this->yyidx + 0]->minor); } -// line 588 "src/Parser/TemplateParser.y" +// line 589 "src/Parser/TemplateParser.y" public function yy_r59(){ $this->yystack[$this->yyidx + -2]->minor[]=$this->yystack[$this->yyidx + 0]->minor; $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor; } -// line 593 "src/Parser/TemplateParser.y" +// line 594 "src/Parser/TemplateParser.y" public function yy_r60(){ $this->_retvalue = array('var' => '\''.substr($this->yystack[$this->yyidx + -2]->minor,1).'\'', 'value'=>$this->yystack[$this->yyidx + 0]->minor); } -// line 600 "src/Parser/TemplateParser.y" +// line 601 "src/Parser/TemplateParser.y" public function yy_r62(){ $this->_retvalue = array('var' => $this->yystack[$this->yyidx + -2]->minor, 'value'=>$this->yystack[$this->yyidx + 0]->minor); } -// line 604 "src/Parser/TemplateParser.y" +// line 605 "src/Parser/TemplateParser.y" public function yy_r63(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; } -// line 629 "src/Parser/TemplateParser.y" +// line 630 "src/Parser/TemplateParser.y" public function yy_r67(){ $this->_retvalue = '$_smarty_tpl->getVariable(\''. substr($this->yystack[$this->yyidx + 0]->minor,1) .'\')->preIncDec(\'' . $this->yystack[$this->yyidx + -1]->minor . '\')'; } -// line 634 "src/Parser/TemplateParser.y" +// line 635 "src/Parser/TemplateParser.y" public function yy_r68(){ $this->_retvalue = '$_smarty_tpl->getVariable(\''. substr($this->yystack[$this->yyidx + -1]->minor,1) .'\')->postIncDec(\'' . $this->yystack[$this->yyidx + 0]->minor . '\')'; } -// line 639 "src/Parser/TemplateParser.y" +// line 640 "src/Parser/TemplateParser.y" public function yy_r69(){ $this->_retvalue = '$_smarty_tpl->getStreamVariable(\''.substr($this->yystack[$this->yyidx + -2]->minor,1).'://' . $this->yystack[$this->yyidx + 0]->minor . '\')'; } -// line 644 "src/Parser/TemplateParser.y" +// line 645 "src/Parser/TemplateParser.y" public function yy_r70(){ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . trim($this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor; } -// line 654 "src/Parser/TemplateParser.y" +// line 655 "src/Parser/TemplateParser.y" public function yy_r72(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor['pre']. $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor['op'].$this->yystack[$this->yyidx + 0]->minor .')'; } -// line 658 "src/Parser/TemplateParser.y" +// line 659 "src/Parser/TemplateParser.y" public function yy_r73(){ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } -// line 662 "src/Parser/TemplateParser.y" +// line 663 "src/Parser/TemplateParser.y" public function yy_r74(){ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor . $this->yystack[$this->yyidx + -1]->minor . ')'; } -// line 666 "src/Parser/TemplateParser.y" +// line 667 "src/Parser/TemplateParser.y" public function yy_r75(){ static $isin = [ 'isin' => 'in_array(', @@ -2457,51 +2524,52 @@ public static $yy_action = array( $op = strtolower(str_replace(' ', '', $this->yystack[$this->yyidx + 0]->minor)); $this->_retvalue = $isin[$op]; } -// line 675 "src/Parser/TemplateParser.y" +// line 676 "src/Parser/TemplateParser.y" public function yy_r76(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + -2]->minor.','.$this->yystack[$this->yyidx + 0]->minor.')'; } -// line 679 "src/Parser/TemplateParser.y" +// line 680 "src/Parser/TemplateParser.y" public function yy_r77(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor . $this->yystack[$this->yyidx + -2]->minor.',(array)'.$this->yystack[$this->yyidx + 0]->minor.')'; } -// line 684 "src/Parser/TemplateParser.y" +// line 685 "src/Parser/TemplateParser.y" public function yy_r78(){ $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor.' ?? '.$this->yystack[$this->yyidx + 0]->minor; } -// line 691 "src/Parser/TemplateParser.y" +// line 692 "src/Parser/TemplateParser.y" public function yy_r79(){ - $this->_retvalue = $this->yystack[$this->yyidx + -4]->minor.' ? '. $this->compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + -2]->minor,1).'\'') . ' : '.$this->yystack[$this->yyidx + 0]->minor; + $this->compiler->triggerTagNoCache(substr($this->yystack[$this->yyidx + -2]->minor,1)); + $this->_retvalue = $this->yystack[$this->yyidx + -4]->minor.' ? $_smarty_tpl->getValue(\''.substr($this->yystack[$this->yyidx + -2]->minor,1).'\') : '.$this->yystack[$this->yyidx + 0]->minor; } -// line 695 "src/Parser/TemplateParser.y" +// line 697 "src/Parser/TemplateParser.y" public function yy_r80(){ $this->_retvalue = $this->yystack[$this->yyidx + -4]->minor.' ? '.$this->yystack[$this->yyidx + -2]->minor.' : '.$this->yystack[$this->yyidx + 0]->minor; } -// line 704 "src/Parser/TemplateParser.y" +// line 706 "src/Parser/TemplateParser.y" public function yy_r82(){ $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor.' ?: '.$this->yystack[$this->yyidx + 0]->minor; } -// line 714 "src/Parser/TemplateParser.y" +// line 716 "src/Parser/TemplateParser.y" public function yy_r84(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } -// line 719 "src/Parser/TemplateParser.y" +// line 721 "src/Parser/TemplateParser.y" public function yy_r85(){ $this->_retvalue = '!'.$this->yystack[$this->yyidx + 0]->minor; } -// line 740 "src/Parser/TemplateParser.y" +// line 742 "src/Parser/TemplateParser.y" public function yy_r90(){ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'.'.$this->yystack[$this->yyidx + 0]->minor; } -// line 744 "src/Parser/TemplateParser.y" +// line 746 "src/Parser/TemplateParser.y" public function yy_r91(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.'.'; } -// line 748 "src/Parser/TemplateParser.y" +// line 750 "src/Parser/TemplateParser.y" public function yy_r92(){ $this->_retvalue = '.'.$this->yystack[$this->yyidx + 0]->minor; } -// line 753 "src/Parser/TemplateParser.y" +// line 755 "src/Parser/TemplateParser.y" public function yy_r93(){ if (defined($this->yystack[$this->yyidx + 0]->minor)) { if ($this->security) { @@ -2512,15 +2580,15 @@ public static $yy_action = array( $this->_retvalue = '\''.$this->yystack[$this->yyidx + 0]->minor.'\''; } } -// line 770 "src/Parser/TemplateParser.y" +// line 772 "src/Parser/TemplateParser.y" public function yy_r95(){ $this->_retvalue = '('. $this->yystack[$this->yyidx + -1]->minor .')'; } -// line 774 "src/Parser/TemplateParser.y" +// line 776 "src/Parser/TemplateParser.y" public function yy_r96(){ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } -// line 792 "src/Parser/TemplateParser.y" +// line 794 "src/Parser/TemplateParser.y" public function yy_r100(){ if ($this->security && $this->security->static_classes !== array()) { $this->compiler->trigger_template_error('dynamic static class not allowed by security setting'); @@ -2529,22 +2597,23 @@ public static $yy_action = array( if ($this->yystack[$this->yyidx + -2]->minor['var'] === '\'smarty\'') { $this->compiler->appendPrefixCode("compile(array(),$this->compiler,$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index']).';?>'); } else { - $this->compiler->appendPrefixCode("compiler->compileVariable($this->yystack[$this->yyidx + -2]->minor['var']).$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index'].';?>'); + $this->compiler->triggerTagNoCache($this->yystack[$this->yyidx + -2]->minor['var']); + $this->compiler->appendPrefixCode("getValue(" . $this->yystack[$this->yyidx + -2]->minor['var'] . ')'.$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index'].';?>'); } $this->_retvalue = $prefixVar .'::'.$this->yystack[$this->yyidx + 0]->minor[0].$this->yystack[$this->yyidx + 0]->minor[1]; } -// line 806 "src/Parser/TemplateParser.y" +// line 809 "src/Parser/TemplateParser.y" public function yy_r101(){ $prefixVar = $this->compiler->getNewPrefixVariable(); $tmp = $this->compiler->appendCode('', (string) $this->yystack[$this->yyidx + 0]->minor); $this->compiler->appendPrefixCode($this->compiler->appendCode($tmp, "")); $this->_retvalue = $prefixVar; } -// line 813 "src/Parser/TemplateParser.y" +// line 816 "src/Parser/TemplateParser.y" public function yy_r102(){ $this->_retvalue = $this->compiler->compileModifier($this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor); } -// line 826 "src/Parser/TemplateParser.y" +// line 829 "src/Parser/TemplateParser.y" public function yy_r105(){ if (!in_array(strtolower($this->yystack[$this->yyidx + -2]->minor), array('self', 'parent')) && (!$this->security || $this->security->isTrustedStaticClassAccess($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->compiler))) { if (isset($this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor])) { @@ -2556,241 +2625,292 @@ public static $yy_action = array( $this->compiler->trigger_template_error ('static class \''.$this->yystack[$this->yyidx + -2]->minor.'\' is undefined or not allowed by security setting'); } } -// line 845 "src/Parser/TemplateParser.y" +// line 848 "src/Parser/TemplateParser.y" public function yy_r107(){ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; } // line 856 "src/Parser/TemplateParser.y" public function yy_r108(){ - $this->_retvalue = $this->compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\''); + $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor,array($this->yystack[$this->yyidx + 0]->minor)); } -// line 859 "src/Parser/TemplateParser.y" - public function yy_r109(){ +// line 883 "src/Parser/TemplateParser.y" + public function yy_r113(){ + $this->compiler->triggerTagNoCache(substr($this->yystack[$this->yyidx + 0]->minor,1)); + $this->_retvalue = array('$_smarty_tpl->hasVariable(\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\')','$_smarty_tpl->getValue(\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\')'); + } +// line 887 "src/Parser/TemplateParser.y" + public function yy_r114(){ if ($this->yystack[$this->yyidx + 0]->minor['var'] === '\'smarty\'') { $smarty_var = (new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,$this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']); - $this->_retvalue = $smarty_var; + $this->_retvalue = array('true', $smarty_var); } else { // used for array reset,next,prev,end,current $this->last_variable = $this->yystack[$this->yyidx + 0]->minor['var']; $this->last_index = $this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']; - $this->_retvalue = $this->compiler->compileVariable($this->yystack[$this->yyidx + 0]->minor['var']).$this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']; + $this->compiler->triggerTagNoCache($this->yystack[$this->yyidx + 0]->minor['var']); + $this->_retvalue = array('true', '$_smarty_tpl->getValue(' . $this->yystack[$this->yyidx + 0]->minor['var'] . ')'.$this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']); } } -// line 872 "src/Parser/TemplateParser.y" - public function yy_r110(){ - $this->_retvalue = '$_smarty_tpl->getVariable('. $this->yystack[$this->yyidx + -2]->minor .')->'.$this->yystack[$this->yyidx + 0]->minor; - } -// line 882 "src/Parser/TemplateParser.y" - public function yy_r112(){ - $this->_retvalue = $this->compiler->compileConfigVariable('\'' . $this->yystack[$this->yyidx + -1]->minor . '\''); - } -// line 886 "src/Parser/TemplateParser.y" - public function yy_r113(){ - $this->_retvalue = '(is_array($tmp = ' . $this->compiler->compileConfigVariable('\'' . $this->yystack[$this->yyidx + -2]->minor . '\'') . ') ? $tmp'.$this->yystack[$this->yyidx + 0]->minor.' :null)'; - } -// line 890 "src/Parser/TemplateParser.y" - public function yy_r114(){ - $this->_retvalue = $this->compiler->compileConfigVariable($this->yystack[$this->yyidx + -1]->minor); - } -// line 894 "src/Parser/TemplateParser.y" - public function yy_r115(){ - $this->_retvalue = '(is_array($tmp = ' . $this->compiler->compileConfigVariable($this->yystack[$this->yyidx + -2]->minor) . ') ? $tmp'.$this->yystack[$this->yyidx + 0]->minor.' : null)'; - } -// line 898 "src/Parser/TemplateParser.y" - public function yy_r116(){ - $this->_retvalue = array('var'=>'\''.substr($this->yystack[$this->yyidx + -1]->minor,1).'\'', 'smarty_internal_index'=>$this->yystack[$this->yyidx + 0]->minor); - } // line 901 "src/Parser/TemplateParser.y" + public function yy_r115(){ + $this->_retvalue = array('true', '$_smarty_tpl->getVariable('. $this->yystack[$this->yyidx + -2]->minor .')->'.$this->yystack[$this->yyidx + 0]->minor); + } +// line 906 "src/Parser/TemplateParser.y" + public function yy_r116(){ + $this->_retvalue = array('true', $this->yystack[$this->yyidx + 0]->minor); + } +// line 911 "src/Parser/TemplateParser.y" public function yy_r117(){ - $this->_retvalue = array('var'=>$this->yystack[$this->yyidx + -1]->minor, 'smarty_internal_index'=>$this->yystack[$this->yyidx + 0]->minor); + $this->_retvalue = $this->compiler->compileConfigVariable('\'' . $this->yystack[$this->yyidx + -1]->minor . '\''); } -// line 914 "src/Parser/TemplateParser.y" +// line 915 "src/Parser/TemplateParser.y" + public function yy_r118(){ + $this->_retvalue = '(is_array($tmp = ' . $this->compiler->compileConfigVariable('\'' . $this->yystack[$this->yyidx + -2]->minor . '\'') . ') ? $tmp'.$this->yystack[$this->yyidx + 0]->minor.' :null)'; + } +// line 919 "src/Parser/TemplateParser.y" public function yy_r119(){ - return; - } -// line 920 "src/Parser/TemplateParser.y" - public function yy_r120(){ - $this->_retvalue = '['.$this->compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\'').']'; + $this->_retvalue = $this->compiler->compileConfigVariable($this->yystack[$this->yyidx + -1]->minor); } // line 923 "src/Parser/TemplateParser.y" - public function yy_r121(){ - $this->_retvalue = '['.$this->compiler->compileVariable($this->yystack[$this->yyidx + 0]->minor).']'; + public function yy_r120(){ + $this->_retvalue = '(is_array($tmp = ' . $this->compiler->compileConfigVariable($this->yystack[$this->yyidx + -2]->minor) . ') ? $tmp'.$this->yystack[$this->yyidx + 0]->minor.' : null)'; } // line 927 "src/Parser/TemplateParser.y" - public function yy_r122(){ - $this->_retvalue = '['.$this->compiler->compileVariable($this->yystack[$this->yyidx + -2]->minor).'->'.$this->yystack[$this->yyidx + 0]->minor.']'; - } -// line 931 "src/Parser/TemplateParser.y" - public function yy_r123(){ - $this->_retvalue = '[\''. $this->yystack[$this->yyidx + 0]->minor .'\']'; + public function yy_r121(){ + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor[1]; } // line 935 "src/Parser/TemplateParser.y" + public function yy_r123(){ + $this->_retvalue = array('var'=>'\''.substr($this->yystack[$this->yyidx + -1]->minor,1).'\'', 'smarty_internal_index'=>$this->yystack[$this->yyidx + 0]->minor); + } +// line 938 "src/Parser/TemplateParser.y" public function yy_r124(){ + $this->_retvalue = array('var'=>$this->yystack[$this->yyidx + -1]->minor, 'smarty_internal_index'=>$this->yystack[$this->yyidx + 0]->minor); + } +// line 951 "src/Parser/TemplateParser.y" + public function yy_r126(){ + return; + } +// line 957 "src/Parser/TemplateParser.y" + public function yy_r127(){ + $this->compiler->triggerTagNoCache(substr($this->yystack[$this->yyidx + 0]->minor,1)); + $this->_retvalue = '[$_smarty_tpl->getValue(\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\')]'; + } +// line 961 "src/Parser/TemplateParser.y" + public function yy_r128(){ + $this->compiler->triggerTagNoCache($this->yystack[$this->yyidx + 0]->minor); + $this->_retvalue = '[$_smarty_tpl->getValue(' . $this->yystack[$this->yyidx + 0]->minor . ')]'; + } +// line 966 "src/Parser/TemplateParser.y" + public function yy_r129(){ + $this->compiler->triggerTagNoCache($this->yystack[$this->yyidx + -2]->minor); + $this->_retvalue = '[$_smarty_tpl->getValue(' . $this->yystack[$this->yyidx + -2]->minor . ')->'.$this->yystack[$this->yyidx + 0]->minor.']'; + } +// line 971 "src/Parser/TemplateParser.y" + public function yy_r130(){ + $this->_retvalue = '[\''. $this->yystack[$this->yyidx + 0]->minor .'\']'; + } +// line 975 "src/Parser/TemplateParser.y" + public function yy_r131(){ $this->_retvalue = '['. $this->yystack[$this->yyidx + 0]->minor .']'; } -// line 940 "src/Parser/TemplateParser.y" - public function yy_r125(){ +// line 980 "src/Parser/TemplateParser.y" + public function yy_r132(){ $this->_retvalue = '['. $this->yystack[$this->yyidx + -1]->minor .']'; } -// line 945 "src/Parser/TemplateParser.y" - public function yy_r126(){ +// line 985 "src/Parser/TemplateParser.y" + public function yy_r133(){ $this->_retvalue = '['.(new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,'[\'section\'][\''.$this->yystack[$this->yyidx + -1]->minor.'\'][\'index\']').']'; } -// line 949 "src/Parser/TemplateParser.y" - public function yy_r127(){ +// line 989 "src/Parser/TemplateParser.y" + public function yy_r134(){ $this->_retvalue = '['.(new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,'[\'section\'][\''.$this->yystack[$this->yyidx + -3]->minor.'\'][\''.$this->yystack[$this->yyidx + -1]->minor.'\']').']'; } -// line 952 "src/Parser/TemplateParser.y" - public function yy_r128(){ +// line 992 "src/Parser/TemplateParser.y" + public function yy_r135(){ $this->_retvalue = '['.$this->yystack[$this->yyidx + -1]->minor.']'; } -// line 958 "src/Parser/TemplateParser.y" - public function yy_r130(){ - $this->_retvalue = '['.$this->compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + -1]->minor,1).'\'').']'; +// line 998 "src/Parser/TemplateParser.y" + public function yy_r137(){ + $this->compiler->triggerTagNoCache(substr($this->yystack[$this->yyidx + -1]->minor,1)); + $this->_retvalue = '[$_smarty_tpl->getValue(\''.substr($this->yystack[$this->yyidx + -1]->minor,1).'\')]'; } -// line 974 "src/Parser/TemplateParser.y" - public function yy_r134(){ +// line 1015 "src/Parser/TemplateParser.y" + public function yy_r141(){ $this->_retvalue = '[]'; } -// line 984 "src/Parser/TemplateParser.y" - public function yy_r135(){ +// line 1025 "src/Parser/TemplateParser.y" + public function yy_r142(){ $this->_retvalue = '\''.substr($this->yystack[$this->yyidx + 0]->minor,1).'\''; } -// line 988 "src/Parser/TemplateParser.y" - public function yy_r136(){ +// line 1029 "src/Parser/TemplateParser.y" + public function yy_r143(){ $this->_retvalue = '\'\''; } -// line 993 "src/Parser/TemplateParser.y" - public function yy_r137(){ +// line 1034 "src/Parser/TemplateParser.y" + public function yy_r144(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.'.'.$this->yystack[$this->yyidx + 0]->minor; } -// line 1001 "src/Parser/TemplateParser.y" - public function yy_r139(){ +// line 1042 "src/Parser/TemplateParser.y" + public function yy_r146(){ $var = trim(substr($this->yystack[$this->yyidx + 0]->minor, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' $'); - $this->_retvalue = $this->compiler->compileVariable('\''.$var.'\''); + $this->compiler->triggerTagNoCache($var); + $this->_retvalue = '$_smarty_tpl->getValue(\''.$var.'\')'; } -// line 1007 "src/Parser/TemplateParser.y" - public function yy_r140(){ +// line 1049 "src/Parser/TemplateParser.y" + public function yy_r147(){ $this->_retvalue = '('.$this->yystack[$this->yyidx + -1]->minor.')'; } -// line 1014 "src/Parser/TemplateParser.y" - public function yy_r141(){ +// line 1056 "src/Parser/TemplateParser.y" + public function yy_r148(){ if ($this->yystack[$this->yyidx + -1]->minor['var'] === '\'smarty\'') { $this->_retvalue = (new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index']).$this->yystack[$this->yyidx + 0]->minor; } else { - $this->_retvalue = $this->compiler->compileVariable($this->yystack[$this->yyidx + -1]->minor['var']).$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index'].$this->yystack[$this->yyidx + 0]->minor; + $this->compiler->triggerTagNoCache($this->yystack[$this->yyidx + -1]->minor['var']); + $this->_retvalue = '$_smarty_tpl->getValue(' . $this->yystack[$this->yyidx + -1]->minor['var'] . ')'.$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index'].$this->yystack[$this->yyidx + 0]->minor; } } -// line 1023 "src/Parser/TemplateParser.y" - public function yy_r142(){ +// line 1066 "src/Parser/TemplateParser.y" + public function yy_r149(){ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; } -// line 1028 "src/Parser/TemplateParser.y" - public function yy_r143(){ +// line 1071 "src/Parser/TemplateParser.y" + public function yy_r150(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } -// line 1033 "src/Parser/TemplateParser.y" - public function yy_r144(){ +// line 1076 "src/Parser/TemplateParser.y" + public function yy_r151(){ if ($this->security && substr($this->yystack[$this->yyidx + -1]->minor,0,1) === '_') { $this->compiler->trigger_template_error (self::ERR1); } $this->_retvalue = '->'.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; } -// line 1040 "src/Parser/TemplateParser.y" - public function yy_r145(){ +// line 1083 "src/Parser/TemplateParser.y" + public function yy_r152(){ if ($this->security) { $this->compiler->trigger_template_error (self::ERR2); } - $this->_retvalue = '->{'.$this->compiler->compileVariable($this->yystack[$this->yyidx + -1]->minor).$this->yystack[$this->yyidx + 0]->minor.'}'; + $this->compiler->triggerTagNoCache($this->yystack[$this->yyidx + -1]->minor); + $this->_retvalue = '->{$_smarty_tpl->getValue(' . $this->yystack[$this->yyidx + -1]->minor . ')'.$this->yystack[$this->yyidx + 0]->minor.'}'; } -// line 1047 "src/Parser/TemplateParser.y" - public function yy_r146(){ +// line 1091 "src/Parser/TemplateParser.y" + public function yy_r153(){ if ($this->security) { $this->compiler->trigger_template_error (self::ERR2); } $this->_retvalue = '->{'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + 0]->minor.'}'; } -// line 1054 "src/Parser/TemplateParser.y" - public function yy_r147(){ +// line 1098 "src/Parser/TemplateParser.y" + public function yy_r154(){ if ($this->security) { $this->compiler->trigger_template_error (self::ERR2); } $this->_retvalue = '->{\''.$this->yystack[$this->yyidx + -4]->minor.'\'.'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + 0]->minor.'}'; } -// line 1062 "src/Parser/TemplateParser.y" - public function yy_r148(){ +// line 1106 "src/Parser/TemplateParser.y" + public function yy_r155(){ $this->_retvalue = '->'.$this->yystack[$this->yyidx + 0]->minor; } -// line 1070 "src/Parser/TemplateParser.y" - public function yy_r149(){ - $this->_retvalue = $this->compiler->compileModifierInExpression($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + -1]->minor); +// line 1114 "src/Parser/TemplateParser.y" + public function yy_r156(){ + + if ($this->yystack[$this->yyidx + -3]->minor == 'isset') { + $this->_retvalue = '(true'; + if (count($this->yystack[$this->yyidx + -1]->minor) == 0) { + throw new CompilerException("Invalid number of arguments for isset. isset expects at least one parameter."); + } + foreach ($this->yystack[$this->yyidx + -1]->minor as $value) { + if (is_array($value)) { + $this->_retvalue .= ' && (' . $value[0] . ' && null !== (' . $value[1] . ' ?? null))'; + } else { + $this->_retvalue .= ' && (' . $value . ' !== null)'; + } + } + $this->_retvalue .= ')'; + } elseif ($this->yystack[$this->yyidx + -3]->minor == 'empty') { + if (count($this->yystack[$this->yyidx + -1]->minor) != 1) { + throw new CompilerException("Invalid number of arguments for empty. empty expects at exactly one parameter."); + } + if (is_array($this->yystack[$this->yyidx + -1]->minor[0])) { + $this->_retvalue .= '( !' . $this->yystack[$this->yyidx + -1]->minor[0][0] . ' || empty(' . $this->yystack[$this->yyidx + -1]->minor[0][1] . '))'; + } else { + $this->_retvalue = 'false == ' . $this->yystack[$this->yyidx + -1]->minor[0]; + } + } else { + $p = array(); + foreach ($this->yystack[$this->yyidx + -1]->minor as $value) { + if (is_array($value)) { + $p[] = $value[1]; + } else { + $p[] = $value; + } + } + $this->_retvalue = $this->compiler->compileModifierInExpression($this->yystack[$this->yyidx + -3]->minor, $p); } -// line 1078 "src/Parser/TemplateParser.y" - public function yy_r150(){ + } +// line 1155 "src/Parser/TemplateParser.y" + public function yy_r157(){ if ($this->security && substr($this->yystack[$this->yyidx + -3]->minor,0,1) === '_') { $this->compiler->trigger_template_error (self::ERR1); } $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . '('. implode(',',$this->yystack[$this->yyidx + -1]->minor) .')'; } -// line 1085 "src/Parser/TemplateParser.y" - public function yy_r151(){ +// line 1162 "src/Parser/TemplateParser.y" + public function yy_r158(){ if ($this->security) { $this->compiler->trigger_template_error (self::ERR2); } $prefixVar = $this->compiler->getNewPrefixVariable(); - $this->compiler->appendPrefixCode("compiler->compileVariable('\''.substr($this->yystack[$this->yyidx + -3]->minor,1).'\'').';?>'); + $this->compiler->triggerTagNoCache(substr($this->yystack[$this->yyidx + -3]->minor,1)); + $this->compiler->appendPrefixCode("getValue('".substr($this->yystack[$this->yyidx + -3]->minor,1).'\')'.';?>'); $this->_retvalue = $prefixVar .'('. implode(',',$this->yystack[$this->yyidx + -1]->minor) .')'; } -// line 1096 "src/Parser/TemplateParser.y" - public function yy_r152(){ - $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor,array($this->yystack[$this->yyidx + 0]->minor)); - } -// line 1113 "src/Parser/TemplateParser.y" - public function yy_r155(){ +// line 1191 "src/Parser/TemplateParser.y" + public function yy_r162(){ $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor,array(array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor))); } -// line 1117 "src/Parser/TemplateParser.y" - public function yy_r156(){ +// line 1195 "src/Parser/TemplateParser.y" + public function yy_r163(){ $this->_retvalue = array(array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor)); } -// line 1125 "src/Parser/TemplateParser.y" - public function yy_r158(){ +// line 1203 "src/Parser/TemplateParser.y" + public function yy_r165(){ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor); } -// line 1133 "src/Parser/TemplateParser.y" - public function yy_r159(){ +// line 1211 "src/Parser/TemplateParser.y" + public function yy_r166(){ $this->_retvalue = array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor); } -// line 1146 "src/Parser/TemplateParser.y" - public function yy_r162(){ +// line 1224 "src/Parser/TemplateParser.y" + public function yy_r169(){ $this->_retvalue = array(trim($this->yystack[$this->yyidx + -1]->minor).$this->yystack[$this->yyidx + 0]->minor); } -// line 1155 "src/Parser/TemplateParser.y" - public function yy_r164(){ +// line 1233 "src/Parser/TemplateParser.y" + public function yy_r171(){ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor, '', 'method'); } -// line 1160 "src/Parser/TemplateParser.y" - public function yy_r165(){ +// line 1238 "src/Parser/TemplateParser.y" + public function yy_r172(){ $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor, 'method'); } -// line 1165 "src/Parser/TemplateParser.y" - public function yy_r166(){ +// line 1243 "src/Parser/TemplateParser.y" + public function yy_r173(){ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor, ''); } -// line 1170 "src/Parser/TemplateParser.y" - public function yy_r167(){ +// line 1248 "src/Parser/TemplateParser.y" + public function yy_r174(){ $this->_retvalue = array($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor, 'property'); } -// line 1175 "src/Parser/TemplateParser.y" - public function yy_r168(){ +// line 1253 "src/Parser/TemplateParser.y" + public function yy_r175(){ $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor, 'property'); } -// line 1181 "src/Parser/TemplateParser.y" - public function yy_r169(){ +// line 1259 "src/Parser/TemplateParser.y" + public function yy_r176(){ $this->_retvalue = ' '. trim($this->yystack[$this->yyidx + 0]->minor) . ' '; } -// line 1185 "src/Parser/TemplateParser.y" - public function yy_r170(){ +// line 1263 "src/Parser/TemplateParser.y" + public function yy_r177(){ static $lops = array( 'eq' => ' == ', 'ne' => ' != ', @@ -2809,8 +2929,8 @@ public static $yy_action = array( $op = strtolower(preg_replace('/\s*/', '', $this->yystack[$this->yyidx + 0]->minor)); $this->_retvalue = $lops[$op]; } -// line 1204 "src/Parser/TemplateParser.y" - public function yy_r171(){ +// line 1282 "src/Parser/TemplateParser.y" + public function yy_r178(){ static $tlops = array( 'isdivby' => array('op' => ' % ', 'pre' => '!('), 'isnotdivby' => array('op' => ' % ', 'pre' => '('), @@ -2822,8 +2942,8 @@ public static $yy_action = array( $op = strtolower(preg_replace('/\s*/', '', $this->yystack[$this->yyidx + 0]->minor)); $this->_retvalue = $tlops[$op]; } -// line 1217 "src/Parser/TemplateParser.y" - public function yy_r172(){ +// line 1295 "src/Parser/TemplateParser.y" + public function yy_r179(){ static $scond = array ( 'iseven' => '!(1 & ', 'isnoteven' => '(1 & ', @@ -2833,54 +2953,54 @@ public static $yy_action = array( $op = strtolower(str_replace(' ', '', $this->yystack[$this->yyidx + 0]->minor)); $this->_retvalue = $scond[$op]; } -// line 1231 "src/Parser/TemplateParser.y" - public function yy_r173(){ +// line 1309 "src/Parser/TemplateParser.y" + public function yy_r180(){ $this->_retvalue = 'array('.$this->yystack[$this->yyidx + -1]->minor.')'; } -// line 1242 "src/Parser/TemplateParser.y" - public function yy_r176(){ +// line 1320 "src/Parser/TemplateParser.y" + public function yy_r183(){ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.','.$this->yystack[$this->yyidx + 0]->minor; } -// line 1250 "src/Parser/TemplateParser.y" - public function yy_r178(){ +// line 1328 "src/Parser/TemplateParser.y" + public function yy_r185(){ $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'=>'.$this->yystack[$this->yyidx + 0]->minor; } -// line 1254 "src/Parser/TemplateParser.y" - public function yy_r179(){ +// line 1332 "src/Parser/TemplateParser.y" + public function yy_r186(){ $this->_retvalue = '\''.$this->yystack[$this->yyidx + -2]->minor.'\'=>'.$this->yystack[$this->yyidx + 0]->minor; } -// line 1270 "src/Parser/TemplateParser.y" - public function yy_r182(){ +// line 1348 "src/Parser/TemplateParser.y" + public function yy_r189(){ $this->compiler->leaveDoubleQuote(); $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor->to_smarty_php($this); } -// line 1276 "src/Parser/TemplateParser.y" - public function yy_r183(){ +// line 1354 "src/Parser/TemplateParser.y" + public function yy_r190(){ $this->yystack[$this->yyidx + -1]->minor->append_subtree($this, $this->yystack[$this->yyidx + 0]->minor); $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; } -// line 1281 "src/Parser/TemplateParser.y" - public function yy_r184(){ +// line 1359 "src/Parser/TemplateParser.y" + public function yy_r191(){ $this->_retvalue = new Dq($this, $this->yystack[$this->yyidx + 0]->minor); } -// line 1285 "src/Parser/TemplateParser.y" - public function yy_r185(){ +// line 1363 "src/Parser/TemplateParser.y" + public function yy_r192(){ $this->_retvalue = new Code('(string)'.$this->yystack[$this->yyidx + -1]->minor); } -// line 1289 "src/Parser/TemplateParser.y" - public function yy_r186(){ +// line 1367 "src/Parser/TemplateParser.y" + public function yy_r193(){ $this->_retvalue = new Code('(string)('.$this->yystack[$this->yyidx + -1]->minor.')'); } -// line 1293 "src/Parser/TemplateParser.y" - public function yy_r187(){ +// line 1371 "src/Parser/TemplateParser.y" + public function yy_r194(){ $this->_retvalue = new Code('(string)$_smarty_tpl->getValue(\''. substr($this->yystack[$this->yyidx + 0]->minor,1) .'\')'); } -// line 1305 "src/Parser/TemplateParser.y" - public function yy_r190(){ +// line 1383 "src/Parser/TemplateParser.y" + public function yy_r197(){ $this->_retvalue = new Tag($this, $this->yystack[$this->yyidx + 0]->minor); } -// line 1309 "src/Parser/TemplateParser.y" - public function yy_r191(){ +// line 1387 "src/Parser/TemplateParser.y" + public function yy_r198(){ $this->_retvalue = new DqContent($this->yystack[$this->yyidx + 0]->minor); } diff --git a/src/Parser/TemplateParser.y b/src/Parser/TemplateParser.y index f1e3c35..58d115f 100644 --- a/src/Parser/TemplateParser.y +++ b/src/Parser/TemplateParser.y @@ -19,7 +19,7 @@ use \Smarty\ParseTree\Code; use \Smarty\ParseTree\Dq; use \Smarty\ParseTree\DqContent; use \Smarty\ParseTree\Tag; - +use \Smarty\CompilerException; /** * Smarty Template Parser Class @@ -306,7 +306,8 @@ smartytag(A) ::= SIMPELOUTPUT(B). { $attributes[] = 'nocache'; $var = $match[1]; } - A = $this->compiler->compilePrintExpression($this->compiler->compileVariable('\''.$var.'\''), $attributes); + $this->compiler->triggerTagNoCache($var); + A = $this->compiler->compilePrintExpression('$_smarty_tpl->getValue(\''.$var.'\')', $attributes); } // simple tag like {name} @@ -375,7 +376,7 @@ outattr(A) ::= output(B) attributes(C). { A = array(B,C); } -output(A) ::= variable(B). { +output(A) ::= variablevalue(B). { A = B; } output(A) ::= value(B). { @@ -689,7 +690,8 @@ nullcoalescing(res) ::= expr(v) QMARK QMARK expr(e2). { // ternary // ternary(res) ::= expr(v) QMARK DOLLARID(e1) COLON expr(e2). { - res = v.' ? '. $this->compiler->compileVariable('\''.substr(e1,1).'\'') . ' : '.e2; + $this->compiler->triggerTagNoCache(substr(e1,1)); + res = v.' ? $_smarty_tpl->getValue(\''.substr(e1,1).'\') : '.e2; } ternary(res) ::= expr(v) QMARK value(e1) COLON expr(e2). { @@ -706,7 +708,7 @@ ternary(res) ::= expr(v) QMARK COLON expr(e2). { } // value -value(res) ::= variable(v). { +value(res) ::= variablevalue(v). { res = v; } @@ -724,7 +726,7 @@ value(res) ::= TYPECAST(t) value(v). { res = t.v; } -value(res) ::= variable(v) INCDEC(o). { +value(res) ::= variablevalue(v) INCDEC(o). { res = v.o; } @@ -771,10 +773,10 @@ value(res) ::= OPENP expr(e) CLOSEP. { res = '('. e .')'; } -value(res) ::= variable(v1) INSTANCEOF(i) ns1(v2). { +value(res) ::= variablevalue(v1) INSTANCEOF(i) ns1(v2). { res = v1.i.v2; } -value(res) ::= variable(v1) INSTANCEOF(i) variable(v2). { +value(res) ::= variablevalue(v1) INSTANCEOF(i) variablevalue(v2). { res = v1.i.v2; } @@ -797,7 +799,8 @@ value(res) ::= varindexed(vi) DOUBLECOLON static_class_access(r). { if (vi['var'] === '\'smarty\'') { $this->compiler->appendPrefixCode("compile(array(),$this->compiler,vi['smarty_internal_index']).';?>'); } else { - $this->compiler->appendPrefixCode("compiler->compileVariable(vi['var']).vi['smarty_internal_index'].';?>'); + $this->compiler->triggerTagNoCache(vi['var']); + $this->compiler->appendPrefixCode("getValue(" . vi['var'] . ')'.vi['smarty_internal_index'].';?>'); } res = $prefixVar .'::'.r[0].r[1]; } @@ -847,54 +850,88 @@ ns1(res) ::= NAMESPACE(i). { } +// variable lists +// multiple variables +variablelist(res) ::= variablelist(l) COMMA variable(v). { + res = array_merge(l,array(v)); +} + +variablelist(res) ::= variablelist(l) COMMA expr(e). { + res = array_merge(l,array(e)); +} + +// single variable +variablelist(res) ::= variable(v). { + res = array(v); +} + +// single expression +variablelist(res) ::= expr(e). { + res = array(e); +} + +// no variable +variablelist(res) ::= . { + res = array(); +} // // variables // // Smarty variable (optional array) variable(res) ::= DOLLARID(i). { - res = $this->compiler->compileVariable('\''.substr(i,1).'\''); + $this->compiler->triggerTagNoCache(substr(i,1)); + res = array('$_smarty_tpl->hasVariable(\''.substr(i,1).'\')','$_smarty_tpl->getValue(\''.substr(i,1).'\')'); } variable(res) ::= varindexed(vi). { if (vi['var'] === '\'smarty\'') { $smarty_var = (new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,vi['smarty_internal_index']); - res = $smarty_var; + res = array('true', $smarty_var); } else { // used for array reset,next,prev,end,current $this->last_variable = vi['var']; $this->last_index = vi['smarty_internal_index']; - res = $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index']; + $this->compiler->triggerTagNoCache(vi['var']); + res = array('true', '$_smarty_tpl->getValue(' . vi['var'] . ')'.vi['smarty_internal_index']); } } // variable with property variable(res) ::= varvar(v) AT ID(p). { - res = '$_smarty_tpl->getVariable('. v .')->'.p; + res = array('true', '$_smarty_tpl->getVariable('. v .')->'.p); } // object variable(res) ::= object(o). { - res = o; + res = array('true', o); } // config variable -variable(res) ::= HATCH ID(i) HATCH. { +configvariable(res) ::= HATCH ID(i) HATCH. { res = $this->compiler->compileConfigVariable('\'' . i . '\''); } -variable(res) ::= HATCH ID(i) HATCH arrayindex(a). { +configvariable(res) ::= HATCH ID(i) HATCH arrayindex(a). { res = '(is_array($tmp = ' . $this->compiler->compileConfigVariable('\'' . i . '\'') . ') ? $tmp'.a.' :null)'; } -variable(res) ::= HATCH variable(v) HATCH. { +configvariable(res) ::= HATCH variablevalue(v) HATCH. { res = $this->compiler->compileConfigVariable(v); } -variable(res) ::= HATCH variable(v) HATCH arrayindex(a). { +configvariable(res) ::= HATCH variablevalue(v) HATCH arrayindex(a). { res = '(is_array($tmp = ' . $this->compiler->compileConfigVariable(v) . ') ? $tmp'.a.' : null)'; } +variablevalue(res) ::= variable(v). { + res = v[1]; +} + +variablevalue(res) ::= configvariable(v). { + res = v; +} + varindexed(res) ::= DOLLARID(i) arrayindex(a). { res = array('var'=>'\''.substr(i,1).'\'', 'smarty_internal_index'=>a); } @@ -918,14 +955,17 @@ arrayindex ::= . { // single index definition // Smarty2 style index indexdef(res) ::= DOT DOLLARID(i). { - res = '['.$this->compiler->compileVariable('\''.substr(i,1).'\'').']'; + $this->compiler->triggerTagNoCache(substr(i,1)); + res = '[$_smarty_tpl->getValue(\''.substr(i,1).'\')]'; } indexdef(res) ::= DOT varvar(v). { - res = '['.$this->compiler->compileVariable(v).']'; + $this->compiler->triggerTagNoCache(v); + res = '[$_smarty_tpl->getValue(' . v . ')]'; } indexdef(res) ::= DOT varvar(v) AT ID(p). { - res = '['.$this->compiler->compileVariable(v).'->'.p.']'; + $this->compiler->triggerTagNoCache(v); + res = '[$_smarty_tpl->getValue(' . v . ')->'.p.']'; } indexdef(res) ::= DOT ID(i). { @@ -956,9 +996,10 @@ indexdef(res) ::= OPENB INTEGER(n) CLOSEB. { res = '['.n.']'; } indexdef(res) ::= OPENB DOLLARID(i) CLOSEB. { - res = '['.$this->compiler->compileVariable('\''.substr(i,1).'\'').']'; + $this->compiler->triggerTagNoCache(substr(i,1)); + res = '[$_smarty_tpl->getValue(\''.substr(i,1).'\')]'; } -indexdef(res) ::= OPENB variable(v) CLOSEB. { +indexdef(res) ::= OPENB variablevalue(v) CLOSEB. { res = '['.v.']'; } indexdef(res) ::= OPENB value(v) CLOSEB. { @@ -1000,7 +1041,8 @@ varvarele(res) ::= ID(s). { } varvarele(res) ::= SIMPELOUTPUT(i). { $var = trim(substr(i, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' $'); - res = $this->compiler->compileVariable('\''.$var.'\''); + $this->compiler->triggerTagNoCache($var); + res = '$_smarty_tpl->getValue(\''.$var.'\')'; } // variable sections of element @@ -1015,7 +1057,8 @@ object(res) ::= varindexed(vi) objectchain(oc). { if (vi['var'] === '\'smarty\'') { res = (new \Smarty\Compile\SpecialVariableCompiler())->compile(array(),$this->compiler,vi['smarty_internal_index']).oc; } else { - res = $this->compiler->compileVariable(vi['var']).vi['smarty_internal_index'].oc; + $this->compiler->triggerTagNoCache(vi['var']); + res = '$_smarty_tpl->getValue(' . vi['var'] . ')'.vi['smarty_internal_index'].oc; } } @@ -1041,7 +1084,8 @@ objectelement(res)::= PTR varvar(v) arrayindex(a). { if ($this->security) { $this->compiler->trigger_template_error (self::ERR2); } - res = '->{'.$this->compiler->compileVariable(v).a.'}'; + $this->compiler->triggerTagNoCache(v); + res = '->{$_smarty_tpl->getValue(' . v . ')'.a.'}'; } objectelement(res)::= PTR LDEL expr(e) RDEL arrayindex(a). { @@ -1067,8 +1111,41 @@ objectelement(res)::= PTR method(f). { // // function // -function(res) ::= ns1(f) OPENP params(p) CLOSEP. { - res = $this->compiler->compileModifierInExpression(f, p); +function(res) ::= ns1(f) OPENP variablelist(v) CLOSEP. { + + if (f == 'isset') { + res = '(true'; + if (count(v) == 0) { + throw new CompilerException("Invalid number of arguments for isset. isset expects at least one parameter."); + } + foreach (v as $value) { + if (is_array($value)) { + res .= ' && (' . $value[0] . ' && null !== (' . $value[1] . ' ?? null))'; + } else { + res .= ' && (' . $value . ' !== null)'; + } + } + res .= ')'; + } elseif (f == 'empty') { + if (count(v) != 1) { + throw new CompilerException("Invalid number of arguments for empty. empty expects at exactly one parameter."); + } + if (is_array(v[0])) { + res .= '( !' . v[0][0] . ' || empty(' . v[0][1] . '))'; + } else { + res = 'false == ' . v[0]; + } + } else { + $p = array(); + foreach (v as $value) { + if (is_array($value)) { + $p[] = $value[1]; + } else { + $p[] = $value; + } + } + res = $this->compiler->compileModifierInExpression(f, $p); + } } @@ -1087,7 +1164,8 @@ method(res) ::= DOLLARID(f) OPENP params(p) CLOSEP. { $this->compiler->trigger_template_error (self::ERR2); } $prefixVar = $this->compiler->getNewPrefixVariable(); - $this->compiler->appendPrefixCode("compiler->compileVariable('\''.substr(f,1).'\'').';?>'); + $this->compiler->triggerTagNoCache(substr(f,1)); + $this->compiler->appendPrefixCode("getValue('".substr(f,1).'\')'.';?>'); res = $prefixVar .'('. implode(',',p) .')'; } @@ -1282,7 +1360,7 @@ doublequoted(res) ::= doublequotedcontent(o). { res = new Dq($this, o); } -doublequotedcontent(res) ::= BACKTICK variable(v) BACKTICK. { +doublequotedcontent(res) ::= BACKTICK variablevalue(v) BACKTICK. { res = new Code('(string)'.v); } @@ -1294,7 +1372,7 @@ doublequotedcontent(res) ::= DOLLARID(i). { res = new Code('(string)$_smarty_tpl->getValue(\''. substr(i,1) .'\')'); } -doublequotedcontent(res) ::= LDEL variable(v) RDEL. { +doublequotedcontent(res) ::= LDEL variablevalue(v) RDEL. { res = new Code('(string)'.v); } diff --git a/src/Resource/BasePlugin.php b/src/Resource/BasePlugin.php index 56f7dfa..6d22222 100644 --- a/src/Resource/BasePlugin.php +++ b/src/Resource/BasePlugin.php @@ -112,7 +112,7 @@ abstract class BasePlugin * @param Source $source source object * @param Template|null $_template template object */ - abstract public function populate(Source $source, \Smarty\Template $_template = null); + abstract public function populate(Source $source, ?\Smarty\Template $_template = null); /** * populate Source Object with timestamp and exists from Resource diff --git a/src/Resource/CustomPlugin.php b/src/Resource/CustomPlugin.php index b50ef7a..895e971 100644 --- a/src/Resource/CustomPlugin.php +++ b/src/Resource/CustomPlugin.php @@ -50,7 +50,7 @@ abstract class CustomPlugin extends BasePlugin { * @param Source $source source object * @param Template|null $_template template object */ - public function populate(Source $source, Template $_template = null) { + public function populate(Source $source, ?Template $_template = null) { $source->uid = sha1($source->type . ':' . $source->name); $mtime = $this->fetchTimestamp($source->name); if ($mtime !== null) { diff --git a/src/Resource/ExtendsPlugin.php b/src/Resource/ExtendsPlugin.php index acce54e..960e379 100644 --- a/src/Resource/ExtendsPlugin.php +++ b/src/Resource/ExtendsPlugin.php @@ -23,7 +23,7 @@ class ExtendsPlugin extends BasePlugin * * @throws Exception */ - public function populate(Source $source, Template $_template = null) + public function populate(Source $source, ?Template $_template = null) { $uid = ''; $sources = array(); @@ -93,7 +93,11 @@ class ExtendsPlugin extends BasePlugin */ public function getBasename(Source $source) { - return str_replace(':', '.', basename($source->getResourceName())); + $search = array(':'); + if (\Smarty\Smarty::$_IS_WINDOWS) { + $search = array(':', '|'); + } + return str_replace($search, '.', basename($source->getResourceName())); } /* diff --git a/src/Resource/FilePlugin.php b/src/Resource/FilePlugin.php index c595957..0033c83 100644 --- a/src/Resource/FilePlugin.php +++ b/src/Resource/FilePlugin.php @@ -32,7 +32,7 @@ class FilePlugin extends BasePlugin { * * @throws Exception */ - public function populate(Source $source, Template $_template = null) { + public function populate(Source $source, ?Template $_template = null) { $source->uid = sha1( $source->name . ($source->isConfig ? $source->getSmarty()->_joined_config_dir : diff --git a/src/Resource/StreamPlugin.php b/src/Resource/StreamPlugin.php index 91afffd..9b5b3f5 100644 --- a/src/Resource/StreamPlugin.php +++ b/src/Resource/StreamPlugin.php @@ -33,7 +33,7 @@ class StreamPlugin extends RecompiledPlugin { * * @return void */ - public function populate(Source $source, Template $_template = null) { + public function populate(Source $source, ?Template $_template = null) { $source->uid = false; $source->content = $this->getContent($source); $source->timestamp = $source->exists = !!$source->content; diff --git a/src/Resource/StringPlugin.php b/src/Resource/StringPlugin.php index 6b5bee4..fb3692c 100644 --- a/src/Resource/StringPlugin.php +++ b/src/Resource/StringPlugin.php @@ -31,7 +31,7 @@ class StringPlugin extends BasePlugin { * * @return void */ - public function populate(Source $source, Template $_template = null) { + public function populate(Source $source, ?Template $_template = null) { $source->uid = sha1($source->name); $source->timestamp = $source->exists = true; } diff --git a/src/Runtime/DefaultPluginHandlerRuntime.php b/src/Runtime/DefaultPluginHandlerRuntime.php index ad6ed74..f3be85c 100644 --- a/src/Runtime/DefaultPluginHandlerRuntime.php +++ b/src/Runtime/DefaultPluginHandlerRuntime.php @@ -26,7 +26,7 @@ class DefaultPluginHandlerRuntime { $script = null; $cacheable = null; - return (call_user_func_array( + return (\call_user_func_array( $this->defaultPluginHandler, [ $tag, @@ -54,7 +54,7 @@ class DefaultPluginHandlerRuntime { $script = null; $cacheable = null; - if (call_user_func_array( + if (\call_user_func_array( $this->defaultPluginHandler, [ $tag, diff --git a/src/Runtime/InheritanceRuntime.php b/src/Runtime/InheritanceRuntime.php index ffd7aae..74ea854 100644 --- a/src/Runtime/InheritanceRuntime.php +++ b/src/Runtime/InheritanceRuntime.php @@ -162,7 +162,7 @@ class InheritanceRuntime { private function processBlock( Template $tpl, \Smarty\Runtime\Block $block, - \Smarty\Runtime\Block $parent = null + ?\Smarty\Runtime\Block $parent = null ) { if ($block->hide && !isset($block->child)) { return; diff --git a/src/Smarty.php b/src/Smarty.php index a8b6685..15baba8 100644 --- a/src/Smarty.php +++ b/src/Smarty.php @@ -54,7 +54,7 @@ class Smarty extends \Smarty\TemplateBase { /** * smarty version */ - const SMARTY_VERSION = '5.4.0'; + const SMARTY_VERSION = '5.4.3'; /** * define caching modes diff --git a/src/Template.php b/src/Template.php index fcb0f58..242fb23 100644 --- a/src/Template.php +++ b/src/Template.php @@ -115,7 +115,7 @@ class Template extends TemplateBase { public function __construct( $template_resource, Smarty $smarty, - \Smarty\Data $_parent = null, + ?\Smarty\Data $_parent = null, $_cache_id = null, $_compile_id = null, $_caching = null, @@ -248,7 +248,7 @@ class Template extends TemplateBase { $caching, $cache_lifetime, array $extra_vars = [], - int $scope = null, + ?int $scope = null, ?string $currentDir = null ) { @@ -462,7 +462,7 @@ class Template extends TemplateBase { * @return string * @throws Exception */ - public function createCodeFrame($content = '', $functions = '', $cache = false, \Smarty\Compiler\Template $compiler = null) { + public function createCodeFrame($content = '', $functions = '', $cache = false, ?\Smarty\Compiler\Template $compiler = null) { return $this->getCodeFrameCompiler()->create($content, $functions, $cache, $compiler); } diff --git a/src/Template/Source.php b/src/Template/Source.php index 382e710..2c2022e 100644 --- a/src/Template/Source.php +++ b/src/Template/Source.php @@ -134,9 +134,9 @@ class Source { * @throws Exception */ public static function load( - Template $_template = null, - Smarty $smarty = null, - $template_resource = null + ?Template $_template = null, + ?Smarty $smarty = null, + $template_resource = null ) { if ($_template) { $smarty = $_template->getSmarty(); @@ -203,7 +203,7 @@ class Source { */ public function _getDefaultTemplate($default_handler) { $_content = $_timestamp = null; - $_return = call_user_func_array( + $_return = \call_user_func_array( $default_handler, [$this->type, $this->name, &$_content, &$_timestamp, $this->smarty] ); diff --git a/src/TemplateBase.php b/src/TemplateBase.php index 3674edf..f01d110 100644 --- a/src/TemplateBase.php +++ b/src/TemplateBase.php @@ -179,7 +179,7 @@ abstract class TemplateBase extends Data { * @api Smarty::createData() * */ - public function createData(Data $parent = null, $name = null) { + public function createData(?Data $parent = null, $name = null) { /* @var Smarty $smarty */ $smarty = $this->getSmarty(); $dataObj = new Data($parent, $smarty, $name); diff --git a/update/ReadMe.md b/update/ReadMe.md new file mode 100644 index 0000000..8a687d5 --- /dev/null +++ b/update/ReadMe.md @@ -0,0 +1,15 @@ +# Files in this folder must be copied or merged over + +The following files can be copied as is + +- `src/BlockHandler/T.php` +- `src/FunctionHandler/Popup.php` +- `src/FunctionHandler/PopupInit.php` + +The following files need to be checkd for changes. + +If no changes they can be copied, else merged + +- `src/FunctionHandler/HtmlCheckboxes.php` +- `src/FunctionHandler/HtmlOptions.php` +- `src/Extensions/DefaultExtensions.php` diff --git a/update/src/BlockHandler/T.php b/update/src/BlockHandler/T.php new file mode 100644 index 0000000..d04ea6a --- /dev/null +++ b/update/src/BlockHandler/T.php @@ -0,0 +1,238 @@ + + * @throws \Smarty\Exception + */ +class T implements BlockHandlerInterface +{ + /** + * Replaces arguments in a string with their values. + * Arguments are represented by % followed by their number. + * + * @param string $str Source string + * @param mixed mixed Arguments, can be passed in an array or through single variables. + * @return string Modified string + */ + private function smartyGettextStrArg($str/*, $varargs... */) + { + $tr = []; + $p = 0; + + $nargs = func_num_args(); + for ($i = 1; $i < $nargs; $i++) { + $arg = func_get_arg($i); + + if (is_array($arg)) { + foreach ($arg as $aarg) { + $tr['%' . ++$p] = $aarg; + } + } else { + $tr['%' . ++$p] = $arg; + } + } + + return strtr($str, $tr); + } + + /** + * raise a notice for missing callable, indicates L10n functions where not loaded + * + * @param string $function + * @return void + */ + private function reportL10nNotInitialized(string $function): void + { + trigger_error("Missing " . $function . ", L10n::loadFunctions() called?", E_NOTICE); + } + + /** + * main handler + * + * @param array $params + * @param string $content + * @param Template $template + * @param boolean $repeat + * @return void + */ + public function handle($params, $content, Template $template, &$repeat) + { + if (is_null($content)) { + return; + } + + $escape = 'html'; + $plural = null; + $count = null; + $domain = null; + $context = null; + + foreach ($params as $_key => $_value) { + switch ($_key) { + // set escape mode, default html escape + case 'escape': + $escape = (string)$_value; + break; + // set plural parameters 'plural' and 'count'. + case 'plural': + $plural = $_value; + break; + // set count, only for plural, else ignored + case 'count': + $count = $_value; + break; + // get domain param + case 'domain': + $domain = (string)$_value; + break; + // get context param + case 'context': + $context = (string)$_value; + break; + } + } + + // use plural if required parameters are set + if (isset($count) && isset($plural)) { + // plural calls + if (isset($domain) && isset($context)) { + if (is_callable('_dnpgettext')) { + $content = _dnpgettext($domain, $context, $content, $plural, $count); + } else { + $this->reportL10nNotInitialized('_dnpgettext'); + } + } elseif (isset($domain)) { + if (is_callable('_dngettext')) { + $content = _dngettext($domain, $content, $plural, $count); + } else { + $this->reportL10nNotInitialized('_dngettext'); + } + } elseif (isset($context)) { + if (is_callable('_npgettext')) { + $content = _npgettext($context, $content, $plural, $count); + } else { + $this->reportL10nNotInitialized('_npgettext'); + } + } else { + if (is_callable('_ngettext')) { + $content = _ngettext($content, $plural, $count); + } else { + $this->reportL10nNotInitialized('_ngettext'); + } + } + } else { + // use normal + if (isset($domain) && isset($context)) { + if (is_callable('_dpgettext')) { + $content = _dpgettext($domain, $context, $content); + } else { + $this->reportL10nNotInitialized('_dpgettext'); + } + } elseif (isset($domain)) { + if (is_callable('_dgettext')) { + $content = _dgettext($domain, $content); + } else { + $this->reportL10nNotInitialized('_dgettext'); + } + } elseif (isset($context)) { + if (is_callable('_pgettext')) { + $content = _pgettext($context, $content); + } else { + $this->reportL10nNotInitialized('_pgettext'); + } + } else { + if (is_callable('_gettext')) { + $content = _gettext($content); + } else { + $this->reportL10nNotInitialized('_gettext'); + } + } + } + + // run strarg if there are parameters + if (count($params)) { + $content = $this->smartyGettextStrArg($content, $params); + } + + switch ($escape) { + case 'html': + // default + $content = nl2br(htmlspecialchars($content)); + break; + case 'javascript': + case 'js': + // javascript escape + $content = strtr( + $content, + [ + '\\' => '\\\\', + "'" => "\\'", + '"' => '\\"', + "\r" => '\\r', + "\n" => '\\n', + ' '<\/' + ] + ); + break; + case 'url': + // url escape + $content = urlencode($content); + break; + // below is a list for explicit OFF + case 'no': + case 'off': + case 'false': + case '0': + case 0: + // explicit OFF + default: + break; + } + + return $content; + } + + public function isCacheable(): bool + { + return true; + } +} + +// __END__ diff --git a/update/src/Extensions/DefaultExtension.php b/update/src/Extensions/DefaultExtension.php new file mode 100644 index 0000000..156e4ec --- /dev/null +++ b/update/src/Extensions/DefaultExtension.php @@ -0,0 +1,760 @@ +modifiers[$modifier])) { + return $this->modifiers[$modifier]; + } + + switch ($modifier) { + case 'cat': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\CatModifierCompiler(); break; + case 'count_characters': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\CountCharactersModifierCompiler(); break; + case 'count_paragraphs': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\CountParagraphsModifierCompiler(); break; + case 'count_sentences': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\CountSentencesModifierCompiler(); break; + case 'count_words': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\CountWordsModifierCompiler(); break; + case 'default': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\DefaultModifierCompiler(); break; + case 'empty': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\EmptyModifierCompiler(); break; + case 'escape': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\EscapeModifierCompiler(); break; + case 'from_charset': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\FromCharsetModifierCompiler(); break; + case 'indent': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\IndentModifierCompiler(); break; + case 'is_array': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\IsArrayModifierCompiler(); break; + case 'isset': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\IssetModifierCompiler(); break; + case 'json_encode': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\JsonEncodeModifierCompiler(); break; + case 'lower': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\LowerModifierCompiler(); break; + case 'nl2br': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\Nl2brModifierCompiler(); break; + case 'noprint': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\NoPrintModifierCompiler(); break; + case 'raw': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\RawModifierCompiler(); break; + case 'round': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\RoundModifierCompiler(); break; + case 'str_repeat': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\StrRepeatModifierCompiler(); break; + case 'string_format': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\StringFormatModifierCompiler(); break; + case 'strip': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\StripModifierCompiler(); break; + case 'strip_tags': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\StripTagsModifierCompiler(); break; + case 'strlen': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\StrlenModifierCompiler(); break; + case 'substr': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\SubstrModifierCompiler(); break; + case 'to_charset': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\ToCharsetModifierCompiler(); break; + case 'unescape': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\UnescapeModifierCompiler(); break; + case 'upper': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\UpperModifierCompiler(); break; + case 'wordwrap': $this->modifiers[$modifier] = new \Smarty\Compile\Modifier\WordWrapModifierCompiler(); break; + } + + return $this->modifiers[$modifier] ?? null; + } + + public function getModifierCallback(string $modifierName) { + switch ($modifierName) { + case 'capitalize': return [$this, 'smarty_modifier_capitalize']; + case 'count': return [$this, 'smarty_modifier_count']; + case 'date_format': return [$this, 'smarty_modifier_date_format']; + case 'debug_print_var': return [$this, 'smarty_modifier_debug_print_var']; + case 'escape': return [$this, 'smarty_modifier_escape']; + case 'explode': return [$this, 'smarty_modifier_explode']; + case 'implode': return [$this, 'smarty_modifier_implode']; + case 'in_array': return [$this, 'smarty_modifier_in_array']; + case 'join': return [$this, 'smarty_modifier_join']; + case 'mb_wordwrap': return [$this, 'smarty_modifier_mb_wordwrap']; + case 'number_format': return [$this, 'smarty_modifier_number_format']; + case 'regex_replace': return [$this, 'smarty_modifier_regex_replace']; + case 'replace': return [$this, 'smarty_modifier_replace']; + case 'spacify': return [$this, 'smarty_modifier_spacify']; + case 'split': return [$this, 'smarty_modifier_split']; + case 'truncate': return [$this, 'smarty_modifier_truncate']; + } + return null; + } + + public function getFunctionHandler(string $functionName): ?\Smarty\FunctionHandler\FunctionHandlerInterface { + + if (isset($this->functionHandlers[$functionName])) { + return $this->functionHandlers[$functionName]; + } + + switch ($functionName) { + case 'count': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\Count(); break; + case 'counter': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\Counter(); break; + case 'cycle': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\Cycle(); break; + case 'fetch': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\Fetch(); break; + case 'html_checkboxes': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\HtmlCheckboxes(); break; + case 'html_image': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\HtmlImage(); break; + case 'html_options': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\HtmlOptions(); break; + case 'html_radios': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\HtmlRadios(); break; + case 'html_select_date': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\HtmlSelectDate(); break; + case 'html_select_time': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\HtmlSelectTime(); break; + case 'html_table': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\HtmlTable(); break; + case 'mailto': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\Mailto(); break; + case 'math': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\Math(); break; + case 'popup_init': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\PopupInit(); break; + case 'popup': $this->functionHandlers[$functionName] = new \Smarty\FunctionHandler\Popup(); break; + } + + return $this->functionHandlers[$functionName] ?? null; + } + + public function getBlockHandler(string $blockTagName): ?\Smarty\BlockHandler\BlockHandlerInterface { + + switch ($blockTagName) { + case 'textformat': $this->blockHandlers[$blockTagName] = new \Smarty\BlockHandler\TextFormat(); break; + case 't': $this->blockHandlers[$blockTagName] = new \Smarty\BlockHandler\T(); break; + } + + return $this->blockHandlers[$blockTagName] ?? null; + } + + /** + * Smarty spacify modifier plugin + * Type: modifier + * Name: spacify + * Purpose: add spaces between characters in a string + * + * @author Monte Ohrt + * + * @param string $string input string + * @param string $spacify_char string to insert between characters. + * + * @return string + */ + public function smarty_modifier_spacify($string, $spacify_char = ' ') + { + // well… what about charsets besides latin and UTF-8? + return implode($spacify_char, preg_split('//' . \Smarty\Smarty::$_UTF8_MODIFIER, $string, -1, PREG_SPLIT_NO_EMPTY)); + } + + /** + * Smarty capitalize modifier plugin + * Type: modifier + * Name: capitalize + * Purpose: capitalize words in the string + * {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }} + * + * @param string $string string to capitalize + * @param boolean $uc_digits also capitalize "x123" to "X123" + * @param boolean $lc_rest capitalize first letters, lowercase all following letters "aAa" to "Aaa" + * + * @return string capitalized string + * @author Monte Ohrt + * @author Rodney Rehm + */ + public function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false) + { + $string = (string) $string; + + if ($lc_rest) { + // uppercase (including hyphenated words) + $upper_string = mb_convert_case($string, MB_CASE_TITLE, \Smarty\Smarty::$_CHARSET); + } else { + // uppercase word breaks + $upper_string = preg_replace_callback( + "!(^|[^\p{L}'])([\p{Ll}])!S" . \Smarty\Smarty::$_UTF8_MODIFIER, + function ($matches) { + return stripslashes($matches[1]) . + mb_convert_case(stripslashes($matches[2]), MB_CASE_UPPER, \Smarty\Smarty::$_CHARSET); + }, + $string + ); + } + // check uc_digits case + if (!$uc_digits) { + if (preg_match_all( + "!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . \Smarty\Smarty::$_UTF8_MODIFIER, + $string, + $matches, + PREG_OFFSET_CAPTURE + ) + ) { + foreach ($matches[ 1 ] as $match) { + $upper_string = + substr_replace( + $upper_string, + mb_strtolower($match[ 0 ], \Smarty\Smarty::$_CHARSET), + $match[ 1 ], + strlen($match[ 0 ]) + ); + } + } + } + $upper_string = + preg_replace_callback( + "!((^|\s)['\"])(\w)!" . \Smarty\Smarty::$_UTF8_MODIFIER, + function ($matches) { + return stripslashes( + $matches[ 1 ]) . mb_convert_case(stripslashes($matches[ 3 ]), + MB_CASE_UPPER, + \Smarty\Smarty::$_CHARSET + ); + }, + $upper_string + ); + return $upper_string; + } + + /** + * Smarty count modifier plugin + * Type: modifier + * Name: count + * Purpose: counts all elements in an array or in a Countable object + * Input: + * - Countable|array: array or object to count + * - mode: int defaults to 0 for normal count mode, if set to 1 counts recursive + * + * @param mixed $arrayOrObject input array/object + * @param int $mode count mode + * + * @return int + */ + public function smarty_modifier_count($arrayOrObject, $mode = 0) { + /* + * @see https://www.php.net/count + * > Prior to PHP 8.0.0, if the parameter was neither an array nor an object that implements the Countable interface, + * > 1 would be returned, unless value was null, in which case 0 would be returned. + */ + + if ($arrayOrObject instanceof \Countable || is_array($arrayOrObject)) { + return count($arrayOrObject, (int) $mode); + } elseif ($arrayOrObject === null) { + return 0; + } + return 1; + } + + /** + * Smarty date_format modifier plugin + * Type: modifier + * Name: date_format + * Purpose: format datestamps via strftime + * Input: + * - string: input date string + * - format: strftime format for output + * - default_date: default date if $string is empty + * + * @author Monte Ohrt + * + * @param string $string input date string + * @param string $format strftime format for output + * @param string $default_date default date if $string is empty + * @param string $formatter either 'strftime' or 'auto' + * + * @return string |void + * @uses smarty_make_timestamp() + */ + public function smarty_modifier_date_format($string, $format = null, $default_date = '', $formatter = 'auto') + { + if ($format === null) { + $format = \Smarty\Smarty::$_DATE_FORMAT; + } + + if (!empty($string) && $string !== '0000-00-00' && $string !== '0000-00-00 00:00:00') { + $timestamp = smarty_make_timestamp($string); + } elseif (!empty($default_date)) { + $timestamp = smarty_make_timestamp($default_date); + } else { + return; + } + if ($formatter === 'strftime' || ($formatter === 'auto' && strpos($format, '%') !== false)) { + if (\Smarty\Smarty::$_IS_WINDOWS) { + $_win_from = array( + '%D', + '%h', + '%n', + '%r', + '%R', + '%t', + '%T' + ); + $_win_to = array( + '%m/%d/%y', + '%b', + "\n", + '%I:%M:%S %p', + '%H:%M', + "\t", + '%H:%M:%S' + ); + if (strpos($format, '%e') !== false) { + $_win_from[] = '%e'; + $_win_to[] = sprintf('%\' 2d', date('j', $timestamp)); + } + if (strpos($format, '%l') !== false) { + $_win_from[] = '%l'; + $_win_to[] = sprintf('%\' 2d', date('h', $timestamp)); + } + $format = str_replace($_win_from, $_win_to, $format); + } + // @ to suppress deprecation errors when running in PHP8.1 or higher. + return @strftime($format, $timestamp); + } else { + return date($format, $timestamp); + } + } + + /** + * Smarty debug_print_var modifier plugin + * Type: modifier + * Name: debug_print_var + * Purpose: formats variable contents for display in the console + * + * @author Monte Ohrt + * + * @param array|object $var variable to be formatted + * @param int $max maximum recursion depth if $var is an array or object + * @param int $length maximum string length if $var is a string + * @param int $depth actual recursion depth + * @param array $objects processed objects in actual depth to prevent recursive object processing + * + * @return string + */ + public function smarty_modifier_debug_print_var($var, $max = 10, $length = 40, $depth = 0, $objects = array()) + { + $_replace = array("\n" => '\n', "\r" => '\r', "\t" => '\t'); + switch (gettype($var)) { + case 'array': + $results = 'Array (' . count($var) . ')'; + if ($depth === $max) { + break; + } + foreach ($var as $curr_key => $curr_val) { + $results .= '
' . str_repeat(' ', $depth * 2) . '' . strtr($curr_key, $_replace) . + ' => ' . + $this->smarty_modifier_debug_print_var($curr_val, $max, $length, ++$depth, $objects); + $depth--; + } + break; + case 'object': + $object_vars = get_object_vars($var); + $results = '' . get_class($var) . ' Object (' . count($object_vars) . ')'; + if (in_array($var, $objects)) { + $results .= ' called recursive'; + break; + } + if ($depth === $max) { + break; + } + $objects[] = $var; + foreach ($object_vars as $curr_key => $curr_val) { + $results .= '
' . str_repeat(' ', $depth * 2) . ' ->' . strtr($curr_key, $_replace) . + ' = ' . $this->smarty_modifier_debug_print_var($curr_val, $max, $length, ++$depth, $objects); + $depth--; + } + break; + case 'boolean': + case 'NULL': + case 'resource': + if (true === $var) { + $results = 'true'; + } elseif (false === $var) { + $results = 'false'; + } elseif (null === $var) { + $results = 'null'; + } else { + $results = htmlspecialchars((string)$var); + } + $results = '' . $results . ''; + break; + case 'integer': + case 'float': + $results = htmlspecialchars((string)$var); + break; + case 'string': + $results = strtr($var, $_replace); + if (mb_strlen($var, \Smarty\Smarty::$_CHARSET) > $length) { + $results = mb_substr($var, 0, $length - 3, \Smarty\Smarty::$_CHARSET) . '...'; + } + $results = htmlspecialchars('"' . $results . '"', ENT_QUOTES, \Smarty\Smarty::$_CHARSET); + break; + case 'unknown type': + default: + $results = strtr((string)$var, $_replace); + if (mb_strlen($results, \Smarty\Smarty::$_CHARSET) > $length) { + $results = mb_substr($results, 0, $length - 3, \Smarty\Smarty::$_CHARSET) . '...'; + } + $results = htmlspecialchars($results, ENT_QUOTES, \Smarty\Smarty::$_CHARSET); + } + return $results; + } + + /** + * Smarty escape modifier plugin + * Type: modifier + * Name: escape + * Purpose: escape string for output + * + * @author Monte Ohrt + * + * @param string $string input string + * @param string $esc_type escape type + * @param string $char_set character set, used for htmlspecialchars() or htmlentities() + * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities() + * + * @return string escaped input string + */ + public function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) + { + if (!$char_set) { + $char_set = \Smarty\Smarty::$_CHARSET; + } + + $string = (string)$string; + + switch ($esc_type) { + case 'html': + return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); + // no break + case 'htmlall': + $string = mb_convert_encoding($string, 'UTF-8', $char_set); + return htmlentities($string, ENT_QUOTES, 'UTF-8', $double_encode); + // no break + case 'url': + return rawurlencode($string); + case 'urlpathinfo': + return str_replace('%2F', '/', rawurlencode($string)); + case 'quotes': + // escape unescaped single quotes + return preg_replace("%(?mb_to_unicode($string, \Smarty\Smarty::$_CHARSET) as $unicode) { + $return .= '&#x' . strtoupper(dechex($unicode)) . ';'; + } + return $return; + case 'decentity': + $return = ''; + foreach ($this->mb_to_unicode($string, \Smarty\Smarty::$_CHARSET) as $unicode) { + $return .= '&#' . $unicode . ';'; + } + return $return; + case 'javascript': + // escape quotes and backslashes, newlines, etc. + return strtr( + $string, + array( + '\\' => '\\\\', + "'" => "\\'", + '"' => '\\"', + "\r" => '\\r', + "\n" => '\\n', + ' '<\/', + // see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements + '