(BC Break) Change shallow+deep formats to begin with an array of elements
authorTim Otten <totten@civicrm.org>
Sat, 26 Oct 2019 00:14:30 +0000 (17:14 -0700)
committerCiviCRM <info@civicrm.org>
Wed, 16 Sep 2020 02:13:19 +0000 (19:13 -0700)
Before: In the shallow+deep representations of `layout`, the root array
has a `#tag` and `#children`.

After: The root array is just list a list of children.

Comment: This is a more accufrate representation of how HTML partials are
often written.

ext/afform/core/CRM/Afform/ArrayHtml.php
ext/afform/core/Civi/Afform/FormDataModel.php
ext/afform/core/Civi/Api4/Utils/AfformFormatTrait.php
ext/afform/mock/tests/phpunit/api/v4/AfformTest.php
ext/afform/mock/tests/phpunit/api/v4/formatExamples/apple.php
ext/afform/mock/tests/phpunit/api/v4/formatExamples/banana.php
ext/afform/mock/tests/phpunit/api/v4/formatExamples/cherry.php [new file with mode: 0644]
ext/afform/mock/tests/phpunit/api/v4/formatExamples/empty.php [new file with mode: 0644]
ext/afform/mock/tests/phpunit/api/v4/formatExamples/string.php [new file with mode: 0644]

index 1839271f1691b32674ac567750642132792ae385..a3086c514a4469d1fb5c3c8190e532dad6cdb9e1 100644 (file)
@@ -86,6 +86,13 @@ class CRM_Afform_ArrayHtml {
       }
     }
     $buf .= '>';
+    $buf .= $this->convertArraysToHtml($children);
+    $buf .= '</' . $tag . '>';
+    return $buf;
+  }
+
+  public function convertArraysToHtml($children) {
+    $buf = '';
 
     foreach ($children as $child) {
       if (is_string($child)) {
@@ -96,7 +103,6 @@ class CRM_Afform_ArrayHtml {
       }
     }
 
-    $buf .= '</' . $tag . '>';
     return $buf;
   }
 
@@ -118,7 +124,7 @@ class CRM_Afform_ArrayHtml {
 
     foreach ($doc->childNodes as $htmlNode) {
       if ($htmlNode instanceof DOMElement && $htmlNode->tagName === 'html') {
-        return $this->convertNodeToArray($htmlNode->firstChild->firstChild);
+        return $this->convertNodesToArray($htmlNode->firstChild->childNodes);
       }
     }
 
@@ -138,8 +144,8 @@ class CRM_Afform_ArrayHtml {
         $type = $this->pickAttrType($node->tagName, $attribute->name);
         $arr[$attribute->name] = $this->decodeAttrValue($type, $txt);
       }
-      foreach ($node->childNodes as $childNode) {
-        $arr['#children'][] = $this->convertNodeToArray($childNode);
+      if ($node->childNodes->length > 0) {
+        $arr['#children'] = $this->convertNodesToArray($node->childNodes);
       }
       return $arr;
     }
@@ -154,6 +160,19 @@ class CRM_Afform_ArrayHtml {
     }
   }
 
+  /**
+   * @param array|DOMNodeList $nodes
+   *   List of DOMNodes
+   * @return array
+   */
+  protected function convertNodesToArray($nodes) {
+    $children = [];
+    foreach ($nodes as $childNode) {
+      $children[] = $this->convertNodeToArray($childNode);
+    }
+    return $children;
+  }
+
   /**
    * Determine the type of data that is stored in an attribute.
    *
index 03a1413a41e7fa5e4b528bb4e1b2080c8da2b8cb..8b783f4bfc9a97abf0e3d14d38be63181a4e66af 100644 (file)
@@ -26,11 +26,15 @@ class FormDataModel {
    *   Parsed summary of the entities used in a given form.
    */
   public static function create($layout) {
-    $entities = array_column(AHQ::getTags($layout, 'af-entity'), NULL, 'name');
+    $root = [
+      '#tag' => 'root',
+      '#children' => $layout,
+    ];
+    $entities = array_column(AHQ::getTags($root, 'af-entity'), NULL, 'name');
     foreach (array_keys($entities) as $entity) {
       $entities[$entity]['fields'] = [];
     }
-    self::parseFields($layout, $entities);
+    self::parseFields($root, $entities);
 
     $self = new static();
     $self->entities = $entities;
@@ -56,8 +60,8 @@ class FormDataModel {
       elseif ($child['#tag'] == 'af-fieldset' && !empty($child['#children'])) {
         $entities[$child['model']]['fields'] = array_merge($entities[$child['model']]['fields'] ?? [], AHQ::getTags($child, 'af-field'));
       }
-      elseif (!empty($child['#children'])) {
-        self::parseFields($child['#children'], $entities);
+      else {
+        self::parseFields($child, $entities);
       }
     }
   }
index 072528608bd721ccc344be093b6f9a9242e3cce7..7d224a657f684c63747e2e7cd60f005d6d541c65 100644 (file)
@@ -39,7 +39,7 @@ trait AfformFormatTrait {
       return $mixed;
     }
     $converter = new \CRM_Afform_ArrayHtml($this->layoutFormat !== 'shallow');
-    return $converter->convertArrayToHtml($mixed);
+    return $converter->convertArraysToHtml($mixed);
   }
 
 }
index 538e977e5e4a100c788186024d41a67a0a7fffa1..606ac9c29a44032829201271cba63168ee397b42 100644 (file)
@@ -65,7 +65,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase {
   public function getFormatExamples() {
     $es = [];
 
-    foreach (['apple', 'banana'] as $exampleName) {
+    foreach (['empty', 'string', 'apple', 'banana', 'cherry'] as $exampleName) {
       $exampleFile = '/formatExamples/' . $exampleName . '.php';
       $example = require __DIR__ . $exampleFile;
       $formats = ['html', 'shallow', 'deep'];
index e5e41acd24c9eb27df527fc305449841dfc805cc..dc37c5024bd876dfff32bae3962d2431d025cdad 100644 (file)
@@ -2,6 +2,10 @@
 
 return [
   'html' => '<strong>New text!</strong>',
-  'shallow' => ['#tag' => 'strong', '#children' => ['New text!']],
-  'deep' => ['#tag' => 'strong', '#children' => ['New text!']],
+  'shallow' => [
+    ['#tag' => 'strong', '#children' => ['New text!']],
+  ],
+  'deep' => [
+    ['#tag' => 'strong', '#children' => ['New text!']],
+  ],
 ];
index af5c134adf9e891ffd6c3f0a6691749b6bcba423..779b3cd4469cf9528120b4dd44adf5cde0092e70 100644 (file)
@@ -3,17 +3,21 @@
 return [
   'html' => '<div><strong>New text!</strong><af-field name="do_not_sms" defn="{label: \'Do not do any of the emailing\'}"></af-field></div>',
   'shallow' => [
-    '#tag' => 'div',
-    '#children' => [
-      ['#tag' => 'strong', '#children' => ['New text!']],
-      ['#tag' => 'af-field', 'name' => 'do_not_sms', 'defn' => "{label: 'Do not do any of the emailing'}"],
+    [
+      '#tag' => 'div',
+      '#children' => [
+        ['#tag' => 'strong', '#children' => ['New text!']],
+        ['#tag' => 'af-field', 'name' => 'do_not_sms', 'defn' => "{label: 'Do not do any of the emailing'}"],
+      ],
     ],
   ],
   'deep' => [
-    '#tag' => 'div',
-    '#children' => [
-      ['#tag' => 'strong', '#children' => ['New text!']],
-      ['#tag' => 'af-field', 'name' => 'do_not_sms', 'defn' => ['label' => 'Do not do any of the emailing']],
+    [
+      '#tag' => 'div',
+      '#children' => [
+        ['#tag' => 'strong', '#children' => ['New text!']],
+        ['#tag' => 'af-field', 'name' => 'do_not_sms', 'defn' => ['label' => 'Do not do any of the emailing']],
+      ],
     ],
   ],
 ];
diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/cherry.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/cherry.php
new file mode 100644 (file)
index 0000000..879329b
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+
+return [
+  'html' => '<span>First</span> <span>Second</span>',
+  'shallow' => [
+    ['#tag' => 'span', '#children' => ['First']],
+    ' ',
+    ['#tag' => 'span', '#children' => ['Second']],
+  ],
+  'deep' => [
+    ['#tag' => 'span', '#children' => ['First']],
+    ' ',
+    ['#tag' => 'span', '#children' => ['Second']],
+  ],
+];
diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/empty.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/empty.php
new file mode 100644 (file)
index 0000000..e08233a
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+return [
+  'html' => '',
+  'shallow' => [],
+  'deep' => [],
+];
diff --git a/ext/afform/mock/tests/phpunit/api/v4/formatExamples/string.php b/ext/afform/mock/tests/phpunit/api/v4/formatExamples/string.php
new file mode 100644 (file)
index 0000000..18ccc7f
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+return [
+  'html' => 'hello world',
+  'shallow' => ['hello world'],
+  'deep' => ['hello world'],
+];