Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev/core#926 Fixes bug on searching for removed members of smartgroups #14182

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions CRM/Contact/BAO/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -2962,6 +2962,8 @@ public function includeContactSubTypes($value, $grouping, $op = 'LIKE') {
* Where / qill clause for groups.
*
* @param $values
*
* @throws \CRM_Core_Exception
*/
public function group($values) {
list($name, $op, $value, $grouping, $wildcard) = $values;
Expand Down Expand Up @@ -3008,8 +3010,10 @@ public function group($values) {
$isNotOp = ($op == 'NOT IN' || $op == '!=');

$statusJoinClause = $this->getGroupStatusClause($grouping);
// If we are searching for 'Removed' contacts then despite it being a smart group we only care about the group_contact table.
$isGroupStatusSearch = (!empty($this->getSelectedGroupStatuses($grouping)) && $this->getSelectedGroupStatuses($grouping) !== ["'Added'"]);
$groupClause = [];
if ($hasNonSmartGroups || empty($value)) {
if ($hasNonSmartGroups || empty($value) || $isGroupStatusSearch) {
// include child groups IDs if any
$childGroupIds = (array) CRM_Contact_BAO_Group::getChildGroupIds($regularGroupIDs);
foreach ($childGroupIds as $key => $id) {
Expand All @@ -3023,7 +3027,13 @@ public function group($values) {
}

if (empty($regularGroupIDs)) {
$regularGroupIDs = [0];
if ($isGroupStatusSearch) {
$regularGroupIDs = $smartGroupIDs;
}
// If it is still empty we want a filter that blocks all results.
if (empty($regularGroupIDs)) {
$regularGroupIDs = [0];
}
}

// if $regularGroupIDs is populated with regular child group IDs
Expand Down Expand Up @@ -3059,8 +3069,9 @@ public function group($values) {
}

//CRM-19589: contact(s) removed from a Smart Group, resides in civicrm_group_contact table
$groupContactCacheClause = '';
if (count($smartGroupIDs) || empty($value)) {
// If we are only searching for Removed or Pending contacts we don't need to resolve the smart group
// as that info is in the group_contact table.
if ((count($smartGroupIDs) || empty($value)) && !$isGroupStatusSearch) {
$this->_groupUniqueKey = uniqid();
$this->_groupKeys[] = $this->_groupUniqueKey;
$gccTableAlias = "civicrm_group_contact_cache_{$this->_groupUniqueKey}";
Expand Down
19 changes: 19 additions & 0 deletions tests/phpunit/CRM/Contact/BAO/QueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -731,12 +731,31 @@ public function testGetByGroupWithStatus() {
$this->assertEquals(2, $resultDAO->N);
}

/**
* Test we can narrow a group get by status.
*
* @throws \Exception
*/
public function testGetByGroupWithStatusSmartGroup() {
$groupID = $this->smartGroupCreate();
// This means they are actually all hard-added, which is fine for this purpose.
$this->groupContactCreate($groupID, 3);
$groupContactID = $this->callAPISuccessGetSingle('GroupContact', ['group_id' => $groupID, 'options' => ['limit' => 1]])['id'];
$this->callAPISuccess('GroupContact', 'create', ['id' => $groupContactID, 'status' => 'Removed']);

$queryObj = new CRM_Contact_BAO_Query([['group', '=', $groupID, 0, 0], ['group_contact_status', 'IN', ['Removed' => 1], 0, 0]]);
$resultDAO = $queryObj->searchQuery();
$this->assertEquals(1, $resultDAO->N);
}

/**
* Test the group contact clause does not contain an OR.
*
* The search should return 3 contacts - 2 households in the smart group of
* Contact Type = Household and one Individual hard-added to it. The
* Household that meets both criteria should be returned once.
*
* @throws \Exception
*/
public function testGroupClause() {
$this->householdCreate();
Expand Down
12 changes: 7 additions & 5 deletions tests/phpunit/CiviTest/CiviUnitTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -1246,13 +1246,15 @@ protected function cleanUpAfterACLs() {
*
* @param array $smartGroupParams
* @param array $groupParams
* @param string $contactType
*
* @return int
*/
public function smartGroupCreate($smartGroupParams = array(), $groupParams = array()) {
$smartGroupParams = array_merge(array(
'formValues' => array('contact_type' => array('IN' => array('Household'))),
),
$smartGroupParams);
public function smartGroupCreate($smartGroupParams = [], $groupParams = [], $contactType = 'Household') {
$smartGroupParams = array_merge([
'formValues' => ['contact_type' => ['IN' => [$contactType]]],
],
$smartGroupParams);
$savedSearch = CRM_Contact_BAO_SavedSearch::create($smartGroupParams);

$groupParams['saved_search_id'] = $savedSearch->id;
Expand Down