Afform - Convert Contact Autofill to a Behavior
authorColeman Watts <coleman@civicrm.org>
Sun, 18 Sep 2022 19:29:44 +0000 (15:29 -0400)
committerColeman Watts <coleman@civicrm.org>
Sun, 23 Oct 2022 22:46:26 +0000 (18:46 -0400)
The functionality for autofilling the current user is unchanged, but now encapsulated in a Behavior.

ext/afform/core/Civi/Afform/Behavior/ContactAutofill.php [new file with mode: 0644]
ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php
ext/afform/core/afform.php
ext/afform/core/ang/af/afEntity.component.js
ext/afform/core/info.xml
ext/afform/core/tests/phpunit/Civi/Afform/AfformBehaviorTest.php [new file with mode: 0644]
ext/afform/mock/tests/phpunit/api/v4/AfformContactUsageTest.php

diff --git a/ext/afform/core/Civi/Afform/Behavior/ContactAutofill.php b/ext/afform/core/Civi/Afform/Behavior/ContactAutofill.php
new file mode 100644 (file)
index 0000000..31feeef
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+namespace Civi\Afform\Behavior;
+
+use Civi\Afform\AbstractBehavior;
+use Civi\Afform\Event\AfformPrefillEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use CRM_Afform_ExtensionUtil as E;
+
+class ContactAutofill extends AbstractBehavior implements EventSubscriberInterface {
+
+  /**
+   * @return array
+   */
+  public static function getSubscribedEvents() {
+    return [
+      'civi.afform.prefill' => ['onAfformPrefill', 99],
+    ];
+  }
+
+  public static function getEntities():array {
+    return ['Individual'];
+  }
+
+  public static function getTitle():string {
+    return E::ts('Autofill');
+  }
+
+  public static function getKey():string {
+    // Would be contact-autofill but this supports legacy afforms from before this was converted to a behavior
+    return 'autofill';
+  }
+
+  public static function getDescription():string {
+    return E::ts('Automatically identify this contact');
+  }
+
+  public static function getModes(string $entityName):array {
+    $modes = [];
+    $modes[] = [
+      'name' => 'user',
+      'label' => E::ts('Current User'),
+    ];
+    return $modes;
+  }
+
+  public static function onAfformPrefill(AfformPrefillEvent $event) {
+    if ($event->getEntityType() === 'Contact') {
+      $entity = $event->getEntity();
+      $id = $event->getEntityId();
+      // Autofill with current user
+      if (!$id && ($entity['autofill'] ?? NULL) === 'user') {
+        $id = \CRM_Core_Session::getLoggedInContactID();
+        if ($id) {
+          $event->getApiRequest()->loadEntity($entity, [$id]);
+        }
+      }
+    }
+  }
+
+}
index 323f3e73235a4e3cb529135f2b4f568ecd16e8c4..109e85ba864a820e730ab7323c59a1d92e26dfe6 100644 (file)
@@ -90,9 +90,6 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction {
           $ids = array_slice($ids, 0, !empty($entity['af-repeat']) ? $entity['max'] ?? NULL : 1);
           $this->loadEntity($entity, $ids);
         }
-        elseif (!empty($entity['autofill']) && $this->fillMode !== 'entity') {
-          $this->autofillEntity($entity, $entity['autofill']);
-        }
       }
       $event = new AfformPrefillEvent($this->_afform, $this->_formDataModel, $this, $entity['type'], $entityName, $this->_entityIds);
       \Civi::dispatcher()->dispatch('civi.afform.prefill', $event);
@@ -140,24 +137,6 @@ abstract class AbstractProcessor extends \Civi\Api4\Generic\AbstractAction {
     }
   }
 
-  /**
-   * Fetch an entity based on its autofill settings
-   *
-   * @param $entity
-   * @param $mode
-   */
-  private function autoFillEntity($entity, $mode) {
-    $id = NULL;
-    if ($entity['type'] == 'Contact') {
-      if ($mode == 'user') {
-        $id = \CRM_Core_Session::getLoggedInContactID();
-      }
-    }
-    if ($id) {
-      $this->loadEntity($entity, [$id]);
-    }
-  }
-
   private function validateBySavedSearch($entity, array $ids) {
     $idField = CoreUtil::getIdFieldName($entity['type']);
     $fetched = civicrm_api4($entity['type'], 'autocomplete', [
index f2ad086b76575ce5179757fd8356651ffc7ddea8..c06facd1e81da51cae11d57ba5e14d31f813977d 100644 (file)
@@ -57,6 +57,7 @@ function afform_civicrm_config(&$config) {
   $dispatcher->addListener('hook_civicrm_check', ['\Civi\Afform\StatusChecks', 'hook_civicrm_check']);
   $dispatcher->addListener('civi.afform.get', ['\Civi\Api4\Action\Afform\Get', 'getCustomGroupBlocks']);
   $dispatcher->addSubscriber(new \Civi\Api4\Subscriber\AutocompleteSubscriber());
+  $dispatcher->addSubscriber(new \Civi\Afform\Behavior\ContactAutofill());
 
   // Register support for email tokens
   if (CRM_Extension_System::singleton()->getMapper()->isActiveModule('authx')) {
index c778856ff288fee18fe8dbf4da0115b1f4820da0..8178e2b3136d442c21d678ec2b57f1b747b96e81 100644 (file)
@@ -6,8 +6,7 @@
     data: '=',
     actions: '=',
     modelName: '@name',
-    label: '@',
-    autofill: '@'
+    label: '@'
   };
   // Example usage: <af-form><af-entity name="Person" type="Contact" /> ... <fieldset af-fieldset="Person"> ... </fieldset></af-form>
   angular.module('af').component('afEntity', {
index 9f3d9b79b1d794d144c356deaebddde076b7b6e2..276756a00e53a623f6bb991c55e98baed68f8390 100644 (file)
@@ -23,6 +23,7 @@
     <namespace>CRM/Afform</namespace>
   </civix>
   <classloader>
+    <psr0 prefix="CRM_" path=""/>
     <psr4 prefix="Civi\" path="Civi"/>
     <psr0 prefix="CRM_" path="."/>
   </classloader>
@@ -32,5 +33,6 @@
   <mixins>
     <mixin>ang-php@1.0.0</mixin>
     <mixin>mgd-php@1.1.0</mixin>
+    <mixin>scan-classes@1.0.0</mixin>
   </mixins>
 </extension>
diff --git a/ext/afform/core/tests/phpunit/Civi/Afform/AfformBehaviorTest.php b/ext/afform/core/tests/phpunit/Civi/Afform/AfformBehaviorTest.php
new file mode 100644 (file)
index 0000000..9f5fc6c
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+namespace Civi\Afform;
+
+use Civi\Api4\AfformBehavior;
+use Civi\Test\HeadlessInterface;
+
+/**
+ * @group headless
+ */
+class AfformBehaviorTest extends \PHPUnit\Framework\TestCase implements HeadlessInterface {
+
+  public function setUpHeadless() {
+    return \Civi\Test::headless()->installMe(__DIR__)->apply();
+  }
+
+  public function testGet() {
+    $autofill = AfformBehavior::get(FALSE)
+      ->addWhere('key', '=', 'autofill')
+      ->execute()->single();
+
+    $this->assertContains('user', array_column($autofill['modes']['Individual'], 'name'));
+  }
+
+}
index b3219d514d5fefc00b9d5ced85b82197e29589b0..4d39f297715006f4349641f0f5fdbe16184567da 100644 (file)
@@ -69,6 +69,7 @@ EOHTML;
     $cid = $this->createLoggedInUser();
     CRM_Core_Config::singleton()->userPermissionTemp = new CRM_Core_Permission_Temp();
 
+    // Autofill form with current user. See `Civi\Afform\Behavior\ContactAutofill`
     $prefill = Civi\Api4\Afform::prefill()
       ->setName($this->formName)
       ->execute()