APIv4 - Decode output of write operations
authorRich Lott / Artful Robot <forums@artfulrobot.uk>
Mon, 20 Sep 2021 13:52:21 +0000 (14:52 +0100)
committerColeman Watts <coleman@civicrm.org>
Mon, 20 Sep 2021 14:01:53 +0000 (10:01 -0400)
CiviCRM regrettably stores most strings as HTML in the database.
This fixes the output of APIv4 write operations to decode them and return non-html

Civi/Api4/Generic/Traits/DAOActionTrait.php
tests/phpunit/api/v4/Action/ResultTest.php

index 31c889f96537a8fc4d6c0b3335cd0a321c06f971..7e0b356ac219686f8b434327f72aa8e8c2d6c2f5 100644 (file)
@@ -149,6 +149,7 @@ trait DAOActionTrait {
       }
 
       $result[] = $this->baoToArray($createResult, $item);
+      \CRM_Utils_API_HTMLInputCoder::singleton()->decodeRows($result);
     }
 
     // Use bulk `writeRecords` method if the BAO doesn't have a create or add method
index a6ecefae73968893dbddf88f6f52dd2e7de0e999..d9153c07d3c10a47c0da5bd3762a21fbde0c811e 100644 (file)
@@ -34,4 +34,37 @@ class ResultTest extends UnitTestCase {
     $this->assertTrue(is_array(json_decode($json)));
   }
 
+  /**
+   * Knowing that the db layer HTML-encodes strings, we want to test
+   * that this ugliness is hidden from us as users of the API.
+   *
+   * @see https://issues.civicrm.org/jira/browse/CRM-11532
+   * @see https://lab.civicrm.org/dev/core/-/issues/1328
+   */
+  public function testNoDataCorruptionThroughEncoding() {
+
+    $original = 'hello < you';
+    $result = Contact::create(FALSE)
+      ->setValues(['display_name' => $original])
+      ->execute()->first();
+    $this->assertEquals($original, $result['display_name'],
+      "The value returned from Contact.create is different to the value sent."
+    );
+
+    $result = Contact::update(FALSE)
+      ->addWhere('id', '=', $result['id'])
+      ->setValues(['display_name' => $original])
+      ->execute()->first();
+    $this->assertEquals($original, $result['display_name'],
+      "The value returned from Contact.update is different to the value sent."
+    );
+
+    $result = Contact::get(FALSE)
+      ->addWhere('id', '=', $result['id'])
+      ->execute()->first();
+    $this->assertEquals($original, $result['display_name'],
+      "The value returned from Contact.get is different to the value sent."
+    );
+  }
+
 }