From 09e87c6ca66b38af001aa1c8c7d5b87aa44db335 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Wed, 3 Aug 2022 14:32:54 -0400 Subject: [PATCH] Afform - Add autocomplete field --- .../Civi/AfformAdmin/AfformAdminMeta.php | 12 +++- .../Civi/Api4/Action/Afform/LoadAdminData.php | 2 +- .../elements/afGuiField.component.js | 3 +- ext/afform/core/Civi/Afform/FormDataModel.php | 4 +- .../Subscriber/AutocompleteSubscriber.php | 64 +++++++++++++++++++ ext/afform/core/afform.php | 1 + 6 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 ext/afform/core/Civi/Api4/Subscriber/AutocompleteSubscriber.php diff --git a/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php b/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php index a0f4b9061c..566a5d387c 100644 --- a/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php +++ b/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php @@ -87,7 +87,7 @@ class AfformAdminMeta { $params += [ 'checkPermissions' => FALSE, 'loadOptions' => ['id', 'label'], - 'action' => 'create', + 'action' => 'update', 'select' => ['name', 'label', 'input_type', 'input_attrs', 'required', 'options', 'help_pre', 'help_post', 'serialize', 'data_type', 'fk_entity', 'readonly'], 'where' => [['input_type', 'IS NOT NULL']], ]; @@ -123,8 +123,14 @@ class AfformAdminMeta { } // Index by name $fields = array_column($fields, NULL, 'name'); - // Mix in alterations declared by afform entities - if ($params['action'] === 'create') { + if ($params['action'] === 'update') { + // Add existing entity field + $idField = CoreUtil::getIdFieldName($entityName); + $fields[$idField]['readonly'] = FALSE; + $fields[$idField]['input_type'] = 'EntityRef'; + $fields[$idField]['is_id'] = TRUE; + $fields[$idField]['label'] = E::ts('Existing %1', [1 => CoreUtil::getInfoItem($entityName, 'title')]); + // Mix in alterations declared by afform entities $afEntity = self::getMetadata()['entities'][$entityName] ?? []; if (!empty($afEntity['alterFields'])) { foreach ($afEntity['alterFields'] as $fieldName => $changes) { diff --git a/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php b/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php index db70363cdc..1bcba81552 100644 --- a/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php +++ b/ext/afform/admin/Civi/Api4/Action/Afform/LoadAdminData.php @@ -83,7 +83,7 @@ class LoadAdminData extends \Civi\Api4\Generic\AbstractAction { } } - $getFieldsMode = 'create'; + $getFieldsMode = 'update'; // Generate list of possibly embedded afform tags to search for $allAfforms = \Civi::service('afform_scanner')->findFilePaths(); diff --git a/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js b/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js index 0102c32e9b..aacb628252 100644 --- a/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js +++ b/ext/afform/admin/ang/afGuiEditor/elements/afGuiField.component.js @@ -52,7 +52,8 @@ }; this.getFkEntity = function() { - var fkEntity = ctrl.getDefn().fk_entity; + var defn = ctrl.getDefn(), + fkEntity = defn.is_id ? ctrl.container.getMainEntityType() : defn.fk_entity; return ctrl.editor.meta.entities[fkEntity]; }; diff --git a/ext/afform/core/Civi/Afform/FormDataModel.php b/ext/afform/core/Civi/Afform/FormDataModel.php index a368728262..8d99733f8c 100644 --- a/ext/afform/core/Civi/Afform/FormDataModel.php +++ b/ext/afform/core/Civi/Afform/FormDataModel.php @@ -50,7 +50,7 @@ class FormDataModel { $this->entities[$entity]['fields'] = $this->entities[$entity]['joins'] = []; } // Pre-load full list of afforms in case this layout embeds other afform directives - $this->blocks = (array) Afform::get()->setCheckPermissions(FALSE)->setSelect(['name', 'directive_name'])->execute()->indexBy('directive_name'); + $this->blocks = (array) Afform::get(FALSE)->setSelect(['name', 'directive_name'])->execute()->indexBy('directive_name'); $this->parseFields($layout); } @@ -171,7 +171,7 @@ class FormDataModel { // Recurse into embedded blocks if (isset($this->blocks[$node['#tag']])) { if (!isset($this->blocks[$node['#tag']]['layout'])) { - $this->blocks[$node['#tag']] = Afform::get()->setCheckPermissions(FALSE)->setSelect(['name', 'layout'])->addWhere('name', '=', $this->blocks[$node['#tag']]['name'])->execute()->first(); + $this->blocks[$node['#tag']] = Afform::get(FALSE)->setSelect(['name', 'layout'])->addWhere('name', '=', $this->blocks[$node['#tag']]['name'])->execute()->first(); } if (!empty($this->blocks[$node['#tag']]['layout'])) { $this->parseFields($this->blocks[$node['#tag']]['layout'], $entity, $join, $searchDisplay); diff --git a/ext/afform/core/Civi/Api4/Subscriber/AutocompleteSubscriber.php b/ext/afform/core/Civi/Api4/Subscriber/AutocompleteSubscriber.php new file mode 100644 index 0000000000..44c29051e7 --- /dev/null +++ b/ext/afform/core/Civi/Api4/Subscriber/AutocompleteSubscriber.php @@ -0,0 +1,64 @@ + ['onApiPrepare', Events::W_MIDDLE], + ]; + } + + /** + * @param \Civi\API\Event\PrepareEvent $event + * API preparation event. + */ + public function onApiPrepare(\Civi\API\Event\PrepareEvent $event) { + $apiRequest = $event->getApiRequest(); + if (is_object($apiRequest) && is_a($apiRequest, 'Civi\Api4\Generic\AutocompleteAction')) { + $formName = $apiRequest->getFormName(); + if (!$formName || !str_starts_with('afform:', $formName) || !strpos(':', $apiRequest->getFieldName() ?: '')) { + return; + } + [$entityName, $fieldName] = explode(':', $apiRequest->getFieldName()); + // Load afform only if user has permission + $afform = Afform::get() + ->addWhere('name', '=', str_replace('afform:', '', $formName)) + ->addSelect('layout') + ->setLayoutFormat('shallow') + ->execute()->first(); + if (!$afform) { + return; + } + $formDataModel = new FormDataModel($afform['layout']); + $entity = $formDataModel->getEntity($entityName); + $field = $entity['fields'][$fieldName] ?? NULL; + if ($field) { + $apiRequest->setCheckPermissions(empty($field['defn']['bypass_permission'])); + $apiRequest->setSavedSearch($field['defn']['saved_search'] ?? NULL); + } + } + } + +} diff --git a/ext/afform/core/afform.php b/ext/afform/core/afform.php index a0b1100347..a7fc1e3787 100644 --- a/ext/afform/core/afform.php +++ b/ext/afform/core/afform.php @@ -56,6 +56,7 @@ function afform_civicrm_config(&$config) { $dispatcher->addListener('hook_civicrm_alterAngular', ['\Civi\Afform\AfformMetadataInjector', 'preprocess']); $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()); // Register support for email tokens if (CRM_Extension_System::singleton()->getMapper()->isActiveModule('authx')) { -- 2.25.1