dev/core#926 Fixes bug on searching for removed members of smartgroups
authoreileen <emcnaughton@wikimedia.org>
Thu, 2 May 2019 06:56:44 +0000 (18:56 +1200)
committereileen <emcnaughton@wikimedia.org>
Sun, 23 Jun 2019 20:12:45 +0000 (08:12 +1200)
CRM/Contact/BAO/Query.php
tests/phpunit/CRM/Contact/BAO/QueryTest.php
tests/phpunit/CiviTest/CiviUnitTestCase.php

index adf30b59070d891bb64808110f9b2cad35d9291a..ed919102b684357e997821269d4276c7cc7096e4 100644 (file)
@@ -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}";
index 7e003272eabe39dfb8586fc76cf8994a2ad4433f..a33d6edd279856f7f83bdda322ce331d9fe9ae35 100644 (file)
@@ -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();
index 817bff23565c0a91d02767b2c90bd390581bf5fd..01258760f27daa6c4beebfeb26c77af04dd46124 100644 (file)
@@ -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;