From bd281af8ff0efa6c13e7e6d1432c0f2ccac94a72 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 22 May 2023 23:28:32 -0700 Subject: [PATCH] Define {htxt} filter to allow some extra parameters. Also: tighten the handling of ' and " to ensure that they are matched properly. --- .../Smarty/plugins/prefilter.htxtFilter.php | 8 +++-- .../CRM/Core/Smarty/plugins/HtxtTest.php | 30 +++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/CRM/Core/Smarty/plugins/prefilter.htxtFilter.php b/CRM/Core/Smarty/plugins/prefilter.htxtFilter.php index c7fdac2c20..c731f68c6e 100644 --- a/CRM/Core/Smarty/plugins/prefilter.htxtFilter.php +++ b/CRM/Core/Smarty/plugins/prefilter.htxtFilter.php @@ -18,11 +18,15 @@ function smarty_prefilter_htxtFilter($tpl_source, &$smarty) { $_htxts = 0; $result = preg_replace_callback_array([ - '/\{htxt id=([\'\"][^\'\"]+[\'\"])/' => function ($m) use (&$htxts) { + '/\{htxt id=(\"[-\w]+\")[ }]/' => function ($m) use (&$htxts) { $htxts++; return sprintf('{if $id == %s}%s', $m[1], $m[0]); }, - '/\{htxt id=(\$\w+)}/' => function ($m) use (&$htxts) { + '/\{htxt id=(\'[-\w]+\')[ }]/' => function ($m) use (&$htxts) { + $htxts++; + return sprintf('{if $id == %s}%s', $m[1], $m[0]); + }, + '/\{htxt id=(\$\w+)[ }]/' => function ($m) use (&$htxts) { $htxts++; return sprintf('{if $id == %s}%s', $m[1], $m[0]); }, diff --git a/tests/phpunit/CRM/Core/Smarty/plugins/HtxtTest.php b/tests/phpunit/CRM/Core/Smarty/plugins/HtxtTest.php index e662377409..2ecf4d9738 100644 --- a/tests/phpunit/CRM/Core/Smarty/plugins/HtxtTest.php +++ b/tests/phpunit/CRM/Core/Smarty/plugins/HtxtTest.php @@ -8,6 +8,7 @@ class CRM_Core_Smarty_plugins_HtxtTest extends CiviUnitTestCase { public function setUp(): void { parent::setUp(); + $this->useTransaction(); require_once 'CRM/Core/Smarty.php'; // Templates should normally be file names, but for unit-testing it's handy to use "string:" notation @@ -18,18 +19,30 @@ class CRM_Core_Smarty_plugins_HtxtTest extends CiviUnitTestCase { /** * @return array */ - public function scopeCases() { + public function supportedCases() { $cases = []; - $cases[] = ['yum yum apple!', '{htxt id="apple"}yum yum apple!{/htxt}', ['id' => 'apple']]; + $cases[] = ['yum yum apple_pie!', '{htxt id="apple_pie"}yum yum apple_pie!{/htxt}', ['id' => 'apple_pie']]; + $cases[] = ['yum yum Apple-Pie!', '{htxt id=\'Apple-Pie\'}yum yum Apple-Pie!{/htxt}', ['id' => 'Apple-Pie']]; + $cases[] = ['yum yum apple!', '{htxt id="apple" other=stuff}yum yum apple!{/htxt}', ['id' => 'apple']]; $cases[] = ['', '{htxt id="apple"}yum yum apple!{/htxt}', ['id' => 'not me']]; $cases[] = ['yum yum banana!', '{htxt id=$dynamic}yum yum {$dynamic}!{/htxt}', ['id' => 'banana', 'dynamic' => 'banana']]; + $cases[] = ['yum yum banana!', '{htxt id=$dynamic other=stuff}yum yum {$dynamic}!{/htxt}', ['id' => 'banana', 'dynamic' => 'banana']]; $cases[] = ['', '{htxt id=$dynamic}yum yum {$dynamic}!{/htxt}', ['id' => 'apple', 'dynamic' => 'banana']]; // More advanced forms of dynamic-id's might be nice, but this is currently the ceiling on what's needed. return $cases; } + public function unsupportedCases() { + $cases = []; + $cases[] = ['{htxt id=$dynamic.zx["$f{b}"]}not supported{/htxt}', []]; + $cases[] = ['{htxt id=\'dragonfruit"}not supported{/htxt}', []]; + $cases[] = ['{htxt id=\'apple\'"banana"]}not supported{/htxt}', []]; + $cases[] = ['{htxt id=\'apple\'.banana]}not supported{/htxt}', []]; + return $cases; + } + /** - * @dataProvider scopeCases + * @dataProvider supportedCases * @param string $expected * @param string $input * @param array $vars @@ -46,11 +59,16 @@ class CRM_Core_Smarty_plugins_HtxtTest extends CiviUnitTestCase { } } - public function testUnsupported() { + /** + * @dataProvider unsupportedCases + * @param string $input + * @param array $vars + */ + public function testUnsupported(string $input, array $vars) { $smarty = CRM_Core_Smarty::singleton(); try { - $smarty->fetch('string:{htxt id=$dynamic.zx["$f{b}"]}power parser!{/htxt}'); - $this->fail("Congratulations, the test failed! You are the road to a better parsing rule."); + $smarty->fetch('string:' . $input); + $this->fail("That should have thrown an error. Are you working on a better parsing rule?"); } catch (Throwable $t) { ob_end_flush(); -- 2.25.1