Skip to content

Commit

Permalink
Merge pull request #25101 from colemanw/contactTypeHook
Browse files Browse the repository at this point in the history
Support multiple contact_type in hook_civicrm_tabset
  • Loading branch information
eileenmcnaughton authored Dec 5, 2022
2 parents 4ee60c6 + a6b704f commit 0701a80
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 13 deletions.
8 changes: 8 additions & 0 deletions CRM/Contact/Page/View/Summary.php
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,14 @@ public function getTabs(array $contact) {
];
CRM_Utils_Hook::tabset('civicrm/contact/view', $allTabs, $context);

// Remove any tabs that don't apply to this contact type
foreach (array_keys($allTabs) as $key) {
$tabContactType = (array) ($allTabs[$key]['contact_type'] ?? []);
if ($tabContactType && !in_array($contact['contact_type'], $tabContactType, TRUE)) {
unset($allTabs[$key]);
}
}

$expectedKeys = ['count', 'class', 'template', 'hideCount', 'icon'];

foreach ($allTabs as &$tab) {
Expand Down
33 changes: 23 additions & 10 deletions ext/afform/core/afform.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,21 +214,23 @@ function afform_civicrm_tabset($tabsetName, &$tabs, $context) {
if ($tabsetName !== 'civicrm/contact/view') {
return;
}
$contactTypes = array_merge([$context['contact_type']], $context['contact_sub_type'] ?? []);
$contactTypes = array_merge([$context['contact_type']] ?? [], $context['contact_sub_type'] ?? []);
$afforms = Civi\Api4\Afform::get(FALSE)
->addSelect('name', 'title', 'icon', 'module_name', 'directive_name', 'summary_contact_type')
->addWhere('contact_summary', '=', 'tab')
->addOrderBy('title')
->execute();
$weight = 111;
foreach ($afforms as $afform) {
if (empty($afform['summary_contact_type']) || array_intersect($afform['summary_contact_type'], $contactTypes)) {
$summaryContactType = $afform['summary_contact_type'] ?? [];
if (!$summaryContactType || !$contactTypes || array_intersect($summaryContactType, $contactTypes)) {
$tabs[] = [
'id' => $afform['name'],
'title' => $afform['title'],
'weight' => $weight++,
'icon' => 'crm-i ' . ($afform['icon'] ?: 'fa-list-alt'),
'is_active' => TRUE,
'contact_type' => _afform_get_contact_types($summaryContactType) ?: NULL,
'template' => 'afform/contactSummary/AfformTab.tpl',
'module' => $afform['module_name'],
'directive' => $afform['directive_name'],
Expand Down Expand Up @@ -298,7 +300,6 @@ function afform_civicrm_contactSummaryBlocks(&$blocks) {
->addWhere('contact_summary', '=', 'block')
->addOrderBy('title')
->execute();
$allContactTypes = \CRM_Contact_BAO_ContactType::getAllContactTypes();
foreach ($afforms as $index => $afform) {
// Create a group per afform type
$blocks += [
Expand All @@ -308,17 +309,12 @@ function afform_civicrm_contactSummaryBlocks(&$blocks) {
'blocks' => [],
],
];
$contactType = [];
// If the form specifies contact types, resolve them to just the parent types (Individual, Organization, Household)
// because ContactLayout doesn't care about sub-types
foreach ($afform['summary_contact_type'] ?? [] as $name) {
$parent = $allContactTypes[$name]['parent'] ?? $name;
$contactType[$parent] = $parent;
}
$contactType = _afform_get_contact_types($afform['summary_contact_type'] ?? []);
$blocks["afform_{$afform['type']}"]['blocks'][$afform['name']] = [
'title' => $afform['title'],
// ContactLayout only supports a single contact type
'contact_type' => count($contactType) === 1 ? CRM_Utils_Array::first($contactType) : NULL,
'contact_type' => $contactType ?: NULL,
'tpl_file' => 'afform/contactSummary/AfformBlock.tpl',
'module' => $afform['module_name'],
'directive' => $afform['directive_name'],
Expand All @@ -331,6 +327,23 @@ function afform_civicrm_contactSummaryBlocks(&$blocks) {
}
}

/**
* Resolve a mixed list of contact types and sub-types into just top-level contact types (Individual, Organization, Household)
*
* @param array $mixedTypes
* @return array
* @throws CRM_Core_Exception
*/
function _afform_get_contact_types(array $mixedTypes): array {
$allContactTypes = \CRM_Contact_BAO_ContactType::getAllContactTypes();
$contactTypes = [];
foreach ($mixedTypes as $name) {
$parent = $allContactTypes[$name]['parent'] ?? $name;
$contactTypes[$parent] = $parent;
}
return array_values($contactTypes);
}

/**
* Implements hook_civicrm_angularModules().
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class AfformContactSummaryTest extends \api\v4\Api4TestBase {
'contact_summary_test1',
'contact_summary_test2',
'contact_summary_test3',
'contact_summary_test4',
'contact_summary_test5',
];

public function setUpHeadless() {
Expand Down Expand Up @@ -52,6 +54,16 @@ public function testAfformContactSummaryTab(): void {
->addValue('title', 'Test A')
->addValue('contact_summary', 'tab')
->execute();
Afform::create()
->addValue('name', $this->formNames[3])
->addValue('title', 'Test D')
->addValue('contact_summary', 'tab')
->addValue('summary_contact_type', ['Individual'])
->execute();
Afform::create()
->addValue('name', $this->formNames[4])
->addValue('title', 'Test E')
->execute();

$tabs = [];
$context = [
Expand All @@ -67,7 +79,11 @@ public function testAfformContactSummaryTab(): void {
$this->assertArrayHasKey($this->formNames[1], $tabs);
$this->assertArrayHasKey($this->formNames[2], $tabs);
$this->assertArrayNotHasKey($this->formNames[0], $tabs);
$this->assertArrayHasKey($this->formNames[3], $tabs);
$this->assertArrayNotHasKey($this->formNames[4], $tabs);
$this->assertEquals('Test C', $tabs[$this->formNames[1]]['title']);
$this->assertEquals(['Individual'], $tabs[$this->formNames[1]]['contact_type']);
$this->assertEquals(['Individual'], $tabs[$this->formNames[3]]['contact_type']);
$this->assertEquals('Test A', $tabs[$this->formNames[2]]['title']);
$this->assertEquals('crm-i smiley-face', $tabs[$this->formNames[1]]['icon']);
// Fallback icon
Expand Down Expand Up @@ -132,10 +148,9 @@ public function testAfformContactSummaryBlock(): void {
$blocks = [];
afform_civicrm_contactSummaryBlocks($blocks);

// ContactLayout doesn't support > 1 contact type, so this ought to be null
$this->assertNull($blocks['afform_search']['blocks'][$this->formNames[0]]['contact_type']);
$this->assertEquals(['Individual', 'Household'], $blocks['afform_search']['blocks'][$this->formNames[0]]['contact_type']);
// Sub-type should have been converted to parent type
$this->assertEquals('Organization', $blocks['afform_form']['blocks'][$this->formNames[1]]['contact_type']);
$this->assertEquals(['Organization'], $blocks['afform_form']['blocks'][$this->formNames[1]]['contact_type']);
$this->assertNull($blocks['afform_form']['blocks'][$this->formNames[2]]['contact_type']);
// Forms should be sorted by title
$order = array_flip(array_keys($blocks['afform_form']['blocks']));
Expand Down

0 comments on commit 0701a80

Please sign in to comment.