Hierarchical groups don't always get the correct group IDs in a "groups" profile field
When you have a profile with the "Groups" field, under certain circumstances the wrong group IDs get assigned to the various input elements - so folks are subscribed to the wrong group. In some scenarios, where the group ID doesn't exist, you get a constraint violation.
I'm having some trouble replicating this on a test site, so while I have a fix, I don't have a test yet.
The issue lies somewhere in CRM_Contact_BAO_Group::getGroupsHierarchy()
, which returns an array of groups where the key is (usually) the group's ID. Under certain circumstances they return in an incorrect order.
I don't have time at present to track it down, so I'm just posting a patch here in case others find the issue. If I have time to find the exact set of circumstances that lead to this issue, I'll write a test and submit a PR.
diff --git a/sites/all/modules/civicrm/CRM/Contact/Form/Edit/TagsAndGroups.php b/sites/all/modules/civicrm/CRM/Contact/Form/Edit/TagsAndGroups.php
index 9299246d..361311dc 100644
--- a/sites/all/modules/civicrm/CRM/Contact/Form/Edit/TagsAndGroups.php
+++ b/sites/all/modules/civicrm/CRM/Contact/Form/Edit/TagsAndGroups.php
@@ -93,7 +93,7 @@ class CRM_Contact_Form_Edit_TagsAndGroups {
$attributes['skiplabel'] = TRUE;
$elements = [];
$groupsOptions = [];
- foreach ($groups as $id => $group) {
+ foreach ($groups as $group) {
// make sure that this group has public visibility
if ($visibility &&
$group['visibility'] == 'User and User Admin Only'
@@ -102,11 +102,11 @@ class CRM_Contact_Form_Edit_TagsAndGroups {
}
if ($groupElementType == 'select') {
- $groupsOptions[$id] = $group;
+ $groupsOptions[$group['id']] = $group;
}
else {
- $form->_tagGroup[$fName][$id]['description'] = $group['description'];
- $elements[] = &$form->addElement('advcheckbox', $id, NULL, $group['text'], $attributes);
+ $form->_tagGroup[$fName][$group['id']]['description'] = $group['description'];
+ $elements[] = &$form->addElement('advcheckbox', $group['id'], NULL, $group['text'], $attributes);
}
}