X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FContact%2FBAO%2FGroupContactCache.php;h=3234710a6b650223c9bdb842b3a8bb114b1302a1;hb=530f7d9dfc8239c7179751ef666a80e9f9cf8e8e;hp=e030e363942cb8bcca4097ed85f800fc9c9b94c6;hpb=d5fd88834139d3bd5be9a170e5689c50c42783e3;p=civicrm-core.git diff --git a/CRM/Contact/BAO/GroupContactCache.php b/CRM/Contact/BAO/GroupContactCache.php index e030e36394..3234710a6b 100644 --- a/CRM/Contact/BAO/GroupContactCache.php +++ b/CRM/Contact/BAO/GroupContactCache.php @@ -266,23 +266,6 @@ WHERE id IN ( $groupIDs ) CRM_Core_DAO::executeQuery($sql); } - /** - * @deprecated function - the best function to call is - * CRM_Contact_BAO_Contact::updateContactCache at the moment, or api job.group_cache_flush - * to really force a flush. - * - * Remove this function altogether by mid 2018. - * - * However, if updating code outside core to use this (or any BAO function) it is recommended that - * you add an api call to lock in into our contract. Currently there is not really a supported - * method for non core functions. - */ - public static function remove() { - Civi::log() - ->warning('Deprecated code. This function should not be called without groupIDs. Extensions can use the api job.group_cache_flush for a hard flush or add an api option for soft flush', ['civi.tag' => 'deprecated']); - CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush(); - } - /** * Function to clear group contact cache and reset the corresponding * group's cache and refresh date @@ -456,6 +439,8 @@ WHERE id IN ( $groupIDs ) * The smart group that needs to be loaded. * @param bool $force * Should we force a search through. + * + * @throws \CRM_Core_Exception */ public static function load(&$group, $force = FALSE) { $groupID = $group->id; @@ -477,68 +462,25 @@ WHERE id IN ( $groupIDs ) if ($savedSearchID) { $ssParams = CRM_Contact_BAO_SavedSearch::getSearchParams($savedSearchID); - // rectify params to what proximity search expects if there is a value for prox_distance - // CRM-7021 - if (!empty($ssParams)) { - CRM_Contact_BAO_ProximityQuery::fixInputParams($ssParams); - } - - $returnProperties = []; - if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $savedSearchID, 'mapping_id')) { - $fv = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID); - $returnProperties = CRM_Core_BAO_Mapping::returnProperties($fv); - } - - if (isset($ssParams['customSearchID'])) { - // if custom search - - // we split it up and store custom class - // so temp tables are not destroyed if they are used - // hence customClass is defined above at top of function - $customClass = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID); - $searchSQL = $customClass->contactIDs(); - $searchSQL = str_replace('ORDER BY contact_a.id ASC', '', $searchSQL); - if (!strstr($searchSQL, 'WHERE')) { - $searchSQL .= " WHERE ( 1 ) "; - } - $sql = [ - 'select' => substr($searchSQL, 0, strpos($searchSQL, 'FROM')), - 'from' => substr($searchSQL, strpos($searchSQL, 'FROM')), - ]; + if (!empty($ssParams['api_entity'])) { + $mainCol = 'a'; + $sql = self::getApiSQL($savedSearchID, $ssParams); } else { - $formValues = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID); - // CRM-17075 using the formValues in this way imposes extra logic and complexity. - // we have the where_clause and where tables stored in the saved_search table - // and should use these rather than re-processing the form criteria (which over-works - // the link between the form layer & the query layer too). - // It's hard to think of when you would want to use anything other than return - // properties = array('contact_id' => 1) here as the point would appear to be to - // generate the list of contact ids in the group. - // @todo review this to use values in saved_search table (preferably for 4.8). - $query - = new CRM_Contact_BAO_Query( - $ssParams, $returnProperties, NULL, - FALSE, FALSE, 1, - TRUE, TRUE, - FALSE, - CRM_Utils_Array::value('display_relationship_type', $formValues), - CRM_Utils_Array::value('operator', $formValues, 'AND') - ); - $query->_useDistinct = FALSE; - $query->_useGroupBy = FALSE; - $sqlParts = $query->getSearchSQLParts( - 0, 0, NULL, - FALSE, FALSE, - FALSE, TRUE - ); - $sql = [ - 'select' => $sqlParts['select'], - 'from' => "{$sqlParts['from']} {$sqlParts['where']} {$sqlParts['having']} {$sqlParts['group_by']}", - ]; + $mainCol = 'contact_a'; + // CRM-7021 rectify params to what proximity search expects if there is a value for prox_distance + if (!empty($ssParams)) { + CRM_Contact_BAO_ProximityQuery::fixInputParams($ssParams); + } + if (isset($ssParams['customSearchID'])) { + $sql = self::getCustomSearchSQL($savedSearchID, $ssParams); + } + else { + $sql = self::getQueryObjectSQL($savedSearchID, $ssParams); + } } $groupID = CRM_Utils_Type::escape($groupID, 'Integer'); - $sql['from'] .= " AND contact_a.id NOT IN ( + $sql['from'] .= " AND $mainCol.id NOT IN ( SELECT contact_id FROM civicrm_group_contact WHERE civicrm_group_contact.status = 'Removed' AND civicrm_group_contact.group_id = $groupID ) "; @@ -775,4 +717,103 @@ ORDER BY gc.contact_id, g.children ]); } + /** + * @param $savedSearchID + * @param array $savedSearch + * @return array + * @throws API_Exception + * @throws \Civi\API\Exception\NotImplementedException + * @throws CRM_Core_Exception + */ + protected static function getApiSQL($savedSearchID, array $savedSearch): array { + $api = \Civi\API\Request::create($savedSearch['api_entity'], 'get', $savedSearch['api_params']); + $query = new \Civi\Api4\Query\Api4SelectQuery($api->getEntityName(), FALSE, $api->entityFields()); + $query->select = ['id']; + $query->where = $api->getWhere(); + $query->orderBy = $api->getOrderBy(); + $query->limit = $api->getLimit(); + $query->offset = $api->getOffset(); + $sql = $query->getSql(); + return [ + 'select' => substr($sql, 0, strpos($sql, 'FROM')), + 'from' => substr($sql, strpos($sql, 'FROM')), + ]; + } + + /** + * Get sql from a custom search. + * + * @param int $savedSearchID + * @param array $ssParams + * + * @return array + * @throws \Exception + */ + protected static function getCustomSearchSQL($savedSearchID, array $ssParams): array { + // if custom search + + // we split it up and store custom class + // so temp tables are not destroyed if they are used + // hence customClass is defined above at top of function + $customClass = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID); + $searchSQL = $customClass->contactIDs(); + $searchSQL = str_replace('ORDER BY contact_a.id ASC', '', $searchSQL); + if (strpos($searchSQL, 'WHERE') === FALSE) { + $searchSQL .= " WHERE ( 1 ) "; + } + $sql = [ + 'select' => substr($searchSQL, 0, strpos($searchSQL, 'FROM')), + 'from' => substr($searchSQL, strpos($searchSQL, 'FROM')), + ]; + return $sql; + } + + /** + * Get array of sql from a saved query object group. + * + * @param int $savedSearchID + * @param array $ssParams + * + * @return array + * @throws \CRM_Core_Exception + * @throws \CiviCRM_API3_Exception + */ + protected static function getQueryObjectSQL($savedSearchID, array $ssParams): array { + $returnProperties = NULL; + if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $savedSearchID, 'mapping_id')) { + $fv = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID); + $returnProperties = CRM_Core_BAO_Mapping::returnProperties($fv); + } + $formValues = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID); + // CRM-17075 using the formValues in this way imposes extra logic and complexity. + // we have the where_clause and where tables stored in the saved_search table + // and should use these rather than re-processing the form criteria (which over-works + // the link between the form layer & the query layer too). + // It's hard to think of when you would want to use anything other than return + // properties = array('contact_id' => 1) here as the point would appear to be to + // generate the list of contact ids in the group. + // @todo review this to use values in saved_search table (preferably for 4.8). + $query + = new CRM_Contact_BAO_Query( + $ssParams, $returnProperties, NULL, + FALSE, FALSE, 1, + TRUE, TRUE, + FALSE, + CRM_Utils_Array::value('display_relationship_type', $formValues), + CRM_Utils_Array::value('operator', $formValues, 'AND') + ); + $query->_useDistinct = FALSE; + $query->_useGroupBy = FALSE; + $sqlParts = $query->getSearchSQLParts( + 0, 0, NULL, + FALSE, FALSE, + FALSE, TRUE + ); + $sql = [ + 'select' => $sqlParts['select'], + 'from' => "{$sqlParts['from']} {$sqlParts['where']} {$sqlParts['having']} {$sqlParts['group_by']}", + ]; + return $sql; + } + }