From: Andrew Engelbrecht Date: Fri, 15 Sep 2017 20:15:10 +0000 (-0400) Subject: Groups filter hack for smaller groups listings X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=297fac311334532d6cdd751efe5a951249ba6400;p=civicrm-core.git Groups filter hack for smaller groups listings This change is a dirty hack that lets site admins filter the "Contacts Group(s)" field output in select profiles. This reduces overwhem for users when they are making a donation or filling out a form with the Groups signup field. This is preferable to using a custom field with smart groups because the Groups field provides double opt-in, while custom fields do not. The filter is controlled via a json string stored in a drupal variable that can be set with drush like so: drush vset --format=string groups_field_filters "{...}" See the documentation marked with "sudoman hack" in CRM/Contact/Form/Edit/TagsAndGroups.php for an example. --- diff --git a/CRM/Contact/Form/Edit/TagsAndGroups.php b/CRM/Contact/Form/Edit/TagsAndGroups.php index 11bb704fca..ffbd24c860 100644 --- a/CRM/Contact/Form/Edit/TagsAndGroups.php +++ b/CRM/Contact/Form/Edit/TagsAndGroups.php @@ -92,11 +92,73 @@ class CRM_Contact_Form_Edit_TagsAndGroups { if ($groupID || !empty($group)) { $groups = CRM_Contact_BAO_Group::getGroupsHierarchy($ids, NULL, '- ', FALSE, $public); + // sudoman hack begins + // + // This hack allows us to filter Groups listings so users aren't + // overwhelmed with choices. The advantage of this over smart groups + // is that normal groups use double opt-in. + // + // To set the variable, use the following method: + // + // $ drush vset --format=string groups_field_filters "{'profile': {'468': [25, 41]}, 'contribution': {'14': [25, 41]}, 'event': {'49': [25, 41]}}" + // + // The "string" format must be used and not the "json" format. + // Otherwise the json will be converted to a PHP array, which will not + // work with this code. + // + // The string contains json text, with the first level referring to + // page type, then the page number, then the list of ids of groups to + // display on that page. + // + // 'profile' is for standalone profiles. If the profile is embedded in + // a contrib or event page, then the id of the contrib or event page + // must be added to the string. + + // Find the list of groups that we want to let pass through a filter on + // a given profile or page. If there is no filter for that page, then + // all groups are displayed. + + $groups_field_filters = json_decode(variable_get('groups_field_filters', NULL), $assoc = TRUE); + + $form_class_name = get_class($form); + + // this commented line is useful for printing class names for future use in the switch statement below: + //watchdog("hacking", "foo message (form class): " . $form_class_name, NULL, WATCHDOG_ALERT); + + switch ($form_class_name) { + + case 'CRM_Profile_Form_Edit': + $page_id = $form->get('gid'); // gid, not id + $filter = $groups_field_filters['profile'][strval($page_id)]; + break; + + case 'CRM_Contribute_Form_Contribution_Main': + case 'CRM_Contribute_Form_Contribution_Confirm': + case 'CRM_Contribute_Form_Contribution_ThankYou': + $page_id = $form->get('id'); // id, not gid + $filter = $groups_field_filters['contribution'][strval($page_id)]; + break; + + case 'CRM_Event_Form_Registration_Register': + $page_id = $form->get('id'); // id, not gid + $filter = $groups_field_filters['event'][strval($page_id)]; + break; + } + // sudoman hack continues further below + $attributes['skiplabel'] = TRUE; $elements = []; $groupsOptions = []; foreach ($groups as $key => $group) { $id = $group['id']; + + // sudoman hack continues + // filter groups if a filter is set + if (isset($filter) and !in_array($id, $filter)) { + continue; + } + // sudoman hack continues with calls to CRM_Contact_Form_Edit_TagsAndGroups::reInsertFilteredGroupMemberships + // make sure that this group has public visibility if ($visibility && $group['visibility'] == 'User and User Admin Only' @@ -219,4 +281,45 @@ class CRM_Contact_Form_Edit_TagsAndGroups { } } + /** re-add groups selectively filtered by sudoman's hack + * + * the sudoman hack continues from above and from calls to this function. + * + * re-add any filtered-out groups if the contact is already in those groups + * so createProfileContact() doesn't remove group memberships. + * + * @param int $page_id (page number) + * @param string $page_type ('profile', 'contribution' or 'event') + * @param int $contactID (id of contact) + * @param bool $ignorePermission (passed to getContactGroup, often TRUE) + * @param array $params (for parameters) + * + * @return array $params (modified parameters: active groups that were filtered are inserted) + */ + public static function reInsertFilteredGroupMemberships($page_id, $page_type, + $contactID, $ignorePermission, $params) { + + $groups_field_filters = json_decode(variable_get('groups_field_filters', NULL), $assoc = TRUE); + $filter = $groups_field_filters[$page_type][strval($page_id)]; + + if ($contactID !== NULL) { + + $contactGroupList = &CRM_Contact_BAO_GroupContact::getContactGroup($contactID, 'Added', + NULL, FALSE, $ignorePermission + ); + + foreach ($contactGroupList as $value) { + + $groupId = $value['group_id']; + if (!empty($filter) && !in_array($groupId, $filter)) { + + $params['group'][strval($groupId)] = 1; + } + } + } + + return $params; + } + // sudoman hack ends + } diff --git a/CRM/Contribute/Form/Contribution/Confirm.php b/CRM/Contribute/Form/Contribution/Confirm.php index c28899bd4a..4fbffcd351 100644 --- a/CRM/Contribute/Form/Contribution/Confirm.php +++ b/CRM/Contribute/Form/Contribution/Confirm.php @@ -2345,6 +2345,10 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr else { $contactType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactID, 'contact_type'); } + + // sudoman hack: re-insert filtered group memberships + $params = CRM_Contact_Form_Edit_TagsAndGroups::reInsertFilteredGroupMemberships($this->_id, 'contribution', $contactID, TRUE, $params); + $contactID = CRM_Contact_BAO_Contact::createProfileContact( $params, $fields, diff --git a/CRM/Event/Form/Registration/Confirm.php b/CRM/Event/Form/Registration/Confirm.php index d83cad562f..d14223315e 100644 --- a/CRM/Event/Form/Registration/Confirm.php +++ b/CRM/Event/Form/Registration/Confirm.php @@ -1102,6 +1102,9 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration { unset($params['contact_id']); } + // sudoman hack: re-insert filtered group memberships + $params = CRM_Contact_Form_Edit_TagsAndGroups::reInsertFilteredGroupMemberships($form->get('id'), 'event', $contactID, TRUE, $params); + $contactID = CRM_Contact_BAO_Contact::createProfileContact( $params, $fields, diff --git a/CRM/Profile/Form.php b/CRM/Profile/Form.php index af6642111c..a4a11e7e19 100644 --- a/CRM/Profile/Form.php +++ b/CRM/Profile/Form.php @@ -1274,6 +1274,9 @@ class CRM_Profile_Form extends CRM_Core_Form { $params['customRecordValues'][$this->_recordId] = array_keys($this->_multiRecordFields); } + // sudoman hack: re-insert filtered group memberships + $params = CRM_Contact_Form_Edit_TagsAndGroups::reInsertFilteredGroupMemberships($this->_gid, 'profile', $this->_id, TRUE, $params); + $this->_id = CRM_Contact_BAO_Contact::createProfileContact( $params, $profileFields,