[REF] Extract function to build temporary table of members of group from Report_Form
authorEileen McNaughton <emcnaughton@wikimedia.org>
Fri, 14 May 2021 02:37:16 +0000 (14:37 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Thu, 20 May 2021 02:34:19 +0000 (14:34 +1200)
CRM/Contact/BAO/GroupContactCache.php
CRM/Report/Form.php
tests/phpunit/api/v3/ReportTemplateTest.php

index 91e011c98b1877f6e190c7f4da06c388efedfaec..03e0a030fb85b2dfcaa213b2da5cc830f8de8712 100644 (file)
@@ -725,6 +725,43 @@ AND  civicrm_group_contact.group_id = $groupID ";
     }
   }
 
+  /**
+   * Populate a temporary table with group ids and contact ids.
+   *
+   * Do not call this outside of core tested code - it WILL change.
+   *
+   * @param array[int] $groupIDs
+   * @param string $temporaryTable
+   *
+   * @throws \CiviCRM_API3_Exception
+   */
+  public static function populateTemporaryTableWithContactsInGroups(array $groupIDs, string $temporaryTable): void {
+    $groups = civicrm_api3('Group', 'get', [
+      'is_active' => 1,
+      'id' => ['IN' => $groupIDs],
+      'saved_search_id' => ['>' => 0],
+      'return' => 'id',
+    ]);
+    $smartGroups = array_keys($groups['values']);
+
+    $query = "
+       SELECT DISTINCT group_contact.contact_id as contact_id
+       FROM civicrm_group_contact group_contact
+       WHERE group_contact.group_id IN (" . implode(', ', $groupIDs) . ")
+       AND group_contact.status = 'Added' ";
+
+    if (!empty($smartGroups)) {
+      CRM_Contact_BAO_GroupContactCache::check($smartGroups);
+      $smartGroups = implode(',', $smartGroups);
+      $query .= "
+        UNION DISTINCT
+        SELECT smartgroup_contact.contact_id as contact_id
+        FROM civicrm_group_contact_cache smartgroup_contact
+        WHERE smartgroup_contact.group_id IN ({$smartGroups}) ";
+    }
+    CRM_Core_DAO::executeQuery('INSERT INTO ' . $temporaryTable . ' ' . $query);
+  }
+
   /**
    * @param array|null $groupIDs
    * @param int $limit
index b7a9a70982dd598038a02642474b2c02c17a62cc..e89934a2c317659cd020dc0683d0aa209509b8c2 100644 (file)
@@ -3763,7 +3763,7 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND
       return $this->legacySlowGroupFilterClause($field, $value, $op);
     }
     if ($op === 'notin') {
-      return " group_temp_table.id IS NULL ";
+      return " group_temp_table.contact_id IS NULL ";
     }
     // We will have used an inner join instead.
     return "1";
@@ -3773,39 +3773,17 @@ WHERE cg.extends IN ('" . implode("','", $this->_customGroupExtends) . "') AND
    * Create a table of the contact ids included by the group filter.
    *
    * This function is called by both the api (tests) and the UI.
+   *
+   * @throws \CiviCRM_API3_Exception
    */
-  public function buildGroupTempTable() {
+  public function buildGroupTempTable(): void {
     if (!empty($this->groupTempTable) || empty($this->_params['gid_value']) || $this->groupFilterNotOptimised) {
       return;
     }
+    $this->groupTempTable = $this->createTemporaryTable('groups', 'contact_id INT', TRUE);
     $filteredGroups = (array) $this->_params['gid_value'];
-
-    $groups = civicrm_api3('Group', 'get', [
-      'is_active' => 1,
-      'id' => ['IN' => $filteredGroups],
-      'saved_search_id' => ['>' => 0],
-      'return' => 'id',
-    ]);
-    $smartGroups = array_keys($groups['values']);
-
-    $query = "
-       SELECT DISTINCT group_contact.contact_id as id
-       FROM civicrm_group_contact group_contact
-       WHERE group_contact.group_id IN (" . implode(', ', $filteredGroups) . ")
-       AND group_contact.status = 'Added' ";
-
-    if (!empty($smartGroups)) {
-      CRM_Contact_BAO_GroupContactCache::check($smartGroups);
-      $smartGroups = implode(',', $smartGroups);
-      $query .= "
-        UNION DISTINCT
-        SELECT smartgroup_contact.contact_id as id
-        FROM civicrm_group_contact_cache smartgroup_contact
-        WHERE smartgroup_contact.group_id IN ({$smartGroups}) ";
-    }
-
-    $this->groupTempTable = $this->createTemporaryTable('rptgrp', $query);
-    CRM_Core_DAO::executeQuery("ALTER TABLE $this->groupTempTable ADD INDEX i_id(id)");
+    CRM_Contact_BAO_GroupContactCache::populateTemporaryTableWithContactsInGroups($filteredGroups, $this->groupTempTable);
+    CRM_Core_DAO::executeQuery("ALTER TABLE $this->groupTempTable ADD INDEX contact_id(contact_id)");
   }
 
   /**
@@ -5222,12 +5200,12 @@ LEFT JOIN civicrm_contact {$field['alias']} ON {$field['alias']}.id = {$this->_a
     if ($this->groupTempTable) {
       if ($this->_params['gid_op'] == 'in') {
         $this->_from = " FROM $this->groupTempTable group_temp_table INNER JOIN $baseTable $tableAlias
-        ON group_temp_table.id = $tableAlias.{$field} ";
+        ON group_temp_table.contact_id = $tableAlias.{$field} ";
       }
       else {
         $this->_from .= "
           LEFT JOIN $this->groupTempTable group_temp_table
-          ON $tableAlias.{$field} = group_temp_table.id ";
+          ON $tableAlias.{$field} = group_temp_table.contact_id ";
       }
     }
   }
index 597d31873d3f9f0cfeef1d26403a7965d0850cfe..02a1202dbe9c3f098e36a6336506444f0b9b55e9 100644 (file)
@@ -546,7 +546,7 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
    *
    * @throws \CRM_Core_Exception
    */
-  public function testContributionSummaryWithSmartGroupFilter($template) {
+  public function testContributionSummaryWithSmartGroupFilter(string $template): void {
     $groupID = $this->setUpPopulatedSmartGroup();
     $rows = $this->callAPISuccess('report_template', 'getrows', [
       'report_id' => $template,
@@ -804,8 +804,8 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
    *
    * @throws \CRM_Core_Exception
    */
-  public function testContributionSummaryWithSingleContactsInTwoGroups() {
-    list($groupID1, $individualID) = $this->setUpPopulatedGroup(TRUE);
+  public function testContributionSummaryWithSingleContactsInTwoGroups(): void {
+    [$groupID1, $individualID] = $this->setUpPopulatedGroup(TRUE);
     // create second group and add the individual to it.
     $groupID2 = $this->groupCreate(['name' => 'test_group', 'title' => 'test_title']);
     $this->callAPISuccess('GroupContact', 'create', [
@@ -828,7 +828,7 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
    *
    * @throws \CRM_Core_Exception
    */
-  public function testContributionSummaryWithTwoGroupsWithIntersection() {
+  public function testContributionSummaryWithTwoGroupsWithIntersection(): void {
     $groups = $this->setUpIntersectingGroups();
 
     $rows = $this->callAPISuccess('report_template', 'getrows', [
@@ -845,7 +845,7 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
    *
    * @throws \CRM_Core_Exception
    */
-  public function testContributionSummaryDateFields() {
+  public function testContributionSummaryDateFields(): void {
     $sql = $this->callAPISuccess('report_template', 'getrows', [
       'report_id' => 'contribute/summary',
       'thankyou_date_relative' => '0',
@@ -884,7 +884,7 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
    * @return int
    * @throws \CRM_Core_Exception
    */
-  public function setUpPopulatedSmartGroup() {
+  public function setUpPopulatedSmartGroup(): int {
     $household1ID = $this->householdCreate();
     $individual1ID = $this->individualCreate();
     $householdID = $this->householdCreate();