From 5f55a8f912c31cf7f47ed20694d9e0097e83a891 Mon Sep 17 00:00:00 2001 From: Andrew Engelbrecht Date: Mon, 25 Sep 2017 18:34:51 -0400 Subject: [PATCH] Filter groups according to included profiles This is a continuation of the contact groups filtering feature, which allows admins to filter the public listings of contact groups on various Civi pages by setting a Drupal variable with drush. It is now possible to set a rule for a profile and for that rule to automatically apply to standalone profile pages, contribution pages that include the profile, and event pages that include it as well. See comments in CRM/Contact/Form/Edit/TagsAndGroups.php for instructions on how to set the variable via drush. --- CRM/Contact/Form/Edit/TagsAndGroups.php | 77 +++++++++++++------- CRM/Contribute/Form/Contribution/Confirm.php | 4 +- CRM/Event/Form/Registration/Confirm.php | 19 ++++- CRM/Profile/Form.php | 2 +- 4 files changed, 70 insertions(+), 32 deletions(-) diff --git a/CRM/Contact/Form/Edit/TagsAndGroups.php b/CRM/Contact/Form/Edit/TagsAndGroups.php index cac0823d02..14ad05c8af 100644 --- a/CRM/Contact/Form/Edit/TagsAndGroups.php +++ b/CRM/Contact/Form/Edit/TagsAndGroups.php @@ -101,19 +101,26 @@ class CRM_Contact_Form_Edit_TagsAndGroups { // // 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]}}" + // $ drush vset --format=string groups_field_filters ' + // { + // "profile": { + // "468": { + // "groups": [41, 25], + // "titles": ["Yes, sign me up!", "Sign me up to the other group!"] + // } + // }, + // }' // // 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. + // The string contains json text, with the first level referring to + // profiles, then the profile number, then the list of ids of groups to + // display on that page and optional replacement titles for those + // groups. + // 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 @@ -122,27 +129,34 @@ class CRM_Contact_Form_Edit_TagsAndGroups { $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_config = $groups_field_filters['profile'][strval($page_id)]; + $profile_id = $form->get('gid'); // gid, not id + $filter_config = $groups_field_filters['profile'][strval($profile_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_config = $groups_field_filters['contribution'][strval($page_id)]; - break; + default: + foreach (['custom_pre_id', 'custom_post_id'] as $which_profile) { - case 'CRM_Event_Form_Registration_Register': - $page_id = $form->get('id'); // id, not gid - $filter_config = $groups_field_filters['event'][strval($page_id)]; + $profile_ids = $form->get('values')[$which_profile]; + + // some pages can have multiple profiles + if (!is_array($profile_ids)) { + $all_profile_ids[] = $profile_ids; + } else { + $all_profile_ids = array_merge($all_profile_ids, $profile_ids); + } + } + + foreach ($all_profile_ids as $profile_id) { + $possible_filter = $groups_field_filters['profile'][strval($profile_id)]; + + if (isset($possible_filter)) { + $filter_config = $possible_filter; + break; + } + } break; } @@ -302,26 +316,33 @@ class CRM_Contact_Form_Edit_TagsAndGroups { } } - /** re-add groups selectively filtered by sudoman's hack + /** re-add groups selectively filtered out 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 array $profile_ids (ids of profiles in use on page) * @param int $contactID (id of contact) * @param bool $ignorePermission (passed to getContactGroup, often TRUE) - * @param array $params (for parameters) + * @param array $params (form parameters) * * @return array $params (modified parameters: active groups that were filtered are inserted) */ - public static function reInsertFilteredGroupMemberships($page_id, $page_type, + public static function reInsertFilteredGroupMemberships($profile_ids, $contactID, $ignorePermission, $params) { $groups_field_filters = json_decode(variable_get('groups_field_filters', NULL), $assoc = TRUE); - $filter_ids = $groups_field_filters[$page_type][strval($page_id)]['groups']; + + foreach ($profile_ids as $profile_id) { + $filter = $groups_field_filters['profile'][strval($profile_id)]; + + if (isset($filter)) { + $filter_ids = $filter['groups']; + break; + } + } if ($contactID !== NULL) { diff --git a/CRM/Contribute/Form/Contribution/Confirm.php b/CRM/Contribute/Form/Contribution/Confirm.php index 8071ea1662..8f0ebf778a 100644 --- a/CRM/Contribute/Form/Contribution/Confirm.php +++ b/CRM/Contribute/Form/Contribution/Confirm.php @@ -2272,7 +2272,9 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr } // sudoman hack: re-insert filtered group memberships - $params = CRM_Contact_Form_Edit_TagsAndGroups::reInsertFilteredGroupMemberships($this->_id, 'contribution', $contactID, TRUE, $params); + if (isset($this->_fields['group'])) { + $params = CRM_Contact_Form_Edit_TagsAndGroups::reInsertFilteredGroupMemberships([$this->_fields['group']['group_id']], $contactID, TRUE, $params); + } $contactID = CRM_Contact_BAO_Contact::createProfileContact( $params, diff --git a/CRM/Event/Form/Registration/Confirm.php b/CRM/Event/Form/Registration/Confirm.php index 1580d1e30b..6b6caac5ba 100644 --- a/CRM/Event/Form/Registration/Confirm.php +++ b/CRM/Event/Form/Registration/Confirm.php @@ -1157,8 +1157,23 @@ 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); + // sudoman hack: get profile ids before re-inserting filtered group memberships + foreach (['custom_pre_id', 'custom_post_id'] as $which_profile) { + + $profile_ids = $form->get('values')[$which_profile]; + + // some pages can have multiple profiles + if (!is_array($profile_ids)) { + $all_profile_ids[] = $profile_ids; + } else { + $all_profile_ids = array_merge($all_profile_ids, $profile_ids); + } + } + + // sudoman hack: continues from above: re-insert filtered group memberships + if (isset($fields['group'])) { + $params = CRM_Contact_Form_Edit_TagsAndGroups::reInsertFilteredGroupMemberships($all_profile_ids, $contactID, TRUE, $params); + } $contactID = CRM_Contact_BAO_Contact::createProfileContact( $params, diff --git a/CRM/Profile/Form.php b/CRM/Profile/Form.php index 15954438d9..36ea5d9a7b 100644 --- a/CRM/Profile/Form.php +++ b/CRM/Profile/Form.php @@ -1282,7 +1282,7 @@ class CRM_Profile_Form extends CRM_Core_Form { } // sudoman hack: re-insert filtered group memberships - $params = CRM_Contact_Form_Edit_TagsAndGroups::reInsertFilteredGroupMemberships($this->_gid, 'profile', $this->_id, TRUE, $params); + $params = CRM_Contact_Form_Edit_TagsAndGroups::reInsertFilteredGroupMemberships([$this->_gid], $this->_id, TRUE, $params); $this->_id = CRM_Contact_BAO_Contact::createProfileContact( $params, -- 2.25.1