Child groups of ACL groups cause ACL to fail
If you have group A which is used to identify contacts that an ACL grants permissions to, and you add group B as a child group of A, the ACLs fail to allow you to see the contacts in group A.
Seems that this line (and again in line 804) is assuming a table alias stored in a PHP serialized field to look like
N is Group A's ID, but actually the alias will be
civicrm_group_contact-N,M where M is the group B's ID.
Presumably the aliases get less predictable if a group has multiple children/grandchildren.
As far as I have understood, the code is trying to standardise the groups into two buckets: one for smart groups and one for normal groups.
I think the logic should be that groups both A and B should be included in the collected group IDs, since if you're in the child group, you're considered to be in the parent group - I think. Although this does mean that if someone has status "Removed" in the parent group (the one that defines which contacts the ACL grants access to), but "Added" in the child group, then the Added will win; access will be granted. So it could get more complicated.
Or the desired behaviour could simply be "no, you have to be actually added to group A since that is the only group explicitly mentioned in the ACL, and that status of group B should not have any bearing on the situation".
To fix this for my client I had to:
Edit group B: Remove group A as the parent for group B.
Edit group A and just hit Save. This step is necessary to ensure the whereTables and selectTables are updated.
Instruct them not to add child groups of ACL groups.
What's the desired behaviour? Is looping through the generated table aliases the most reliable way to implement it?