Filter groups according to included profiles
authorAndrew Engelbrecht <andrew@fsf.org>
Mon, 25 Sep 2017 22:34:51 +0000 (18:34 -0400)
committerMichael McMahon <michael@fsf.org>
Thu, 5 Dec 2019 01:24:49 +0000 (20:24 -0500)
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
CRM/Contribute/Form/Contribution/Confirm.php
CRM/Event/Form/Registration/Confirm.php
CRM/Profile/Form.php

index 62ed9415d61412b806a677e833c37ff2f414e9ea..41f11be781072da17a8af26e2066b6c190763c8f 100644 (file)
@@ -122,30 +122,18 @@ class CRM_Contact_Form_Edit_TagsAndGroups {
         //             "titles": ["Yes, sign me up!", "Sign me up to the other group!"]
         //         }
         //     },
-        //     "contribution": {
-        //         "14": {
-        //             "groups": [41, 25],
-        //             "titles": ["Yes, sign me up!"]
-        //         }
-        //     },
-        //     "event": {
-        //         "49": {
-        //             "groups": [25]
-        //         }
-        //     }
         // }'
         //
         // 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
@@ -154,27 +142,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;
         }
 
@@ -334,26 +329,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) {
 
index 8118fc9fea1ca5bef67477e50f2550ca9d90d14a..e328276651cca237a2a8e36bf262710b9c4f4abb 100644 (file)
@@ -2208,7 +2208,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,
index 997641b6052eca699f66997d2a7ced6e14c4a0e2..38657c393313fdf16c950b1f8559b0043665c424 100644 (file)
@@ -1166,8 +1166,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,
index 67046eb22085fab901fa31bf0cf2ebcb22dcb259..efd3e48421e88238ea747f5f0a13441632e7f8bd 100644 (file)
@@ -1287,7 +1287,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,