From 778a10cbae3285a35739616d5f128a44b4bc94c9 Mon Sep 17 00:00:00 2001 From: kurund Date: Wed, 9 Apr 2014 14:45:51 -0700 Subject: [PATCH] CRM-14438 and CRM-13996 fix to populate prev/next cache when sorting in advanced search using profile search view ---------------------------------------- * CRM-14438: Can't select contact records from custom search profile when sorted by Current Employer https://issues.civicrm.org/jira/browse/CRM-14438 * CRM-13996: Advanced Search; Sorting of Results displayed in a custom profile fails and Advanced Search must be reset https://issues.civicrm.org/jira/browse/CRM-13996 --- CRM/Contact/Selector.php | 61 ++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/CRM/Contact/Selector.php b/CRM/Contact/Selector.php index da60b1324d..aa040d8e9b 100644 --- a/CRM/Contact/Selector.php +++ b/CRM/Contact/Selector.php @@ -519,11 +519,6 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se if ($rowCount) { $cacheKey = $this->buildPrevNextCache($sort); $result = $this->_query->getCachedContacts($cacheKey, $offset, $rowCount, $includeContactIds); - - // CRM-13996: result is empty when selector columns are sorted. hence we need to run the query again - if ( $result->N == 0) { - $result = $this->_query->searchQuery($offset, $rowCount, $sort, FALSE, $includeContactIds); - } } else { $result = $this->_query->searchQuery($offset, $rowCount, $sort, FALSE, $includeContactIds); @@ -898,19 +893,17 @@ class CRM_Contact_Selector extends CRM_Core_Selector_Base implements CRM_Core_Se * @param int $end */ function fillupPrevNextCache($sort, $cacheKey, $start = 0, $end = 500) { - + $coreSearch = TRUE; // For custom searches, use the contactIDs method if (is_a($this, 'CRM_Contact_Selector_Custom')) { $sql = $this->_search->contactIDs($start, $end, $sort, TRUE); $replaceSQL = "SELECT contact_a.id as contact_id"; + $coreSearch = FALSE; } // For core searches use the searchQuery method else { - $sql = $this->_query->searchQuery( - $start, $end, $sort, - FALSE, FALSE, - FALSE, TRUE, TRUE, NULL - ); + $sql = $this->_query->searchQuery($start, $end, $sort, FALSE, $this->_query->_includeContactIds, + FALSE, TRUE, TRUE); $replaceSQL = "SELECT contact_a.id as id"; } @@ -935,16 +928,54 @@ SELECT 'civicrm_contact', contact_a.id, contact_a.id, '$cacheKey', contact_a.dis CRM_Core_Error::setCallback(); if (is_a($result, 'DB_Error')) { - // oops the above query failed, so lets just ignore it - // and return - // we print a sorry cant figure it out on view page - return; + // check if we get error during core search + if ($coreSearch) { + // in the case of error, try rebuilding cache using full sql which is used for search selector display + // this fixes the bugs reported in CRM-13996 & CRM-14438 + $this->rebuildPreNextCache($start, $end, $sort, $cacheKey); + } + else { + // return if above query fails + return; + } } // also record an entry in the cache key table, so we can delete it periodically CRM_Core_BAO_Cache::setItem($cacheKey, 'CiviCRM Search PrevNextCache', $cacheKey); } + /** + * This function is called to rebuild prev next cache using full sql in case of core search ( excluding custom search) + * + * @param int $start start for limit clause + * @param int $end end for limit clause + * @param $object $sort sort object + * @param string $cacheKey cache key + * + * @return void + */ + function rebuildPreNextCache($start, $end, $sort, $cacheKey) { + // generate full SQL + $sql = $this->_query->searchQuery($start, $end, $sort, FALSE, $this->_query->_includeContactIds, + FALSE, FALSE, TRUE); + + $dao = CRM_Core_DAO::executeQuery($sql); + + // build insert query, note that currently we build cache for 500 contact records at a time, hence below approach + $insertValues = array(); + while($dao->fetch()) { + $insertValues[] = "('civicrm_contact', {$dao->contact_id}, {$dao->contact_id}, '{$cacheKey}', '{$dao->sort_name}')"; + } + + //update pre/next cache using single insert query + if (!empty($insertValues)) { + $sql = 'INSERT INTO civicrm_prevnext_cache ( entity_table, entity_id1, entity_id2, cacheKey, data ) VALUES +'.implode(',', $insertValues); + + $result = CRM_Core_DAO::executeQuery($sql); + } + } + /** * Given the current formValues, gets the query in local * language -- 2.25.1