+--------------------------------------------------------------------+
*/
-use Civi\Api4\Group;
-
/**
*
* @package CRM
$acls = CRM_ACL_BAO_Cache::build($contactID);
$whereClause = NULL;
+ $allInclude = $allExclude = FALSE;
$clauses = [];
if (!empty($acls)) {
$dao = CRM_Core_DAO::executeQuery($query);
// do an or of all the where clauses u see
- $ids = [];
+ $ids = $excludeIds = [];
while ($dao->fetch()) {
// make sure operation matches the type TODO
if (self::matchType($type, $dao->operation)) {
if (!$dao->deny) {
if (empty($dao->object_id)) {
- $ids = array_merge($ids, Group::get(FALSE)->execute()->column('id'));
+ $allInclude = TRUE;
}
else {
$ids[] = $dao->object_id;
}
}
else {
- $ids = array_diff($ids, [$dao->object_id]);
+ if (empty($dao->object_id)) {
+ $allExclude = TRUE;
+ }
+ else {
+ $excludeIds[] = $dao->object_id;
+ }
}
}
}
+ if (!empty($excludeIds) && !$allInclude) {
+ $ids = array_diff($ids, $excludeIds);
+ }
+ elseif (!empty($excludeIds) && $allInclude) {
+ $ids = [];
+ $clauses[] = self::getGroupClause($excludeIds, 'NOT IN');
+ }
if (!empty($ids)) {
- $ids = implode(',', $ids);
- $query = "
-SELECT g.*
- FROM civicrm_group g
- WHERE g.id IN ( $ids )
- AND g.is_active = 1
-";
- $dao = CRM_Core_DAO::executeQuery($query);
- $groupIDs = [];
- $groupContactCacheClause = FALSE;
- while ($dao->fetch()) {
- $groupIDs[] = $dao->id;
-
- if (($dao->saved_search_id || $dao->children || $dao->parents)) {
- if ($dao->cache_date == NULL) {
- CRM_Contact_BAO_GroupContactCache::load($dao);
- }
- $groupContactCacheClause = " UNION SELECT contact_id FROM civicrm_group_contact_cache WHERE group_id IN (" . implode(', ', $groupIDs) . ")";
- }
-
- }
-
- if ($groupIDs) {
- $clauses[] = "(
- `contact_a`.id IN (
- SELECT contact_id FROM civicrm_group_contact WHERE group_id IN (" . implode(', ', $groupIDs) . ") AND status = 'Added'
- $groupContactCacheClause
- )
- )";
- }
+ $clauses[] = self::getGroupClause($ids, 'IN');
}
}
return $ids;
}
+ private static function getGroupClause(array $groupIDs, string $operation): string {
+ $ids = implode(',', $groupIDs);
+ $query = "
+SELECT g.*
+ FROM civicrm_group g
+ WHERE g.id IN ( $ids )
+ AND g.is_active = 1
+";
+ $dao = CRM_Core_DAO::executeQuery($query);
+ $foundGroupIDs = [];
+ $groupContactCacheClause = FALSE;
+ while ($dao->fetch()) {
+ $foundGroupIDs[] = $dao->id;
+ if (($dao->saved_search_id || $dao->children || $dao->parents)) {
+ if ($dao->cache_date == NULL) {
+ CRM_Contact_BAO_GroupContactCache::load($dao);
+ }
+ $groupContactCacheClause = " UNION SELECT contact_id FROM civicrm_group_contact_cache WHERE group_id IN (" . implode(', ', $foundGroupIDs) . ")";
+ }
+ }
+
+ if ($groupIDs) {
+ return "(
+ `contact_a`.id $operation (
+ SELECT contact_id FROM civicrm_group_contact WHERE group_id IN (" . implode(', ', $foundGroupIDs) . ") AND status = 'Added'
+ $groupContactCacheClause
+ )
+ )";
+ }
+ return '';
+ }
+
}
]);
$contact1 = $this->individualCreate();
$contact2 = $this->individualCreate();
+ $contact3 = $this->individualCreate();
$excludeGroup = $this->groupCreate(['title' => 'exclude group', 'name' => 'exclude group']);
$otherGroup = $this->groupCreate(['title' => 'Other group', 'name' => 'other group']);
$this->callAPISuccess('GroupContact', 'create', [
'entity_table' => 'civicrm_acl_role',
'entity_id' => 6,
'operation' => 'Edit',
- 'object_table' => 'civicrm_saved_search',
+ 'object_table' => 'civicrm_group',
'object_id' => 0,
]);
$this->callAPISuccess('Acl', 'create', [
'entity_table' => 'civicrm_acl_role',
'entity_id' => 6,
'operation' => 'Edit',
- 'object_table' => 'civicrm_saved_search',
+ 'object_table' => 'civicrm_group',
'object_id' => $excludeGroup,
'deny' => 1,
]);
$this->cleanupCachedPermissions();
Civi::cache('metadata')->clear();
Civi::$statics['CRM_ACL_BAO_ACL'] = [];
- $contacts = Contact::get()->addWhere('id', 'IN', [$contact1, $contact2])->execute();
- $this->assertCount(1, $contacts);
+ $contacts = Contact::get()->addWhere('id', 'IN', [$contact1, $contact2, $contact3])->execute();
+ $this->assertCount(2, $contacts);
$this->assertEquals($contact2, $contacts[0]['id']);
+ $this->assertEquals($contact3, $contacts[1]['id']);
}
/**