Answers.Body: <p>The core issue is that CiviCRM's in-built ACLs don't distinguish between access to view a group and access to view the group's contacts.</p>
  
  <p>However, extension-based ACLs CAN distinguish.  So my solution is to give folks access to "View All Groups" as a web-based ACL, then restrict permissions by extension.</p>
  
  <p>Note that this doesn't work unless you've applied the <a href="https://github.com/civicrm/civicrm-core/pull/13373/commits" rel="nofollow noreferrer">patch for core#580</a>.  This will be part of CiviCRM 5.12+. </p>
  
  <p>UPDATE: Here's an example where I limit the viewing of anonymous donors (as flagged by a custom field) to members of a group called "Confidential Staff":</p>
  
  
  
  <pre><code>function tweaks_civicrm_aclWhereClause($type, &amp;$tables, &amp;$whereTables, &amp;$contactID, &amp;$where) {
    // If the person is not in the "Confidential Staff" group, don't show them the contacts in the "Anonymous Donors" group.
    if (!$contactID) {
      return;
    }
    $confidentialStaff = civicrm_api3('GroupContact', 'get', [
      'group_id' =&gt; "Confidential_Staff_14",
      'contact_id' =&gt; $contactID,
    ]);
    // If this person is not confidential staff;
    if ($confidentialStaff['count'] === 0) {
      // Find a list of anonymous donors.
      $result = civicrm_api3('Contact', 'get', [
        'return' =&gt; ["id"],
        'custom_12' =&gt; 1,
      ]);
      $anonDonors = array_keys($result['values']);
      $anonDonors = implode(",", $anonDonors);
      $where .= ($where ? ' AND ' : '') . " contact_a.id NOT IN ($anonDonors)";
    }
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-03-15T15:03:25.147Z
Answers.Text: Thanks! As in this hook: https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_aclGroup/ ? If so do you know of any public repo where I can see an example? (the HDR example link in the documentation page is dead)
Answers.UserDisplayName: artfulrobot
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-03-15T15:20:09.250Z
Answers.Text: @artfulrobot I don't have a public example - at least, not a simple one.  However, I just updated my answer with source from a non-public example.
Answers.UserDisplayName: Jon G - Megaphone Tech
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-03-15T14:42:21.423Z
Answers.LastActivityDate: 2019-03-15T15:18:36.290Z
Answers.LastEditDate: 2019-03-15T15:18:36.290Z
Answers.UserDisplayName: Jon G - Megaphone Tech
Body: <p>I have a group of CiviCRM users who are restricted by ACL to only be allowed to view and edit contacts in a certain geographic region (those contacts in a group called "Northern Region"). They also have view and edit permission on another group.</p>
  
  <p>The problem is that the Manage Groups page <em>only</em> shows these two groups. If they add a new group it immediately dissapears!</p>
  
  <p>Is this by design? It seems excessively limiting. I'd expect people to be able to see pretty much all groups, but only be able to see contacts within those groups that intersect with the contacts they're allowed by ACL.</p>
  
  <p>Is there a work around?</p>
  
  <p>Perhaps such staff are expected to create new groups as child groups of one of their ACL groups, but this is problematic because (a) it means that they can't make a group combining contacts from two+ groups and (b) it currently breaks access because of <a href="https://lab.civicrm.org/dev/core/issues/430" rel="nofollow noreferrer">Bug #430</a></p>
  
  <p>CiviCRM 5.10.3 / Drupal 7</p>
  
Tags: <permissions><acl>
Title: Staff restricted by ACLs cannot use/see any other groups
ThreadText: # Staff restricted by ACLs cannot use/see any other groups
  
  (Asked by: username_0 on 2019-03-15)
  
  I have a group of CiviCRM users who are restricted by ACL to only be allowed to view and edit contacts in a certain geographic region (those contacts in a group called "Northern Region"). They also have view and edit permission on another group.
  
  The problem is that the Manage Groups page *only* shows these two groups. If they add a new group it immediately dissapears!
  
  Is this by design? It seems excessively limiting. I'd expect people to be able to see pretty much all groups, but only be able to see contacts within those groups that intersect with the contacts they're allowed by ACL.
  
  Is there a work around?
  
  Perhaps such staff are expected to create new groups as child groups of one of their ACL groups, but this is problematic because (a) it means that they can't make a group combining contacts from two+ groups and (b) it currently breaks access because of [Bug #430](https://lab.civicrm.org/dev/core/issues/430)
  
  CiviCRM 5.10.3 / Drupal 7
  
  **Tags:** permissions, acl
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2019-03-15. Score: 3 | Accepted answer
  
  The core issue is that CiviCRM's in-built ACLs don't distinguish between access to view a group and access to view the group's contacts.
  However, extension-based ACLs CAN distinguish.  So my solution is to give folks access to "View All Groups" as a web-based ACL, then restrict permissions by extension.
  Note that this doesn't work unless you've applied the patch for core#580.  This will be part of CiviCRM 5.12+. 
  UPDATE: Here's an example where I limit the viewing of anonymous donors (as flagged by a custom field) to members of a group called "Confidential Staff":
  function tweaks_civicrm_aclWhereClause($type, &$tables, &$whereTables, &$contactID, &$where) {
    // If the person is not in the "Confidential Staff" group, don't show them the contacts in the "Anonymous Donors" group.
    if (!$contactID) {
      return;
    }
    $confidentialStaff = civicrm_api3('GroupContact', 'get', [
      'group_id' => "Confidential_Staff_14",
      'contact_id' => $contactID,
    ]);
    // If this person is not confidential staff;
    if ($confidentialStaff['count'] === 0) {
      // Find a list of anonymous donors.
      $result = civicrm_api3('Contact', 'get', [
        'return' => ["id"],
        'custom_12' => 1,
      ]);
      $anonDonors = array_keys($result['values']);
      $anonDonors = implode(",", $anonDonors);
      $where .= ($where ? ' AND ' : '') . " contact_a.id NOT IN ($anonDonors)";
    }
  }
  
  > **Comments:**
  > **username_0**: Thanks! As in this hook: https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_aclGroup/ ? If so do you know of any public repo where I can see an example? (the HDR example link in the documentation page is dead)  
  > **username_1**: @username_0 I don't have a public example - at least, not a simple one.  However, I just updated my answer with source from a non-public example.  
  
  ---
  
  