filter tests passing

This commit is contained in:
Simon Wisselink
2023-01-03 14:12:36 +01:00
parent b9ecf115dd
commit 9766aba66e
14 changed files with 122 additions and 313 deletions

View File

@@ -18,7 +18,7 @@ string
name name
The first argument specifies the type of the filter to load and can be 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. specifies the `name` of the filter plugin.

View File

@@ -11,6 +11,7 @@
namespace Smarty\Compile; namespace Smarty\Compile;
use Smarty\Compile\Tag\Base; use Smarty\Compile\Tag\Base;
use Smarty\Compiler\BaseCompiler;
/** /**
* Smarty Internal Plugin Compile Print Expression Class * Smarty Internal Plugin Compile Print Expression Class
@@ -64,55 +65,33 @@ class PrintExpressionCompiler extends Base {
// display value // display value
if (!$_attr['nofilter']) { if (!$_attr['nofilter']) {
// default modifier // default modifier
if (!empty($compiler->smarty->default_modifiers)) { if ($compiler->smarty->getDefaultModifiers()) {
if (empty($compiler->default_modifier_list)) {
$modifierlist = []; $modifierlist = [];
foreach ($compiler->smarty->default_modifiers as $key => $single_default_modifier) { foreach ($compiler->smarty->getDefaultModifiers() as $key => $single_default_modifier) {
preg_match_all( preg_match_all(
'/(\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|:|[^:]+)/', '/(\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|:|[^:]+)/',
$single_default_modifier, $single_default_modifier,
$mod_array $mod_array
); );
for ($i = 0, $count = count($mod_array[0]); $i < $count; $i++) { for ($i = 0, $count = count($mod_array[0]); $i < $count; $i++) {
if ($mod_array[0][$i] !== ':') { if ($mod_array[0][$i] !== ':') {
$modifierlist[$key][] = $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) { if ($compiler->template->smarty->escape_html) {
$output = "htmlspecialchars((string) {$output}, ENT_QUOTES, '" . addslashes(\Smarty\Smarty::$_CHARSET) . "')"; $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 = "<?php echo {$output};?>\n"; $output = "<?php echo {$output};?>\n";
} }
return $output; return $output;
} }
} }

View File

@@ -20,8 +20,8 @@ class Setfilter extends Base {
* @return string compiled code * @return string compiled code
*/ */
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) { public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
$compiler->variable_filter_stack[] = $compiler->variable_filters; $compiler->variable_filter_stack[] = $compiler->getSmarty()->getAutoModifiers();
$compiler->variable_filters = $parameter['modifier_list']; $compiler->getSmarty()->setAutoModifiers((array) $parameter['modifier_list']);
// this tag does not return compiled code // this tag does not return compiled code
$compiler->has_code = false; $compiler->has_code = false;
return true; return true;

View File

@@ -29,12 +29,12 @@ class SetfilterClose extends Base {
*/ */
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) { public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
$this->getAttributes($compiler, $args); $this->getAttributes($compiler, $args);
// reset variable filter to previous state // reset variable filter to previous state
if (count($compiler->variable_filter_stack)) { $compiler->getSmarty()->setAutoModifiers(
$compiler->variable_filters = array_pop($compiler->variable_filter_stack); count($compiler->variable_filter_stack) ? array_pop($compiler->variable_filter_stack) : []
} else { );
$compiler->variable_filters = [];
}
// this tag does not return compiled code // this tag does not return compiled code
$compiler->has_code = false; $compiler->has_code = false;
return true; return true;

View File

@@ -125,13 +125,6 @@ class Template extends BaseCompiler {
*/ */
public $trace_filepath = ''; public $trace_filepath = '';
/**
* saved preprocessed modifier list
*
* @var mixed
*/
public $default_modifier_list = null;
/** /**
* force compilation of complete template as nocache * force compilation of complete template as nocache
* *
@@ -216,13 +209,6 @@ class Template extends BaseCompiler {
*/ */
public $variable_filter_stack = []; public $variable_filter_stack = [];
/**
* variable filters for {setfilter} {/setfilter}
*
* @var array
*/
public $variable_filters = [];
/** /**
* Nesting count of looping tags like {foreach}, {for}, {section}, {while} * Nesting count of looping tags like {foreach}, {for}, {section}, {while}
* *
@@ -696,7 +682,7 @@ class Template extends BaseCompiler {
* @return callback|null * @return callback|null
* @throws \Smarty\CompilerException * @throws \Smarty\CompilerException
*/ */
public function getPluginFromDefaultHandler($tag, $plugin_type): ?callback { public function getPluginFromDefaultHandler($tag, $plugin_type) {
$defaultPluginHandlerFunc = $this->smarty->getDefaultPluginHandlerFunc(); $defaultPluginHandlerFunc = $this->smarty->getDefaultPluginHandlerFunc();

View File

@@ -214,7 +214,6 @@ class Debug extends Data
$debObj->debug_tpl = $smarty->debug_tpl ?? 'file:' . __DIR__ . '/../debug.tpl'; $debObj->debug_tpl = $smarty->debug_tpl ?? 'file:' . __DIR__ . '/../debug.tpl';
$debObj->registered_resources = array(); $debObj->registered_resources = array();
$debObj->registered_filters = array(); $debObj->registered_filters = array();
$debObj->default_modifiers = array();
$debObj->escape_html = true; $debObj->escape_html = true;
$debObj->caching = \Smarty::CACHING_OFF; $debObj->caching = \Smarty::CACHING_OFF;
$debObj->compile_id = null; $debObj->compile_id = null;

View File

@@ -1806,8 +1806,6 @@ class Smarty extends \Smarty\TemplateBase
return $code; return $code;
} }
/** /**
* Run filters over template output * Run filters over template output
* *
@@ -2130,18 +2128,34 @@ class Smarty extends \Smarty\TemplateBase
*/ */
public function loadFilter($type, $name) { 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 ' . 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 ' . '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); '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()); $this->BCPluginsAdapter->addOutputFilter(new TrimWhitespace());
return true; return true;
} else { }
$_plugin = "smarty_{$type}filter_{$name}";
if (!is_callable($_plugin) && class_exists($_plugin, false)) { $_plugin = "smarty_{$type}filter_{$name}";
$_plugin = [$_plugin, 'execute']; if (!is_callable($_plugin) && class_exists($_plugin, false)) {
} $_plugin = [$_plugin, 'execute'];
} }
if (is_callable($_plugin)) { if (is_callable($_plugin)) {
@@ -2193,6 +2207,14 @@ class Smarty extends \Smarty\TemplateBase
throw new Exception("{$type}filter '{$name}' not callable"); throw new Exception("{$type}filter '{$name}' not callable");
} }
switch ($type) { 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': case 'output':
$this->BCPluginsAdapter->addCallableAsOutputFilter($callback, $name); $this->BCPluginsAdapter->addCallableAsOutputFilter($callback, $name);
break; break;
@@ -2266,5 +2288,53 @@ class Smarty extends \Smarty\TemplateBase
return $this; 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;
}
} }

View File

@@ -343,26 +343,6 @@ abstract class TemplateBase extends Data {
$this->cache_id = $cache_id; $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 * creates a data object
* *
@@ -398,17 +378,6 @@ abstract class TemplateBase extends Data {
return $smarty->debug_tpl; 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 * return a reference to a registered object
@@ -657,20 +626,4 @@ abstract class TemplateBase extends Data {
return $this; 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;
}
} }

View File

@@ -153,7 +153,6 @@ class PHPUnit_Smarty extends PHPUnit\Framework\TestCase
$this->smarty->setCacheDir(__DIR__ . '/cache'); $this->smarty->setCacheDir(__DIR__ . '/cache');
} }
$this->getSmartyObj();
} }
/** /**

View File

@@ -55,6 +55,17 @@ class FilterTest extends PHPUnit_Smarty
$this->assertEquals("hello world", $this->smarty->fetch($tpl)); $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 * test registered output filter not cached
* *
@@ -208,14 +219,14 @@ class FilterTest extends PHPUnit_Smarty
*/ */
public function testLoadedVariableFilter() public function testLoadedVariableFilter()
{ {
$this->smarty->loadFilter("variable", "htmlspecialchars"); $this->smarty->loadFilter(\Smarty\Smarty::FILTER_VARIABLE, "escape");
$tpl = $this->smarty->createTemplate('eval:{$foo}'); $tpl = $this->smarty->createTemplate('eval:{$foo}');
$tpl->assign('foo', '<?php ?>'); $tpl->assign('foo', '<?php ?>');
$this->assertEquals('&lt;?php ?&gt;', $this->smarty->fetch($tpl)); $this->assertEquals('&lt;?php ?&gt;', $this->smarty->fetch($tpl));
} }
/** /**
* test registered post filter * test registered variable filter
*/ */
public function testRegisteredVariableFilter2() public function testRegisteredVariableFilter2()
{ {
@@ -230,7 +241,7 @@ class FilterTest extends PHPUnit_Smarty
Class VarFilter Class VarFilter
{ {
function my_filter($input, $smarty) function my_filter($input)
{ {
return 'var{$foo}' . $input; return 'var{$foo}' . $input;
} }

View File

@@ -1,31 +0,0 @@
<?php
/**
* Smarty PHPunit tests loadFilter method
*
* @package PHPunit
* @author Uwe Tews
*/
/**
* class for loadFilter method tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class LoadFilterTest extends PHPUnit_Smarty
{
public function setUp(): void
{
$this->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']));
}
}

View File

@@ -1,158 +0,0 @@
<?php
/**
* Smarty PHPunit tests register_filter / unregister_filter methods
*
* @package PHPunit
* @author Uwe Tews
*/
/**
* class for register_filter / unregister_filter methods tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*/
class RegisterFilterTest extends PHPUnit_Smarty
{
public function setUp(): void
{
$this->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;
}
}

View File

@@ -11,6 +11,7 @@
*/ */
use Smarty\Template; use Smarty\Template;
use Smarty\Template\Config;
use Smarty\Template\Source; use Smarty\Template\Source;
class Smarty_Resource_Db4 extends Smarty\Resource\BasePlugin 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) public function getContent(Source $source)
{ {
if ($source->is_config) { if ($source instanceof Config) {
return "foo = 'bar'\n"; return "foo = 'bar'\n";
} }

View File

@@ -110,7 +110,7 @@ class ModifierTest extends PHPUnit_Smarty
*/ */
public function testDefaultModifier() public function testDefaultModifier()
{ {
$this->smarty->default_modifiers = array('escape'); $this->smarty->setDefaultModifiers(array('escape'));
$this->smarty->assign('foo', '<bar>'); $this->smarty->assign('foo', '<bar>');
$this->assertEquals('&lt;bar&gt;<bar>', $this->smarty->fetch('testModifier_Default.tpl')); $this->assertEquals('&lt;bar&gt;<bar>', $this->smarty->fetch('testModifier_Default.tpl'));
} }