AfformScanner - Allow loading bare forms
authorTim Otten <totten@civicrm.org>
Sat, 9 Feb 2019 02:43:46 +0000 (21:43 -0500)
committerCiviCRM <info@civicrm.org>
Wed, 16 Sep 2020 02:13:17 +0000 (19:13 -0700)
__Before__: To create an afform, you *must* create both the HTML and JSON file.

__After__: To create an afform, you *must* create the HTML file. You *may* create JSON file.

__Comments__: This enhances developer usability.

ext/afform/core/CRM/Afform/AfformScanner.php
ext/afform/core/Civi/Api4/Action/Afform/Revert.php
ext/afform/mock/ang/afformExamplepage.aff.html
ext/afform/mock/ang/afformExamplepage.aff.json
ext/afform/mock/ang/fakelibBareFile.aff.html [new file with mode: 0644]
ext/afform/mock/ang/fakelibFoo.aff.html
ext/afform/mock/tests/phpunit/api/v4/AfformTest.php

index 6c64f988e0503ca600028a84572392f1d50ec7c7..82a6d40a9193e03cad9abaa6ac51ee939305fb67 100644 (file)
@@ -12,6 +12,10 @@ class CRM_Afform_AfformScanner {
 
   const METADATA_FILE = 'aff.json';
 
+  const LAYOUT_FILE = 'aff.html';
+
+  const FILE_REGEXP = '/\.aff\.(json|html)$/';
+
   const DEFAULT_REQUIRES = 'afformCore';
 
   /**
@@ -122,10 +126,6 @@ class CRM_Afform_AfformScanner {
    */
   public function getMeta($name) {
     // FIXME error checking
-    $metaFile = $this->findFilePath($name, self::METADATA_FILE);
-    if (!$metaFile) {
-      return NULL;
-    }
 
     $defaults = [
       'name' => $name,
@@ -135,7 +135,16 @@ class CRM_Afform_AfformScanner {
       'is_public' => FALSE,
     ];
 
-    return array_merge($defaults, json_decode(file_get_contents($metaFile), 1));
+    $metaFile = $this->findFilePath($name, self::METADATA_FILE);
+    if ($metaFile !== NULL) {
+      return array_merge($defaults, json_decode(file_get_contents($metaFile), 1));
+    }
+    elseif ($this->findFilePath($name, self::LAYOUT_FILE)) {
+      return $defaults;
+    }
+    else {
+      return NULL;
+    }
   }
 
   /**
@@ -164,10 +173,12 @@ class CRM_Afform_AfformScanner {
    *   Lower priority files override higher priority files.
    */
   private function appendFilePaths(&$formPaths, $parent, $priority) {
-    $files = (array) glob("$parent/*." . self::METADATA_FILE);
+    $files = preg_grep(self::FILE_REGEXP, (array) glob("$parent/*"));
+
     foreach ($files as $file) {
-      $name = _afform_angular_module_name(preg_replace('/\.aff\.json$/', '', basename($file)));
-      $formPaths[$name][$priority] = preg_replace('/\.aff\.json$/', '', $file);
+      $fileBase = preg_replace(self::FILE_REGEXP, '', $file);
+      $name = _afform_angular_module_name(basename($fileBase));
+      $formPaths[$name][$priority] = $fileBase;
       ksort($formPaths[$name]);
     }
   }
@@ -184,4 +195,15 @@ class CRM_Afform_AfformScanner {
     return Civi::paths()->getPath('[civicrm.files]/ang');
   }
 
+  /**
+   * @return string
+   */
+  private function getMarkerRegexp() {
+    static $v;
+    if ($v === NULL) {
+      $v = '/\.(' . preg_quote(self::LAYOUT_FILE, '/') . '|' . preg_quote(self::METADATA_FILE, '/') . ')$/';
+    }
+    return $v;
+  }
+
 }
index 895890adfec363ecabdefdc96bd6f4baec15fc62..f194e6f1753803dbdc6ebdf7882ced8cb1c7ff77 100644 (file)
@@ -13,7 +13,7 @@ class Revert extends Get {
 
     parent::_run($result);
 
-    $files = [\CRM_Afform_AfformScanner::METADATA_FILE, 'aff.html'];
+    $files = [\CRM_Afform_AfformScanner::METADATA_FILE, \CRM_Afform_AfformScanner::LAYOUT_FILE];
 
     foreach ($result as $afform) {
       foreach ($files as $file) {
index f5272396877e1d76d423b3e8406580aa9ec41c2d..7e18ff54409e9adee188f3b19f84f4073b6d7288 100644 (file)
@@ -1,2 +1,3 @@
 <div>Hello {{routeParams.name}}.</div>
 <div>The foo says "<span fakelib-foo/>".</div>
+<div>The bare file says "<span fakelib-bare-file/>"</div>
\ No newline at end of file
index 355d29cf622061179e3a48fac2b95ea056342fc0..5aad8afd2c1ddeaa93e7843345ed027c7b618f3c 100644 (file)
@@ -1 +1 @@
-{"server_route": "civicrm/example-page", "requires":["fakelibFoo"]}
+{"server_route": "civicrm/example-page", "requires":["fakelibFoo", "fakelibBareFile"]}
diff --git a/ext/afform/mock/ang/fakelibBareFile.aff.html b/ext/afform/mock/ang/fakelibBareFile.aff.html
new file mode 100644 (file)
index 0000000..15827e4
--- /dev/null
@@ -0,0 +1 @@
+<em>This is just an HTML file without any metadata.</em>
index 996cbd8d81fa169e77b6f3cd140cf442ac168049..b32d06d7f847315137d2fb3ba15943139e5e84e3 100644 (file)
@@ -1 +1 @@
-the foo bar stuff
\ No newline at end of file
+<em>the foo bar stuff</em>
\ No newline at end of file
index fed12e8c5a1eab2b44519d46926d61de2334f57f..97d7da937e94c4cc0e61565e09430813563f5581 100644 (file)
@@ -37,45 +37,56 @@ class api_v4_AfformTest extends \PHPUnit_Framework_TestCase implements HeadlessI
     parent::tearDown();
   }
 
+  public function getBasicDirectives() {
+    return [
+      ['afformExamplepage', ['title' => '', 'description' => '', 'server_route' => 'civicrm/example-page']],
+      ['fakelibBareFile', ['title' => '', 'description' => '']],
+      ['fakelibFoo', ['title' => '', 'description' => '']],
+    ];
+  }
+
   /**
    * This takes the bundled `examplepage` and performs some API calls on it.
+   * @dataProvider getBasicDirectives
    */
-  public function testGetUpdateRevert() {
-    Civi\Api4\Afform::revert()->addWhere('name', '=', 'afformExamplepage')->execute();
+  public function testGetUpdateRevert($directiveName, $originalMetadata) {
+    $get = function($arr, $key) {
+      return isset($arr[$key]) ? $arr[$key] : NULL;
+    };
+
+    Civi\Api4\Afform::revert()->addWhere('name', '=', $directiveName)->execute();
 
     $message = 'The initial Afform.get should return default data';
-    $result = Civi\Api4\Afform::get()->addWhere('name', '=', 'afformExamplepage')->execute();
-    $result->indexBy('name');
-    $b = (array) $result;
-    $this->assertEquals('afformExamplepage', $result['afformExamplepage']['name'], $message);
-    $this->assertEquals('', $result['afformExamplepage']['title'], $message);
-    $this->assertEquals('', $result['afformExamplepage']['description'], $message);
-    $this->assertEquals('civicrm/example-page', $result['afformExamplepage']['server_route'], $message);
-    $this->assertTrue(is_array($result['afformExamplepage']['layout']), $message);
+    $result = Civi\Api4\Afform::get()->addWhere('name', '=', $directiveName)->execute();
+    $this->assertEquals($directiveName, $result[0]['name'], $message);
+    $this->assertEquals($get($originalMetadata, 'title'), $get($result[0], 'title'), $message);
+    $this->assertEquals($get($originalMetadata, 'description'), $get($result[0], 'description'), $message);
+    $this->assertEquals($get($originalMetadata, 'server_route'), $get($result[0], 'server_route'), $message);
+    $this->assertTrue(is_array($result[0]['layout']), $message);
 
     $message = 'After updating with Afform.create, the revised data should be returned';
     $result = Civi\Api4\Afform::update()
-      ->addWhere('name', '=', 'afformExamplepage')
+      ->addWhere('name', '=', $directiveName)
       ->addValue('description', 'The temporary description')
       ->execute();
-    $this->assertEquals('afformExamplepage', $result[0]['name'], $message);
+    $this->assertEquals($directiveName, $result[0]['name'], $message);
     $this->assertEquals('The temporary description', $result[0]['description'], $message);
 
     $message = 'After updating, the Afform.get API should return blended data';
-    $result = Civi\Api4\Afform::get()->addWhere('name', '=', 'afformExamplepage')->execute();
-    $this->assertEquals('afformExamplepage', $result[0]['name'], $message);
-    $this->assertEquals('', $result[0]['title'], $message);
-    $this->assertEquals('The temporary description', $result[0]['description'], $message);
-    $this->assertEquals('civicrm/example-page', $result[0]['server_route'], $message);
+    $result = Civi\Api4\Afform::get()->addWhere('name', '=', $directiveName)->execute();
+    $this->assertEquals($directiveName, $result[0]['name'], $message);
+    $this->assertEquals($get($originalMetadata, 'title'), $get($result[0], 'title'), $message);
+    $this->assertEquals('The temporary description', $get($result[0], 'description'), $message);
+    $this->assertEquals($get($originalMetadata, 'server_route'), $get($result[0], 'server_route'), $message);
     $this->assertTrue(is_array($result[0]['layout']), $message);
 
-    Civi\Api4\Afform::revert()->addWhere('name', '=', 'afformExamplepage')->execute();
-    $message = 'After reverting, te final Afform.get should return default data';
-    $result = Civi\Api4\Afform::get()->addWhere('name', '=', 'afformExamplepage')->execute();
-    $this->assertEquals('afformExamplepage', $result[0]['name'], $message);
-    $this->assertEquals('', $result[0]['title'], $message);
-    $this->assertEquals('', $result[0]['description'], $message);
-    $this->assertEquals('civicrm/example-page', $result[0]['server_route'], $message);
+    Civi\Api4\Afform::revert()->addWhere('name', '=', $directiveName)->execute();
+    $message = 'After reverting, the final Afform.get should return default data';
+    $result = Civi\Api4\Afform::get()->addWhere('name', '=', $directiveName)->execute();
+    $this->assertEquals($directiveName, $result[0]['name'], $message);
+    $this->assertEquals($get($originalMetadata, 'title'), $get($result[0], 'title'), $message);
+    $this->assertEquals($get($originalMetadata, 'description'), $get($result[0], 'description'), $message);
+    $this->assertEquals($get($originalMetadata, 'server_route'), $get($result[0], 'server_route'), $message);
     $this->assertTrue(is_array($result[0]['layout']), $message);
   }