From: Eileen McNaughton Date: Fri, 14 May 2021 02:37:16 +0000 (+1200) Subject: [REF] Extract function to build temporary table of members of group from Report_Form X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=7afacd0fb876346b35febca604889862aa9ba64d;p=civicrm-core.git [REF] Extract function to build temporary table of members of group from Report_Form --- diff --git a/CRM/Contact/BAO/GroupContactCache.php b/CRM/Contact/BAO/GroupContactCache.php index 91e011c98b..03e0a030fb 100644 --- a/CRM/Contact/BAO/GroupContactCache.php +++ b/CRM/Contact/BAO/GroupContactCache.php @@ -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 diff --git a/CRM/Report/Form.php b/CRM/Report/Form.php index b7a9a70982..e89934a2c3 100644 --- a/CRM/Report/Form.php +++ b/CRM/Report/Form.php @@ -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 "; } } } diff --git a/tests/phpunit/api/v3/ReportTemplateTest.php b/tests/phpunit/api/v3/ReportTemplateTest.php index 597d31873d..02a1202dbe 100644 --- a/tests/phpunit/api/v3/ReportTemplateTest.php +++ b/tests/phpunit/api/v3/ReportTemplateTest.php @@ -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();