Define {htxt} filter to allow some extra parameters.
authorTim Otten <totten@civicrm.org>
Tue, 23 May 2023 06:28:32 +0000 (23:28 -0700)
committerTim Otten <totten@civicrm.org>
Tue, 23 May 2023 07:29:58 +0000 (00:29 -0700)
Also: tighten the handling of ' and " to ensure that they are matched properly.

CRM/Core/Smarty/plugins/prefilter.htxtFilter.php
tests/phpunit/CRM/Core/Smarty/plugins/HtxtTest.php

index c7fdac2c207d4797083c736767918c39491ec45e..c731f68c6e95fc9db0d017f11769a9737ef65759 100644 (file)
@@ -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]);
     },
index e662377409f747dfddb1afb58086f045d7094cb9..2ecf4d97385d086aa1c130e108399eab6b47707d 100644 (file)
@@ -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();