From 0d38cb6d87743992adcc1f21eab91b0001691de3 Mon Sep 17 00:00:00 2001 From: eileen Date: Thu, 2 May 2019 18:56:44 +1200 Subject: [PATCH] dev/core#926 Fixes bug on searching for removed members of smartgroups --- CRM/Contact/BAO/Query.php | 19 +++++++++++++++---- tests/phpunit/CRM/Contact/BAO/QueryTest.php | 19 +++++++++++++++++++ tests/phpunit/CiviTest/CiviUnitTestCase.php | 12 +++++++----- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/CRM/Contact/BAO/Query.php b/CRM/Contact/BAO/Query.php index adf30b5907..ed919102b6 100644 --- a/CRM/Contact/BAO/Query.php +++ b/CRM/Contact/BAO/Query.php @@ -2962,6 +2962,8 @@ class CRM_Contact_BAO_Query { * Where / qill clause for groups. * * @param $values + * + * @throws \CRM_Core_Exception */ public function group($values) { list($name, $op, $value, $grouping, $wildcard) = $values; @@ -3008,8 +3010,10 @@ class CRM_Contact_BAO_Query { $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) { @@ -3023,7 +3027,13 @@ class CRM_Contact_BAO_Query { } 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 @@ -3059,8 +3069,9 @@ class CRM_Contact_BAO_Query { } //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}"; diff --git a/tests/phpunit/CRM/Contact/BAO/QueryTest.php b/tests/phpunit/CRM/Contact/BAO/QueryTest.php index 7e003272ea..a33d6edd27 100644 --- a/tests/phpunit/CRM/Contact/BAO/QueryTest.php +++ b/tests/phpunit/CRM/Contact/BAO/QueryTest.php @@ -731,12 +731,31 @@ civicrm_relationship.is_active = 1 AND $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(); diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index 817bff2356..01258760f2 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -1245,13 +1245,15 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase { * * @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; -- 2.25.1