From a19f583409bf2821fd262fbad601a85dd4e91649 Mon Sep 17 00:00:00 2001 From: Jamie McClelland Date: Wed, 27 Sep 2017 19:29:38 -0400 Subject: [PATCH] CRM-21229 - don't regenerate smart groups on manage groups It takes too long. --- CRM/Contact/BAO/Group.php | 19 ++++---- tests/phpunit/CRM/Group/Page/AjaxTest.php | 57 +++++++++++++++++++++++ 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/CRM/Contact/BAO/Group.php b/CRM/Contact/BAO/Group.php index 3273fbee88..3963f26b00 100644 --- a/CRM/Contact/BAO/Group.php +++ b/CRM/Contact/BAO/Group.php @@ -1016,15 +1016,16 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group { $values[$object->id]['created_by'] = "{$object->created_by}"; } - // get group contact count using Contact.GetCount API - // CRM-20226 This has been added here in order to address a specific bug. However, a prior - // decision was to refresh group counts less aggressively, offering instead a button to - // refresh them to give users a better experience by loading pages quicker. - // For some sites this can be crazy slow even though only 25 sites resolve. Even for sites - // with relatively few smart groups it is not a good user experience. - // Adding comments here as I'm not going to tackle a fix this time around but want - // to warn people off making it worse. - $values[$object->id]['count'] = civicrm_api3('Contact', 'getcount', array('group' => $object->id)); + // If it's a smart group AND the contacts aren't cached, don't try to + // generate a count, it will take forever. + if ($object->saved_search_id && is_null($object->cache_date)) { + $values[$object->id]['count'] = ts('unknown'); + } + else { + // If it's not a smart group or we have them cached, then + // populate the count. + $values[$object->id]['count'] = civicrm_api3('Contact', 'getcount', array('group' => $object->id)); + } } // CRM-16905 - Sort by count cannot be done with sql diff --git a/tests/phpunit/CRM/Group/Page/AjaxTest.php b/tests/phpunit/CRM/Group/Page/AjaxTest.php index ba9790574c..09ef82f5d6 100644 --- a/tests/phpunit/CRM/Group/Page/AjaxTest.php +++ b/tests/phpunit/CRM/Group/Page/AjaxTest.php @@ -510,6 +510,63 @@ class CRM_Group_Page_AjaxTest extends CiviUnitTestCase { $this->assertEquals('pick-me-active', $groups['data'][0]['title']); } + /** + * Don't populate smart group cache when building Group list. + * + * It takes forever, especially if you have lots of smart groups. + */ + public function testGroupDontRegenerateSmartGroups() { + // Create a contact. + $firstName = 'Tweak'; + $lastName = 'Octonaut'; + $params = array( + 'first_name' => $firstName, + 'last_name' => $lastName, + 'contact_type' => 'Individual', + ); + $contact = CRM_Contact_BAO_Contact::add($params); + + // Create a smart group. + $searchParams = array( + 'last_name' => $lastName, + ); + $groupParams = array('title' => 'Find all Octonauts', 'formValues' => $searchParams, 'is_active' => 1); + $group = CRM_Contact_BAO_Group::createSmartGroup($groupParams); + + // Ensure the smart group is created. + $this->assertTrue(is_int($group->id), "Smart group created successfully."); + CRM_Contact_BAO_GroupContactCache::load($group, TRUE); + + // Ensure it is populating the cache when loaded. + $sql = 'SELECT contact_id FROM civicrm_group_contact_cache WHERE group_id = %1'; + $params = array(1 => array($group->id, 'Integer')); + $dao = CRM_Core_DAO::executeQuery($sql, $params); + $this->assertEquals($dao->N, 1, '1 record should be found in smart group'); + + // Purge the group contact cache. + CRM_Contact_BAO_GroupContactCache::clearGroupContactCache($group->id); + + // Load the Manage Group page code. + $_GET = $this->_params; + $obj = new CRM_Group_Page_AJAX(); + $groups = $obj->getGroupList(); + + // Make sure we returned our smart group. + $found = FALSE; + foreach ($groups['data'] as $returned_group) { + if ($returned_group['group_id'] == $group->id) { + $found = TRUE; + } + } + $this->assertTrue($found, 'Smart group shows up on Manage Group page.'); + + // Ensure we did not populate the cache. + $sql = 'SELECT contact_id FROM civicrm_group_contact_cache WHERE group_id = %1'; + $params = array(1 => array($group->id, 'Integer')); + $dao = CRM_Core_DAO::executeQuery($sql, $params); + $this->assertEquals($dao->N, 0, 'Group contact cache should not be populated on Manage Groups'); + } + /** * Implements ACLGroup hook. * aclGroup function returns a list of permitted groups -- 2.25.1