From 9766aba66e015e1ce3bd4861f81fc4ecb6ae99af Mon Sep 17 00:00:00 2001 From: Simon Wisselink Date: Tue, 3 Jan 2023 14:12:36 +0100 Subject: [PATCH] filter tests passing --- .../api-functions/api-load-filter.md | 2 +- src/Compile/PrintExpressionCompiler.php | 57 ++----- src/Compile/Tag/Setfilter.php | 4 +- src/Compile/Tag/SetfilterClose.php | 10 +- src/Compiler/Template.php | 16 +- src/Debug.php | 1 - src/Smarty.php | 86 +++++++++- src/TemplateBase.php | 47 ------ tests/PHPUnit_Smarty.php | 1 - tests/UnitTests/A_Core/Filter/FilterTest.php | 17 +- .../A_Core/Filter/LoadFilterTest.php | 31 ---- .../A_Core/Filter/RegisterFilterTest.php | 158 ------------------ .../PHPunitplugins/resource.db4.php | 3 +- .../ValueTests/Modifier/ModifierTest.php | 2 +- 14 files changed, 122 insertions(+), 313 deletions(-) delete mode 100644 tests/UnitTests/A_Core/Filter/LoadFilterTest.php delete mode 100644 tests/UnitTests/A_Core/Filter/RegisterFilterTest.php diff --git a/docs/programmers/api-functions/api-load-filter.md b/docs/programmers/api-functions/api-load-filter.md index 7e46b131..e2738b0c 100644 --- a/docs/programmers/api-functions/api-load-filter.md +++ b/docs/programmers/api-functions/api-load-filter.md @@ -18,7 +18,7 @@ string name The first argument specifies the type of the filter to load and can be -one of the following: `pre`, `post` or `output`. The second argument +one of the following: `variable`, `pre`, `post` or `output`. The second argument specifies the `name` of the filter plugin. diff --git a/src/Compile/PrintExpressionCompiler.php b/src/Compile/PrintExpressionCompiler.php index 657a4899..90837e67 100644 --- a/src/Compile/PrintExpressionCompiler.php +++ b/src/Compile/PrintExpressionCompiler.php @@ -11,6 +11,7 @@ namespace Smarty\Compile; use Smarty\Compile\Tag\Base; +use Smarty\Compiler\BaseCompiler; /** * Smarty Internal Plugin Compile Print Expression Class @@ -64,55 +65,33 @@ class PrintExpressionCompiler extends Base { // display value if (!$_attr['nofilter']) { // default modifier - if (!empty($compiler->smarty->default_modifiers)) { - if (empty($compiler->default_modifier_list)) { - $modifierlist = []; - foreach ($compiler->smarty->default_modifiers as $key => $single_default_modifier) { - preg_match_all( - '/(\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|:|[^:]+)/', - $single_default_modifier, - $mod_array - ); - for ($i = 0, $count = count($mod_array[0]); $i < $count; $i++) { - if ($mod_array[0][$i] !== ':') { - $modifierlist[$key][] = $mod_array[0][$i]; - } + if ($compiler->smarty->getDefaultModifiers()) { + + $modifierlist = []; + foreach ($compiler->smarty->getDefaultModifiers() as $key => $single_default_modifier) { + preg_match_all( + '/(\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|:|[^:]+)/', + $single_default_modifier, + $mod_array + ); + for ($i = 0, $count = count($mod_array[0]); $i < $count; $i++) { + if ($mod_array[0][$i] !== ':') { + $modifierlist[$key][] = $mod_array[0][$i]; } } - $compiler->default_modifier_list = $modifierlist; } - $output = $compiler->compileModifier($compiler->default_modifier_list, $output); + + $output = $compiler->compileModifier($modifierlist, $output); } - // autoescape html + if ($compiler->template->smarty->escape_html) { $output = "htmlspecialchars((string) {$output}, ENT_QUOTES, '" . addslashes(\Smarty\Smarty::$_CHARSET) . "')"; } - // loop over registered filters - if (!empty($compiler->template->smarty->registered_filters[\Smarty\Smarty::FILTER_VARIABLE])) { - foreach ($compiler->template->smarty->registered_filters[\Smarty\Smarty::FILTER_VARIABLE] as $key => - $function) { - if (!is_array($function)) { - $output = "{$function}({$output},\$_smarty_tpl)"; - } elseif (is_object($function[0])) { - $output = - "\$_smarty_tpl->smarty->registered_filters[\Smarty\Smarty::FILTER_VARIABLE]['{$key}'][0]->{$function[1]}({$output},\$_smarty_tpl)"; - } else { - $output = "{$function[0]}::{$function[1]}({$output},\$_smarty_tpl)"; - } - } - } - foreach ($compiler->variable_filters as $filter) { - if (count($filter) === 1 - && ($result = $this->compile_variable_filter($compiler, $filter[0], $output)) !== false - ) { - $output = $result; - } else { - $output = $compiler->compileModifier([$filter], $output); - } - } + } $output = "\n"; } return $output; } + } diff --git a/src/Compile/Tag/Setfilter.php b/src/Compile/Tag/Setfilter.php index 2564d537..703641db 100644 --- a/src/Compile/Tag/Setfilter.php +++ b/src/Compile/Tag/Setfilter.php @@ -20,8 +20,8 @@ class Setfilter extends Base { * @return string compiled code */ public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) { - $compiler->variable_filter_stack[] = $compiler->variable_filters; - $compiler->variable_filters = $parameter['modifier_list']; + $compiler->variable_filter_stack[] = $compiler->getSmarty()->getAutoModifiers(); + $compiler->getSmarty()->setAutoModifiers((array) $parameter['modifier_list']); // this tag does not return compiled code $compiler->has_code = false; return true; diff --git a/src/Compile/Tag/SetfilterClose.php b/src/Compile/Tag/SetfilterClose.php index a3c22652..9edac780 100644 --- a/src/Compile/Tag/SetfilterClose.php +++ b/src/Compile/Tag/SetfilterClose.php @@ -29,12 +29,12 @@ class SetfilterClose extends Base { */ public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) { $this->getAttributes($compiler, $args); + // reset variable filter to previous state - if (count($compiler->variable_filter_stack)) { - $compiler->variable_filters = array_pop($compiler->variable_filter_stack); - } else { - $compiler->variable_filters = []; - } + $compiler->getSmarty()->setAutoModifiers( + count($compiler->variable_filter_stack) ? array_pop($compiler->variable_filter_stack) : [] + ); + // this tag does not return compiled code $compiler->has_code = false; return true; diff --git a/src/Compiler/Template.php b/src/Compiler/Template.php index 7413850e..10bdd7d3 100644 --- a/src/Compiler/Template.php +++ b/src/Compiler/Template.php @@ -125,13 +125,6 @@ class Template extends BaseCompiler { */ public $trace_filepath = ''; - /** - * saved preprocessed modifier list - * - * @var mixed - */ - public $default_modifier_list = null; - /** * force compilation of complete template as nocache * @@ -216,13 +209,6 @@ class Template extends BaseCompiler { */ public $variable_filter_stack = []; - /** - * variable filters for {setfilter} {/setfilter} - * - * @var array - */ - public $variable_filters = []; - /** * Nesting count of looping tags like {foreach}, {for}, {section}, {while} * @@ -696,7 +682,7 @@ class Template extends BaseCompiler { * @return callback|null * @throws \Smarty\CompilerException */ - public function getPluginFromDefaultHandler($tag, $plugin_type): ?callback { + public function getPluginFromDefaultHandler($tag, $plugin_type) { $defaultPluginHandlerFunc = $this->smarty->getDefaultPluginHandlerFunc(); diff --git a/src/Debug.php b/src/Debug.php index cdeba945..714c8411 100644 --- a/src/Debug.php +++ b/src/Debug.php @@ -214,7 +214,6 @@ class Debug extends Data $debObj->debug_tpl = $smarty->debug_tpl ?? 'file:' . __DIR__ . '/../debug.tpl'; $debObj->registered_resources = array(); $debObj->registered_filters = array(); - $debObj->default_modifiers = array(); $debObj->escape_html = true; $debObj->caching = \Smarty::CACHING_OFF; $debObj->compile_id = null; diff --git a/src/Smarty.php b/src/Smarty.php index 77bbef58..881e7b8b 100644 --- a/src/Smarty.php +++ b/src/Smarty.php @@ -1806,8 +1806,6 @@ class Smarty extends \Smarty\TemplateBase return $code; } - - /** * Run filters over template output * @@ -2130,18 +2128,34 @@ class Smarty extends \Smarty\TemplateBase */ public function loadFilter($type, $name) { + + + if ($type == \Smarty\Smarty::FILTER_VARIABLE) { + foreach ($this->getExtensions() as $extension) { + if ($extension->getModifierCallback($name)) { + + trigger_error('Using Smarty::loadFilter() to load variable filters is deprecated and will ' . + 'be removed in a future release. Use Smarty::addDefaultModifiers() to add a modifier.', + E_USER_DEPRECATED); + + $this->addDefaultModifiers([$name]); + return true; + } + } + } + trigger_error('Using Smarty::loadFilter() to load filters is deprecated and will be ' . 'removed in a future release. Use Smarty::addExtension() to add an extension or Smarty::registerFilter to ' . 'quickly register a filter using a callback function.', E_USER_DEPRECATED); - if ($type == 'output' && $name == 'trimwhitespace') { + if ($type == \Smarty\Smarty::FILTER_OUTPUT && $name == 'trimwhitespace') { $this->BCPluginsAdapter->addOutputFilter(new TrimWhitespace()); return true; - } else { - $_plugin = "smarty_{$type}filter_{$name}"; - if (!is_callable($_plugin) && class_exists($_plugin, false)) { - $_plugin = [$_plugin, 'execute']; - } + } + + $_plugin = "smarty_{$type}filter_{$name}"; + if (!is_callable($_plugin) && class_exists($_plugin, false)) { + $_plugin = [$_plugin, 'execute']; } if (is_callable($_plugin)) { @@ -2193,6 +2207,14 @@ class Smarty extends \Smarty\TemplateBase throw new Exception("{$type}filter '{$name}' not callable"); } switch ($type) { + case 'variable': + $this->registerPlugin(self::PLUGIN_MODIFIER, $name, $callback); + trigger_error('Using Smarty::registerFilter() to register variable filters is deprecated and ' . + 'will be removed in a future release. Use Smarty::addDefaultModifiers() to add a modifier.', + E_USER_DEPRECATED); + + $this->addDefaultModifiers([$name]); + break; case 'output': $this->BCPluginsAdapter->addCallableAsOutputFilter($callback, $name); break; @@ -2266,5 +2288,53 @@ class Smarty extends \Smarty\TemplateBase return $this; } + + /** + * Add default modifiers + * + * @param array|string $modifiers modifier or list of modifiers + * to add + * + * @return \Smarty|\Smarty\Template + * @api Smarty::addDefaultModifiers() + * + */ + public function addDefaultModifiers($modifiers) { + if (is_array($modifiers)) { + $this->default_modifiers = array_merge($this->default_modifiers, $modifiers); + } else { + $this->default_modifiers[] = $modifiers; + } + return $this; + } + + + /** + * Get default modifiers + * + * @return array list of default modifiers + * @api Smarty::getDefaultModifiers() + * + */ + public function getDefaultModifiers() { + return $this->default_modifiers; + } + + /** + * Set default modifiers + * + * @param array|string $modifiers modifier or list of modifiers + * to set + * + * @return TemplateBase + * @api Smarty::setDefaultModifiers() + * + */ + public function setDefaultModifiers($modifiers) { + $this->default_modifiers = (array)$modifiers; + return $this; + } + + } diff --git a/src/TemplateBase.php b/src/TemplateBase.php index a3864aad..87a075f1 100644 --- a/src/TemplateBase.php +++ b/src/TemplateBase.php @@ -343,26 +343,6 @@ abstract class TemplateBase extends Data { $this->cache_id = $cache_id; } - /** - * Add default modifiers - * - * @param array|string $modifiers modifier or list of modifiers - * to add - * - * @return \Smarty|\Smarty\Template - * @api Smarty::addDefaultModifiers() - * - */ - public function addDefaultModifiers($modifiers) { - $smarty = $this->_getSmartyObj(); - if (is_array($modifiers)) { - $smarty->default_modifiers = array_merge($smarty->default_modifiers, $modifiers); - } else { - $smarty->default_modifiers[] = $modifiers; - } - return $this; - } - /** * creates a data object * @@ -398,17 +378,6 @@ abstract class TemplateBase extends Data { return $smarty->debug_tpl; } - /** - * Get default modifiers - * - * @return array list of default modifiers - * @api Smarty::getDefaultModifiers() - * - */ - public function getDefaultModifiers() { - $smarty = $this->_getSmartyObj(); - return $smarty->default_modifiers; - } /** * return a reference to a registered object @@ -657,20 +626,4 @@ abstract class TemplateBase extends Data { return $this; } - /** - * Set default modifiers - * - * @param array|string $modifiers modifier or list of modifiers - * to set - * - * @return TemplateBase - * @api Smarty::setDefaultModifiers() - * - */ - public function setDefaultModifiers($modifiers) { - $smarty = $this->_getSmartyObj(); - $smarty->default_modifiers = (array)$modifiers; - return $this; - } - } diff --git a/tests/PHPUnit_Smarty.php b/tests/PHPUnit_Smarty.php index fc1f6157..95be482f 100644 --- a/tests/PHPUnit_Smarty.php +++ b/tests/PHPUnit_Smarty.php @@ -153,7 +153,6 @@ class PHPUnit_Smarty extends PHPUnit\Framework\TestCase $this->smarty->setCacheDir(__DIR__ . '/cache'); } - $this->getSmartyObj(); } /** diff --git a/tests/UnitTests/A_Core/Filter/FilterTest.php b/tests/UnitTests/A_Core/Filter/FilterTest.php index 1fc49dee..c19feaeb 100644 --- a/tests/UnitTests/A_Core/Filter/FilterTest.php +++ b/tests/UnitTests/A_Core/Filter/FilterTest.php @@ -55,6 +55,17 @@ class FilterTest extends PHPUnit_Smarty $this->assertEquals("hello world", $this->smarty->fetch($tpl)); } + /** + * test unregister output filter + */ + public function testUnRegisterOutputFilter() + { + $this->smarty->registerFilter(\Smarty\Smarty::FILTER_OUTPUT, 'myoutputfilter'); + $this->smarty->unRegisterFilter(\Smarty\Smarty::FILTER_OUTPUT, 'myoutputfilter'); + $tpl = $this->smarty->createTemplate('eval:{"hello world"}'); + $this->assertEquals("hello world", $this->smarty->fetch($tpl)); + } + /** * test registered output filter not cached * @@ -208,14 +219,14 @@ class FilterTest extends PHPUnit_Smarty */ public function testLoadedVariableFilter() { - $this->smarty->loadFilter("variable", "htmlspecialchars"); + $this->smarty->loadFilter(\Smarty\Smarty::FILTER_VARIABLE, "escape"); $tpl = $this->smarty->createTemplate('eval:{$foo}'); $tpl->assign('foo', ''); $this->assertEquals('<?php ?>', $this->smarty->fetch($tpl)); } /** - * test registered post filter + * test registered variable filter */ public function testRegisteredVariableFilter2() { @@ -230,7 +241,7 @@ class FilterTest extends PHPUnit_Smarty Class VarFilter { - function my_filter($input, $smarty) + function my_filter($input) { return 'var{$foo}' . $input; } diff --git a/tests/UnitTests/A_Core/Filter/LoadFilterTest.php b/tests/UnitTests/A_Core/Filter/LoadFilterTest.php deleted file mode 100644 index 223fa1e0..00000000 --- a/tests/UnitTests/A_Core/Filter/LoadFilterTest.php +++ /dev/null @@ -1,31 +0,0 @@ -setUpSmarty(__DIR__); - } - - /** - * test loadFilter method - */ - public function testLoadFilter() - { - $this->smarty->loadFilter('output', 'trimwhitespace'); - $this->assertTrue(is_callable($this->smarty->registered_filters['output']['smarty_outputfilter_trimwhitespace'])); - } -} diff --git a/tests/UnitTests/A_Core/Filter/RegisterFilterTest.php b/tests/UnitTests/A_Core/Filter/RegisterFilterTest.php deleted file mode 100644 index fc1e7550..00000000 --- a/tests/UnitTests/A_Core/Filter/RegisterFilterTest.php +++ /dev/null @@ -1,158 +0,0 @@ -setUpSmarty(__DIR__); - } - - /** - * test register->preFilter method for function - */ - public function testRegisterPrefilterFunction() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_PRE, 'myfilter'); - $this->assertTrue(is_callable($this->smarty->registered_filters['pre']['myfilter'])); - } - - /** - * test register->preFilter method for class method - */ - public function testRegisterPrefiltermethod() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_PRE, array('myfilterclass', 'execute')); - $this->assertTrue(is_callable($this->smarty->registered_filters['pre']['myfilterclass_execute'])); - } - - /** - * test register->preFilter method for class object - */ - public function testRegisterPrefilterObject() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_PRE, array(new myfilterclass, 'execute')); - $this->assertTrue(is_callable($this->smarty->registered_filters['pre']['myfilterclass_execute'])); - } - - /** - * test unregister->preFilter method for function - */ - public function testUnegisterPrefilterFunction() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_PRE, 'myfilter'); - $this->smarty->unregisterFilter(\Smarty\Smarty::FILTER_PRE, 'myfilter'); - $this->assertFalse(isset($this->smarty->registered_filters['pre']['myfilter'])); - } - - /** - * test unregister->preFilter method for class method - */ - public function testUnregisterPrefiltermethod() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_PRE, array('myfilterclass', 'execute')); - $this->smarty->unregisterFilter(\Smarty\Smarty::FILTER_PRE, array('myfilterclass', 'execute')); - $this->assertFalse(isset($this->smarty->registered_filters['pre']['myfilterclass_execute'])); - } - - /** - * test register->postFilter method for function - */ - public function testRegisterPostfilterFunction() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_POST, 'myfilter'); - $this->assertTrue(is_callable($this->smarty->registered_filters['post']['myfilter'])); - } - - /** - * test register->postFilter method for class method - */ - public function testRegisterPostfiltermethod() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_POST, array('myfilterclass', 'execute')); - $this->assertTrue(is_callable($this->smarty->registered_filters['post']['myfilterclass_execute'])); - } - - /** - * test unregister->postFilter method for function - */ - public function testUnegisterPostfilterFunction() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_POST, 'myfilter'); - $this->smarty->unregisterFilter(\Smarty\Smarty::FILTER_POST, 'myfilter'); - $this->assertFalse(isset($this->smarty->registered_filters['post']['myfilter'])); - } - - /** - * test unregister->postFilter method for class method - */ - public function testUnregisterPostfiltermethod() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_POST, array('myfilterclass', 'execute')); - $this->smarty->unregisterFilter(\Smarty\Smarty::FILTER_POST, array('myfilterclass', 'execute')); - $this->assertFalse(isset($this->smarty->registered_filters['post']['myfilterclass_execute'])); - } - - /** - * test register->outputFilter method for function - */ - public function testRegisterOutputfilterFunction() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_OUTPUT, 'myfilter'); - $this->assertTrue(is_callable($this->smarty->registered_filters['output']['myfilter'])); - } - - /** - * test register->outputFilter method for class method - */ - public function testRegisterOutputfiltermethod() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_OUTPUT, array('myfilterclass', 'execute')); - $this->assertTrue(is_callable($this->smarty->registered_filters['output']['myfilterclass_execute'])); - } - - /** - * test unregister->outputFilter method for function - */ - public function testUnegisterOutputfilterFunction() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_OUTPUT, 'myfilter'); - $this->smarty->unregisterFilter(\Smarty\Smarty::FILTER_OUTPUT, 'myfilter'); - $this->assertFalse(isset($this->smarty->registered_filters['output']['myfilter'])); - } - - /** - * test unregister->outputFilter method for class method - */ - public function testUnregisterOutputfiltermethod() - { - $this->smarty->registerFilter(\Smarty\Smarty::FILTER_OUTPUT, array('myfilterclass', 'execute')); - $this->smarty->unregisterFilter(\Smarty\Smarty::FILTER_OUTPUT, array('myfilterclass', 'execute')); - $this->assertFalse(isset($this->smarty->registered_filters['output']['myfilterclass_execute'])); - } -} - -function myfilter($input) -{ - return $input; -} - -class myfilterclass -{ - static function execute($input) - { - return $input; - } -} diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db4.php b/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db4.php index 9cda1754..823c7e5e 100644 --- a/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db4.php +++ b/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db4.php @@ -11,6 +11,7 @@ */ use Smarty\Template; +use Smarty\Template\Config; use Smarty\Template\Source; class Smarty_Resource_Db4 extends Smarty\Resource\BasePlugin @@ -25,7 +26,7 @@ class Smarty_Resource_Db4 extends Smarty\Resource\BasePlugin public function getContent(Source $source) { - if ($source->is_config) { + if ($source instanceof Config) { return "foo = 'bar'\n"; } diff --git a/tests/UnitTests/TemplateSource/ValueTests/Modifier/ModifierTest.php b/tests/UnitTests/TemplateSource/ValueTests/Modifier/ModifierTest.php index c2551c0f..2593f9d5 100644 --- a/tests/UnitTests/TemplateSource/ValueTests/Modifier/ModifierTest.php +++ b/tests/UnitTests/TemplateSource/ValueTests/Modifier/ModifierTest.php @@ -110,7 +110,7 @@ class ModifierTest extends PHPUnit_Smarty */ public function testDefaultModifier() { - $this->smarty->default_modifiers = array('escape'); + $this->smarty->setDefaultModifiers(array('escape')); $this->smarty->assign('foo', ''); $this->assertEquals('<bar>', $this->smarty->fetch('testModifier_Default.tpl')); }