When using multiple group-based ACLs where the current user has ACLs on a group of contacts, and one or more subgroups of that same group, browsing the contacts of the larger group only lists a subset of the contacts of the larger group. We saw this in the following context:
- The site uses ACLs and ACL groups.
- An admin of our Italy group also has ACLs for people in the Venice, Rome and Florence subgroups.
- Italy has ~3000 contacts, but only about 150 contacts appear in that group when browsing group contacts for Italy.
After investigating the query generated by CiviCRM, I discovered that this user sees the the intersection of the Italy group, and the Venice group; in effect, since Venice is a proper subset of Italy, you only see Venice members.
Cause turns out to be a section of code that processes the ACL records one at a time; Venice is the last processed, so Venice wins. This is because there is only a single LEFT JOIN, and the last ACL record processed "owns" that single left join.
I will enclose a patch against the trunk for this issue. The code has actually only been tested against 4.1.x (it's pretty hard to set up the database so you will see this), but it applies clean to trunk as of 6 Nov 2012.