From e80c57a12973cf332195178e51707d681e869f01 Mon Sep 17 00:00:00 2001 From: colemanw Date: Sun, 8 Oct 2023 04:14:29 -0400 Subject: [PATCH] Afform - Unify 'is_dashlet', 'is_token' & 'contact_summary' as 'placement' Gathering these items into an option group makes future placement options easy to add, and easy for other extensions to contribute to. --- ang/afform/afsearchTabNote.aff.php | 2 +- ang/afform/afsearchTabRel.aff.php | 2 +- .../Civi/AfformAdmin/AfformAdminMeta.php | 7 ++ ext/afform/admin/ang/afAdmin.js | 2 +- .../ang/afAdmin/afAdminList.controller.js | 9 +- ext/afform/admin/ang/afGuiEditor.js | 2 +- .../ang/afGuiEditor/afGuiEditor.component.js | 12 +- .../admin/ang/afGuiEditor/config-form.html | 43 ++----- ext/afform/core/CRM/Afform/AfformScanner.php | 2 - ext/afform/core/Civi/Afform/Tokens.php | 4 +- ext/afform/core/Civi/Afform/Utils.php | 20 ++++ .../core/Civi/Api4/Action/Afform/Get.php | 19 ++- .../core/Civi/Api4/Action/Afform/Revert.php | 10 +- ext/afform/core/Civi/Api4/Afform.php | 31 ++--- .../core/Civi/Api4/Utils/AfformSaveTrait.php | 17 +-- ext/afform/core/afform.php | 12 +- ext/afform/core/api/v3/Afform.php | 5 +- .../core/managed/AfformPlacement.mgd.php | 109 ++++++++++++++++++ .../Civi/Afform/AfformContactSummaryTest.php | 16 +-- .../Civi/Afform/AfformMetadataTest.php | 2 +- .../mock/tests/phpunit/api/v4/AfformTest.php | 14 +-- ext/civigrant/ang/afsearchTabGrant.aff.php | 2 +- 22 files changed, 222 insertions(+), 120 deletions(-) create mode 100644 ext/afform/core/managed/AfformPlacement.mgd.php diff --git a/ang/afform/afsearchTabNote.aff.php b/ang/afform/afsearchTabNote.aff.php index c22bf3a049..c2a99ba08f 100644 --- a/ang/afform/afsearchTabNote.aff.php +++ b/ang/afform/afsearchTabNote.aff.php @@ -4,7 +4,7 @@ return [ 'type' => 'search', 'title' => ts('Notes'), 'description' => '', - 'contact_summary' => 'tab', + 'placement' => ['contact_summary_tab'], 'summary_weight' => 100, 'icon' => 'fa-sticky-note-o', 'summary_contact_type' => NULL, diff --git a/ang/afform/afsearchTabRel.aff.php b/ang/afform/afsearchTabRel.aff.php index 3eb3cb03ae..43af4f00df 100644 --- a/ang/afform/afsearchTabRel.aff.php +++ b/ang/afform/afsearchTabRel.aff.php @@ -6,7 +6,7 @@ return [ 'permission' => [ 'access CiviCRM', ], - 'contact_summary' => 'tab', + 'placement' => ['contact_summary_tab'], 'icon' => 'fa-handshake-o', 'summary_weight' => 80, 'permission_operator' => 'AND', diff --git a/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php b/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php index cf283b74a7..e1516a21e6 100644 --- a/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php +++ b/ext/afform/admin/Civi/AfformAdmin/AfformAdminMeta.php @@ -13,6 +13,12 @@ class AfformAdminMeta { * @return array */ public static function getAdminSettings() { + $afformPlacement = \CRM_Utils_Array::formatForSelect2((array) \Civi\Api4\OptionValue::get(FALSE) + ->addSelect('value', 'label', 'icon', 'description') + ->addWhere('is_active', '=', TRUE) + ->addWhere('option_group_id:name', '=', 'afform_placement') + ->addOrderBy('weight') + ->execute(), 'label', 'value'); $afformTypes = (array) \Civi\Api4\OptionValue::get(FALSE) ->addSelect('name', 'label', 'icon') ->addWhere('is_active', '=', TRUE) @@ -31,6 +37,7 @@ class AfformAdminMeta { } return [ 'afform_type' => $afformTypes, + 'afform_placement' => $afformPlacement, 'search_operators' => \Civi\Afform\Utils::getSearchOperators(), ]; } diff --git a/ext/afform/admin/ang/afAdmin.js b/ext/afform/admin/ang/afAdmin.js index 8d45473732..af06f68e98 100644 --- a/ext/afform/admin/ang/afAdmin.js +++ b/ext/afform/admin/ang/afAdmin.js @@ -11,7 +11,7 @@ // Load data for lists afforms: function(crmApi4) { return crmApi4('Afform', 'get', { - select: ['name', 'title', 'type', 'server_route', 'is_public', 'submission_count', 'submission_date', 'submit_limit', 'submit_enabled', 'submit_currently_open', 'has_local', 'has_base', 'base_module', 'base_module:label', 'is_dashlet', 'contact_summary:label'] + select: ['name', 'title', 'type', 'server_route', 'is_public', 'submission_count', 'submission_date', 'submit_limit', 'submit_enabled', 'submit_currently_open', 'has_local', 'has_base', 'base_module', 'base_module:label', 'placement:label'] }); } } diff --git a/ext/afform/admin/ang/afAdmin/afAdminList.controller.js b/ext/afform/admin/ang/afAdmin/afAdminList.controller.js index 70c9536f93..621947cf52 100644 --- a/ext/afform/admin/ang/afAdmin/afAdminList.controller.js +++ b/ext/afform/admin/ang/afAdmin/afAdminList.controller.js @@ -24,14 +24,7 @@ this.afforms = _.transform(afforms, function(afforms, afform) { afform.type = afform.type || 'system'; - // Aggregate a couple fields for the "Placement" column - afform.placement = []; - if (afform.is_dashlet) { - afform.placement.push(ts('Dashboard')); - } - if (afform['contact_summary:label']) { - afform.placement.push(afform['contact_summary:label']); - } + afform.placement = afform['placement:label']; if (afform.submission_date) { afform.submission_date = CRM.utils.formatDate(afform.submission_date); } diff --git a/ext/afform/admin/ang/afGuiEditor.js b/ext/afform/admin/ang/afGuiEditor.js index 120798c721..6b52f6228d 100644 --- a/ext/afform/admin/ang/afGuiEditor.js +++ b/ext/afform/admin/ang/afGuiEditor.js @@ -141,7 +141,7 @@ }); }, - meta: CRM.afGuiEditor, + meta: _.extend(CRM.afGuiEditor, CRM.afAdmin), getEntity: function(entityName) { return CRM.afGuiEditor.entities[entityName]; diff --git a/ext/afform/admin/ang/afGuiEditor/afGuiEditor.component.js b/ext/afform/admin/ang/afGuiEditor/afGuiEditor.component.js index 07eb9fabeb..d2279c950f 100644 --- a/ext/afform/admin/ang/afGuiEditor/afGuiEditor.component.js +++ b/ext/afform/admin/ang/afGuiEditor/afGuiEditor.component.js @@ -99,10 +99,10 @@ delete editor.afform.name; delete editor.afform.server_route; delete editor.afform.navigation; - editor.afform.is_dashlet = false; editor.afform.title += ' ' + ts('(copy)'); } editor.afform.icon = editor.afform.icon || 'fa-list-alt'; + editor.afform.placement = editor.afform.placement || []; $scope.canvasTab = 'layout'; $scope.layoutHtml = ''; $scope.entities = {}; @@ -332,14 +332,16 @@ return filter ? _.filter($scope.entities, filter) : _.toArray($scope.entities); }; - this.toggleContactSummary = function() { - if (editor.afform.contact_summary) { - editor.afform.contact_summary = null; + this.isContactSummary = function() { + return editor.afform.placement.includes('contact_summary_block') || editor.afform.placement.includes('contact_summary_tab'); + }; + + this.onChangePlacement = function() { + if (!editor.isContactSummary()) { _.each(editor.searchDisplays, function(searchDisplay) { delete searchDisplay.element.filters; }); } else { - editor.afform.contact_summary = 'block'; _.each(editor.searchDisplays, function(searchDisplay) { var filterOptions = getSearchFilterOptions(searchDisplay.settings); if (filterOptions.length) { diff --git a/ext/afform/admin/ang/afGuiEditor/config-form.html b/ext/afform/admin/ang/afGuiEditor/config-form.html index d18e23cfdc..b439b4c816 100644 --- a/ext/afform/admin/ang/afGuiEditor/config-form.html +++ b/ext/afform/admin/ang/afGuiEditor/config-form.html @@ -43,7 +43,7 @@ - +

{{:: ts('Expose the form as a standalone webpage. (Example: "civicrm/my-form")') }}

@@ -54,14 +54,6 @@ -
- -

{{:: ts('Allows CiviMail authors to easily link to this page') }}

-
-
+ + +

{{:: ts('Additional contexts in which the form can be embedded') }}

+
+ +
- - + +
-
+
- -
-

- {{:: ts('Placement can be configured using the Contact Layout Editor.') }} -

-
- -
- -

{{:: ts('Allow CiviCRM users to add the form to their home dashboard.') }}

diff --git a/ext/afform/core/CRM/Afform/AfformScanner.php b/ext/afform/core/CRM/Afform/AfformScanner.php index 766b66c1b3..5a27b5e71d 100644 --- a/ext/afform/core/CRM/Afform/AfformScanner.php +++ b/ext/afform/core/CRM/Afform/AfformScanner.php @@ -150,9 +150,7 @@ class CRM_Afform_AfformScanner { 'requires' => [], 'title' => '', 'description' => '', - 'is_dashlet' => FALSE, 'is_public' => FALSE, - 'is_token' => FALSE, 'permission' => ['access CiviCRM'], 'type' => 'system', ]; diff --git a/ext/afform/core/Civi/Afform/Tokens.php b/ext/afform/core/Civi/Afform/Tokens.php index aa50defa49..8e4e120c33 100644 --- a/ext/afform/core/Civi/Afform/Tokens.php +++ b/ext/afform/core/Civi/Afform/Tokens.php @@ -176,8 +176,8 @@ class Tokens extends AutoService implements EventSubscriberInterface { */ public static function getTokenForms() { if (!isset(\Civi::$statics[__CLASS__]['tokenForms'])) { - $tokenForms = (array) \Civi\Api4\Afform::get(0) - ->addWhere('is_token', '=', TRUE) + $tokenForms = (array) \Civi\Api4\Afform::get(FALSE) + ->addWhere('placement', 'CONTAINS', 'msg_token') ->addSelect('name', 'title', 'server_route', 'is_public') ->execute() ->indexBy('name'); diff --git a/ext/afform/core/Civi/Afform/Utils.php b/ext/afform/core/Civi/Afform/Utils.php index 613787f0c6..27a0a8ca8c 100644 --- a/ext/afform/core/Civi/Afform/Utils.php +++ b/ext/afform/core/Civi/Afform/Utils.php @@ -78,4 +78,24 @@ class Utils { ]; } + public static function shouldReconcileManaged(array $updatedAfform, array $originalAfform = []): bool { + $isChanged = function($field) use ($updatedAfform, $originalAfform) { + return ($updatedAfform[$field] ?? NULL) !== ($originalAfform[$field] ?? NULL); + }; + + return $isChanged('placement') || + $isChanged('navigation') || + (!empty($updatedAfform['placement']) && $isChanged('title')) || + (!empty($updatedAfform['navigation']) && ($isChanged('title') || $isChanged('permission') || $isChanged('icon') || $isChanged('server_route'))); + } + + public static function shouldClearMenuCache(array $updatedAfform, array $originalAfform = []): bool { + $isChanged = function($field) use ($updatedAfform, $originalAfform) { + return ($updatedAfform[$field] ?? NULL) !== ($originalAfform[$field] ?? NULL); + }; + + return $isChanged('server_route') || + (!empty($updatedAfform['server_route']) && $isChanged('title')); + } + } diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Get.php b/ext/afform/core/Civi/Api4/Action/Afform/Get.php index 6ee8487073..9559b619ae 100644 --- a/ext/afform/core/Civi/Api4/Action/Afform/Get.php +++ b/ext/afform/core/Civi/Api4/Action/Afform/Get.php @@ -91,6 +91,9 @@ class Get extends \Civi\Api4\Generic\BasicGetAction { if ($getSearchDisplays) { $afforms[$name]['search_displays'] = $this->getSearchDisplays($afforms[$name]['layout']); } + if (!isset($afforms[$name]['placement']) && $this->_isFieldSelected('placement')) { + self::convertLegacyPlacement($afforms[$name]); + } } if ($getLayout && $this->layoutFormat !== 'html') { @@ -177,9 +180,7 @@ class Get extends \Civi\Api4\Generic\BasicGetAction { 'requires' => [], 'title' => E::ts('%1 block', [1 => $custom['title']]), 'description' => '', - 'is_dashlet' => FALSE, 'is_public' => FALSE, - 'is_token' => FALSE, 'permission' => ['access CiviCRM'], 'join_entity' => 'Custom_' . $custom['name'], 'entity_type' => $custom['extends'], @@ -216,4 +217,18 @@ class Get extends \Civi\Api4\Generic\BasicGetAction { return $searchDisplays; } + private static function convertLegacyPlacement(array &$afform): void { + $afform['placement'] = []; + if (!empty($afform['is_dashlet'])) { + $afform['placement'][] = 'dashboard_dashlet'; + } + if (!empty($afform['is_token'])) { + $afform['placement'][] = 'msg_token'; + } + if (!empty($afform['contact_summary'])) { + $afform['placement'][] = 'contact_summary_' . $afform['contact_summary']; + } + unset($afform['is_dashlet'], $afform['is_token'], $afform['contact_summary']); + } + } diff --git a/ext/afform/core/Civi/Api4/Action/Afform/Revert.php b/ext/afform/core/Civi/Api4/Action/Afform/Revert.php index a30c2d76b1..d51e39a3b1 100644 --- a/ext/afform/core/Civi/Api4/Action/Afform/Revert.php +++ b/ext/afform/core/Civi/Api4/Action/Afform/Revert.php @@ -2,6 +2,7 @@ namespace Civi\Api4\Action\Afform; +use Civi\Afform\Utils; use Civi\Api4\Generic\Result; use CRM_Afform_ExtensionUtil as E; @@ -65,15 +66,12 @@ class Revert extends \Civi\Api4\Generic\BasicBatchAction { $original = (array) $scanner->getMeta($item['name']); // If the dashlet setting changed, managed entities must be reconciled - if ( - (empty($item['is_dashlet']) !== empty($original['is_dashlet'])) || - ($item['is_dashlet'] && ($item['title'] ?? '') !== ($original['title'] ?? '')) - ) { + if (Utils::shouldReconcileManaged($item, $original)) { $this->flushManaged = TRUE; } // If the server_route changed, reset menu cache - if (($item['server_route'] ?? '') !== ($original['server_route'] ?? '')) { + if (Utils::shouldClearMenuCache($item, $original)) { $this->flushMenu = TRUE; } @@ -86,7 +84,7 @@ class Revert extends \Civi\Api4\Generic\BasicBatchAction { * @return string[] */ protected function getSelect() { - return ['name', 'title', 'is_dashlet', 'server_route']; + return ['name', 'title', 'placement', 'server_route']; } } diff --git a/ext/afform/core/Civi/Api4/Afform.php b/ext/afform/core/Civi/Api4/Afform.php index 83c481a5bf..dfd1f13d0a 100644 --- a/ext/afform/core/Civi/Api4/Afform.php +++ b/ext/afform/core/Civi/Api4/Afform.php @@ -166,28 +166,10 @@ class Afform extends Generic\AbstractEntity { 'title' => E::ts('Description'), ], [ - 'name' => 'is_dashlet', - 'title' => E::ts('Dashboard Dashlet'), - 'data_type' => 'Boolean', - ], - [ - 'name' => 'is_public', - 'title' => E::ts('Is Public'), - 'data_type' => 'Boolean', - ], - [ - 'name' => 'is_token', - 'title' => E::ts('Generate Tokens'), - 'data_type' => 'Boolean', - ], - [ - 'name' => 'contact_summary', - 'title' => E::ts('Contact Summary'), - 'data_type' => 'String', - 'options' => [ - 'block' => E::ts('Contact Summary Block'), - 'tab' => E::ts('Contact Summary Tab'), - ], + 'name' => 'placement', + 'title' => E::ts('Placement'), + 'pseudoconstant' => ['optionGroupName' => 'afform_placement'], + 'data_type' => 'Array', ], [ 'name' => 'summary_contact_type', @@ -209,6 +191,11 @@ class Afform extends Generic\AbstractEntity { 'name' => 'server_route', 'title' => E::ts('Page Route'), ], + [ + 'name' => 'is_public', + 'title' => E::ts('Is Public'), + 'data_type' => 'Boolean', + ], [ 'name' => 'permission', 'title' => E::ts('Permission'), diff --git a/ext/afform/core/Civi/Api4/Utils/AfformSaveTrait.php b/ext/afform/core/Civi/Api4/Utils/AfformSaveTrait.php index 699f3b6498..aae55b4318 100644 --- a/ext/afform/core/Civi/Api4/Utils/AfformSaveTrait.php +++ b/ext/afform/core/Civi/Api4/Utils/AfformSaveTrait.php @@ -2,6 +2,7 @@ namespace Civi\Api4\Utils; +use Civi\Afform\Utils; use CRM_Afform_ExtensionUtil as E; /** @@ -67,24 +68,12 @@ trait AfformSaveTrait { // We may have changed list of files covered by the cache. _afform_clear(); - $isChanged = function($field) use ($item, $orig) { - return ($item[$field] ?? NULL) !== ($orig[$field] ?? NULL); - }; - // If the dashlet or navigation setting changed, managed entities must be reconciled - // TODO: If this list of conditions gets any longer, then - // maybe we should unconditionally reconcile and accept the small performance drag. - if ( - $isChanged('is_dashlet') || - $isChanged('navigation') || - (!empty($meta['is_dashlet']) && $isChanged('title')) || - (!empty($meta['navigation']) && ($isChanged('title') || $isChanged('permission') || $isChanged('icon') || $isChanged('server_route'))) - ) { + if (Utils::shouldReconcileManaged($item, $orig ?? [])) { \CRM_Core_ManagedEntities::singleton()->reconcile(E::LONG_NAME); } - // Right now, permission-checks are completely on-demand. - if ($isChanged('server_route') /* || $isChanged('permission') */) { + if (Utils::shouldClearMenuCache($item, $orig ?? [])) { \CRM_Core_Menu::store(); } diff --git a/ext/afform/core/afform.php b/ext/afform/core/afform.php index 674f44be72..bd812e89a5 100644 --- a/ext/afform/core/afform.php +++ b/ext/afform/core/afform.php @@ -105,7 +105,11 @@ function afform_civicrm_managed(&$entities, $modules) { if (empty($afform['name'])) { continue; } + // Backward-compat with legacy `is_dashlet` if (!empty($afform['is_dashlet'])) { + $afform['placement'][] = 'dashboard_dashlet'; + } + if (in_array('dashboard_dashlet', $afform['placement'] ?? [], TRUE)) { $entities[] = [ 'module' => E::LONG_NAME, 'name' => 'afform_dashlet_' . $afform['name'], @@ -141,7 +145,7 @@ function afform_civicrm_managed(&$entities, $modules) { 'weight' => $afform['navigation']['weight'] ?? 0, 'url' => $afform['server_route'], 'is_active' => 1, - 'icon' => 'crm-i ' . $afform['icon'], + 'icon' => !empty($afform['icon']) ? 'crm-i ' . $afform['icon'] : '', 'domain_id' => $domain['id'], ], 'match' => ['domain_id', 'name'], @@ -174,7 +178,7 @@ function afform_civicrm_tabset($tabsetName, &$tabs, $context) { $contactTypes = array_merge((array) ($context['contact_type'] ?? []), $context['contact_sub_type'] ?? []); $afforms = Civi\Api4\Afform::get(FALSE) ->addSelect('name', 'title', 'icon', 'module_name', 'directive_name', 'summary_contact_type', 'summary_weight') - ->addWhere('contact_summary', '=', 'tab') + ->addWhere('placement', 'CONTAINS', 'contact_summary_tab') ->addOrderBy('title') ->execute(); $weight = 111; @@ -213,7 +217,7 @@ function afform_civicrm_pageRun(&$page) { } $afforms = Civi\Api4\Afform::get(FALSE) ->addSelect('name', 'title', 'icon', 'module_name', 'directive_name', 'summary_contact_type') - ->addWhere('contact_summary', '=', 'block') + ->addWhere('placement', 'CONTAINS', 'contact_summary_block') ->addOrderBy('summary_weight') ->addOrderBy('title') ->execute(); @@ -257,7 +261,7 @@ function afform_civicrm_pageRun(&$page) { function afform_civicrm_contactSummaryBlocks(&$blocks) { $afforms = \Civi\Api4\Afform::get(FALSE) ->setSelect(['name', 'title', 'directive_name', 'module_name', 'type', 'type:icon', 'type:label', 'summary_contact_type']) - ->addWhere('contact_summary', '=', 'block') + ->addWhere('placement', 'CONTAINS', 'contact_summary_block') ->addOrderBy('title') ->execute(); foreach ($afforms as $index => $afform) { diff --git a/ext/afform/core/api/v3/Afform.php b/ext/afform/core/api/v3/Afform.php index fda6038cb5..6c2863cc45 100644 --- a/ext/afform/core/api/v3/Afform.php +++ b/ext/afform/core/api/v3/Afform.php @@ -65,9 +65,8 @@ function _civicrm_api3_afform_get_spec(&$fields) { 'title' => 'Type', 'type' => CRM_Utils_Type::T_STRING, ]; - $fields['is_dashlet'] = [ - 'title' => 'Dashlet', - 'type' => CRM_Utils_Type::T_BOOLEAN, + $fields['placement'] = [ + 'title' => 'Placement', ]; $fields['is_public'] = [ 'title' => 'Public', diff --git a/ext/afform/core/managed/AfformPlacement.mgd.php b/ext/afform/core/managed/AfformPlacement.mgd.php new file mode 100644 index 0000000000..cd95994c63 --- /dev/null +++ b/ext/afform/core/managed/AfformPlacement.mgd.php @@ -0,0 +1,109 @@ + 'AfformPlacement', + 'entity' => 'OptionGroup', + 'update' => 'always', + 'cleanup' => 'always', + 'params' => [ + 'version' => 4, + 'values' => [ + 'name' => 'afform_placement', + 'title' => E::ts('Afform Placement'), + 'is_reserved' => TRUE, + 'is_active' => TRUE, + 'option_value_fields' => [ + 'name', + 'label', + 'icon', + 'description', + ], + ], + 'match' => ['name'], + ], + ], + [ + 'name' => 'AfformPlacement:dashboard_dashlet', + 'entity' => 'OptionValue', + 'cleanup' => 'always', + 'update' => 'always', + 'params' => [ + 'version' => 4, + 'values' => [ + 'option_group_id.name' => 'afform_placement', + 'name' => 'dashboard_dashlet', + 'value' => 'dashboard_dashlet', + 'label' => E::ts('Dashboard Dashlet'), + 'is_reserved' => TRUE, + 'is_active' => TRUE, + 'icon' => 'fa-tachometer', + 'description' => E::ts('Allow CiviCRM users to add the form to their home dashboard.'), + ], + 'match' => ['option_group_id', 'name'], + ], + ], + [ + 'name' => 'AfformPlacement:contact_summary_tab', + 'entity' => 'OptionValue', + 'cleanup' => 'always', + 'update' => 'always', + 'params' => [ + 'version' => 4, + 'values' => [ + 'option_group_id.name' => 'afform_placement', + 'name' => 'contact_summary_tab', + 'value' => 'contact_summary_tab', + 'label' => E::ts('Contact Summary Tab'), + 'is_reserved' => TRUE, + 'is_active' => TRUE, + 'icon' => 'fa-address-card-o', + 'description' => E::ts('Add tab to contact summary page.'), + ], + 'match' => ['option_group_id', 'name'], + ], + ], + [ + 'name' => 'AfformPlacement:contact_summary_block', + 'entity' => 'OptionValue', + 'cleanup' => 'always', + 'update' => 'always', + 'params' => [ + 'version' => 4, + 'values' => [ + 'option_group_id.name' => 'afform_placement', + 'name' => 'contact_summary_block', + 'value' => 'contact_summary_block', + 'label' => E::ts('Contact Summary Block'), + 'is_reserved' => TRUE, + 'is_active' => TRUE, + 'icon' => 'fa-columns', + 'description' => E::ts('Add block to main contact summary tab.'), + ], + 'match' => ['option_group_id', 'name'], + ], + ], + [ + 'name' => 'AfformPlacement:msg_token', + 'entity' => 'OptionValue', + 'cleanup' => 'always', + 'update' => 'always', + 'params' => [ + 'version' => 4, + 'values' => [ + 'option_group_id.name' => 'afform_placement', + 'name' => 'msg_token', + 'value' => 'msg_token', + 'label' => E::ts('Message Tokens'), + 'is_reserved' => TRUE, + 'is_active' => TRUE, + 'icon' => 'fa-code', + 'description' => E::ts('Allows CiviMail authors to easily link to this page'), + ], + 'match' => ['option_group_id', 'name'], + ], + ], +]; diff --git a/ext/afform/core/tests/phpunit/Civi/Afform/AfformContactSummaryTest.php b/ext/afform/core/tests/phpunit/Civi/Afform/AfformContactSummaryTest.php index 0397eba8ac..3fe58995f4 100644 --- a/ext/afform/core/tests/phpunit/Civi/Afform/AfformContactSummaryTest.php +++ b/ext/afform/core/tests/phpunit/Civi/Afform/AfformContactSummaryTest.php @@ -43,25 +43,25 @@ class AfformContactSummaryTest extends TestCase implements HeadlessInterface { Afform::create() ->addValue('name', $this->formNames[0]) ->addValue('title', 'Test B') - ->addValue('contact_summary', 'tab') + ->addValue('placement', ['contact_summary_tab']) ->addValue('summary_contact_type', ['Organization']) ->execute(); Afform::create() ->addValue('name', $this->formNames[1]) ->addValue('title', 'Test C') - ->addValue('contact_summary', 'tab') + ->addValue('placement', ['contact_summary_tab']) ->addValue('summary_contact_type', ['FooBar']) ->addValue('icon', 'smiley-face') ->execute(); Afform::create() ->addValue('name', $this->formNames[2]) ->addValue('title', 'Test A') - ->addValue('contact_summary', 'tab') + ->addValue('placement', ['contact_summary_tab']) ->execute(); Afform::create() ->addValue('name', $this->formNames[3]) ->addValue('title', 'Test D') - ->addValue('contact_summary', 'tab') + ->addValue('placement', ['contact_summary_tab']) ->addValue('summary_contact_type', ['Individual']) ->addValue('summary_weight', 99) ->execute(); @@ -116,14 +116,14 @@ class AfformContactSummaryTest extends TestCase implements HeadlessInterface { ->addValue('name', $this->formNames[0]) ->addValue('title', 'Test B') ->addValue('type', 'search') - ->addValue('contact_summary', 'block') + ->addValue('placement', ['contact_summary_block']) ->addValue('summary_contact_type', ['Individual', 'Household']) ->execute(); Afform::create() ->addValue('name', $this->formNames[1]) ->addValue('title', 'Test C') ->addValue('type', 'form') - ->addValue('contact_summary', 'block') + ->addValue('placement', ['contact_summary_block']) ->addValue('summary_contact_type', ['Farm']) ->addValue('icon', 'smiley-face') ->execute(); @@ -131,13 +131,13 @@ class AfformContactSummaryTest extends TestCase implements HeadlessInterface { ->addValue('name', $this->formNames[2]) ->addValue('type', 'form') ->addValue('title', 'Test A') - ->addValue('contact_summary', 'block') + ->addValue('placement', ['contact_summary_block']) ->execute(); Afform::create() ->addValue('name', $this->formNames[3]) ->addValue('type', 'form') ->addValue('title', 'A Weight Test') - ->addValue('contact_summary', 'block') + ->addValue('placement', ['contact_summary_block']) ->addValue('summary_weight', 99) ->execute(); diff --git a/ext/afform/core/tests/phpunit/Civi/Afform/AfformMetadataTest.php b/ext/afform/core/tests/phpunit/Civi/Afform/AfformMetadataTest.php index 607ee3851a..ed2b0e251a 100644 --- a/ext/afform/core/tests/phpunit/Civi/Afform/AfformMetadataTest.php +++ b/ext/afform/core/tests/phpunit/Civi/Afform/AfformMetadataTest.php @@ -21,7 +21,7 @@ class AfformMetadataTest extends \PHPUnit\Framework\TestCase implements Headless $this->assertEquals(['name', 'label', 'icon', 'description'], $fields['type']['suffixes']); $this->assertTrue($fields['base_module']['options']); - $this->assertTrue($fields['contact_summary']['options']); + $this->assertTrue($fields['placement']['options']); } public function testGetEntityFields():void { diff --git a/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php b/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php index 6b381ed1fa..c087e8ba73 100644 --- a/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php +++ b/ext/afform/mock/tests/phpunit/api/v4/AfformTest.php @@ -31,8 +31,8 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { public function getBasicDirectives() { return [ - ['mockPage', ['title' => '', 'description' => '', 'server_route' => 'civicrm/mock-page', 'permission' => ['access Foobar'], 'is_dashlet' => TRUE, 'submit_enabled' => TRUE]], - ['mockBareFile', ['title' => '', 'description' => '', 'permission' => ['access CiviCRM'], 'is_dashlet' => FALSE, 'submit_enabled' => TRUE]], + ['mockPage', ['title' => '', 'description' => '', 'server_route' => 'civicrm/mock-page', 'permission' => ['access Foobar'], 'placement' => ['dashboard_dashlet'], 'submit_enabled' => TRUE]], + ['mockBareFile', ['title' => '', 'description' => '', 'permission' => ['access CiviCRM'], 'placement' => [], 'submit_enabled' => TRUE]], ['mockFoo', ['title' => '', 'description' => '', 'permission' => ['access CiviCRM']], 'submit_enabled' => TRUE], ['mock-weird-name', ['title' => 'Weird Name', 'description' => '', 'permission' => ['access CiviCRM']], 'submit_enabled' => TRUE], ]; @@ -55,7 +55,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { $dashlet = Dashboard::get(FALSE) ->addWhere('name', '=', $formName) ->execute(); - if (!empty($afform['is_dashlet'])) { + if (in_array('dashboard_dashlet', $afform['placement'] ?? [], TRUE)) { $this->assertCount(1, $dashlet); } else { @@ -73,7 +73,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { $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->assertEquals($get($originalMetadata, 'is_dashlet'), $get($result[0], 'is_dashlet'), $message); + $this->assertEquals($get($originalMetadata, 'placement') ?? [], $get($result[0], 'placement'), $message); $this->assertEquals($get($originalMetadata, 'permission'), $get($result[0], 'permission'), $message); $this->assertTrue(is_array($result[0]['layout']), $message); $this->assertEquals(TRUE, $get($result[0], 'has_base'), $message); @@ -86,7 +86,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { ->addWhere('name', '=', $formName) ->addValue('description', 'The temporary description') ->addValue('permission', ['access foo', 'access bar']) - ->addValue('is_dashlet', empty($originalMetadata['is_dashlet'])) + ->addValue('placement', empty($originalMetadata['placement']) ? ['dashboard_dashlet'] : []) ->execute(); $this->assertEquals($formName, $result[0]['name'], $message); $this->assertEquals('The temporary description', $result[0]['description'], $message); @@ -98,7 +98,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { $this->assertEquals($formName, $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(empty($originalMetadata['is_dashlet']), $get($result[0], 'is_dashlet'), $message); + $this->assertNotEquals($get($originalMetadata, 'placement'), $get($result[0], 'placement'), $message); $this->assertEquals($get($originalMetadata, 'server_route'), $get($result[0], 'server_route'), $message); $this->assertEquals(['access foo', 'access bar'], $get($result[0], 'permission'), $message); $this->assertTrue(is_array($result[0]['layout']), $message); @@ -117,7 +117,7 @@ class api_v4_AfformTest extends api_v4_AfformTestCase { $this->assertEquals($get($originalMetadata, 'description'), $get($result[0], 'description'), $message); $this->assertEquals($get($originalMetadata, 'server_route'), $get($result[0], 'server_route'), $message); $this->assertEquals($get($originalMetadata, 'permission'), $get($result[0], 'permission'), $message); - $this->assertEquals($get($originalMetadata, 'is_dashlet'), $get($result[0], 'is_dashlet'), $message); + $this->assertEquals($get($originalMetadata, 'placement') ?? [], $get($result[0], 'placement'), $message); $this->assertTrue(is_array($result[0]['layout']), $message); $this->assertEquals(TRUE, $get($result[0], 'has_base'), $message); $this->assertEquals(FALSE, $get($result[0], 'has_local'), $message); diff --git a/ext/civigrant/ang/afsearchTabGrant.aff.php b/ext/civigrant/ang/afsearchTabGrant.aff.php index af3297ac2d..ae187701c0 100644 --- a/ext/civigrant/ang/afsearchTabGrant.aff.php +++ b/ext/civigrant/ang/afsearchTabGrant.aff.php @@ -4,7 +4,7 @@ use CRM_Grant_ExtensionUtil as E; return [ 'type' => 'search', 'title' => E::ts('Grants'), - 'contact_summary' => 'tab', + 'placement' => ['contact_summary_tab'], 'summary_weight' => 60, 'icon' => 'fa-money', 'server_route' => '', -- 2.25.1