return "SELECT $addSelect, `$idField` AS contact_id FROM ($sql) api_query";
}
- /**
- * Get sql from a custom search.
- *
- * We split it up and store custom class
- * so temp tables are not destroyed if they are used
- *
- * @param array $savedSearch
- * @param int $groupID
- *
- * @return string
- * @throws \CRM_Core_Exception
- */
- protected static function getCustomSearchSQL(array $savedSearch, int $groupID) {
- $savedSearchID = $savedSearch['id'];
- $excludeClause = "NOT IN (
- SELECT contact_id FROM civicrm_group_contact
- WHERE civicrm_group_contact.status = 'Removed'
- AND civicrm_group_contact.group_id = $groupID )";
- $addSelect = "$groupID AS group_id";
- $ssParams = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
- // 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);
- }
- $searchSQL = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID)->contactIDs();
- $searchSQL = str_replace('ORDER BY contact_a.id ASC', '', $searchSQL);
- if (strpos($searchSQL, 'WHERE') === FALSE) {
- $searchSQL .= " WHERE contact_a.id $excludeClause";
- }
- else {
- $searchSQL .= " AND contact_a.id $excludeClause";
- }
- return preg_replace("/^\s*SELECT /", "SELECT $addSelect, ", $searchSQL);
- }
-
/**
* Get array of sql from a saved query object group.
*
->execute()
->first();
- if ($savedSearch['api_entity']) {
- $sql = self::getApiSQL($savedSearch, $groupID);
- }
- elseif (!empty($savedSearch['search_custom_id'])) {
- $sql = self::getCustomSearchSQL($savedSearch, $groupID);
- }
- else {
- $sql = self::getQueryObjectSQL($savedSearch, $groupID);
+ $sql = '';
+ CRM_Utils_Hook::buildGroupContactCache($savedSearch, $groupID, $sql);
+ if (!$sql) {
+ if ($savedSearch['api_entity']) {
+ $sql = self::getApiSQL($savedSearch, $groupID);
+ }
+ elseif (!empty($savedSearch['search_custom_id'])) {
+ Group::update(FALSE)->addWhere('id', '=', $groupID)->setValues(['is_active' => FALSE])->execute();
+ CRM_Core_Session::setStatus(ts('Invalid group %1 found and disabled'), [1 => $groupID]);
+ return;
+ }
+ else {
+ $sql = self::getQueryObjectSQL($savedSearch, $groupID);
+ }
}
}
);
}
+ /**
+ * Build the group contact cache for the relevant group.
+ *
+ * This hook allows a listener to specify the sql to be used to build a group in
+ * the group contact cache.
+ *
+ * If sql is altered then the api / bao query methods of building the cache will not
+ * be called.
+ *
+ * An example of the sql it might be set to is:
+ *
+ * SELECT 7 AS group_id, contact_a.id as contact_id
+ * FROM civicrm_contact contact_a
+ * WHERE contact_a.contact_type = 'Household' AND contact_a.household_name LIKE '%' AND ( 1 ) ORDER BY contact_a.id
+ * AND contact_a.id
+ * NOT IN (
+ * SELECT contact_id FROM civicrm_group_contact
+ * WHERE civicrm_group_contact.status = 'Removed'
+ * AND civicrm_group_contact.group_id = 7 )
+ *
+ * @param array $savedSearch
+ * @param int $groupID
+ * @param string $sql
+ */
+ public static function buildGroupContactCache(array $savedSearch, int $groupID, string &$sql): void {
+ $null = NULL;
+ self::singleton()->invoke(['savedSearch', 'groupID', 'sql'], $savedSearch, $groupID,
+ $sql, $null, $null, $null,
+ 'civicrm_buildGroupContactCache'
+ );
+ }
+
/**
* (EXPERIMENTAL) Scan extensions for a list of auto-registered interfaces.
*
function legacycustomsearches_civicrm_enable() {
_legacycustomsearches_civix_civicrm_enable();
}
+
+/**
+ * Determine the sql
+ * @param array $savedSearch
+ * @param int $groupID
+ * @param string $sql
+ *
+ * @throws \CRM_Core_Exception
+ */
+function legacycustomsearches_civicrm_buildGroupContactCache(array $savedSearch, int $groupID, string &$sql): void {
+ if (empty($savedSearch['search_custom_id'])) {
+ return;
+ }
+ $savedSearchID = $savedSearch['id'];
+ $excludeClause = "
+ NOT IN (
+ SELECT contact_id FROM civicrm_group_contact
+ WHERE civicrm_group_contact.status = 'Removed'
+ AND civicrm_group_contact.group_id = $groupID )";
+ $addSelect = "$groupID AS group_id";
+ $ssParams = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
+ // 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);
+ }
+ $searchSQL = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID)->contactIDs();
+ $searchSQL = str_replace('ORDER BY contact_a.id ASC', '', $searchSQL);
+ if (strpos($searchSQL, 'WHERE') === FALSE) {
+ $searchSQL .= " WHERE contact_a.id $excludeClause";
+ }
+ else {
+ $searchSQL .= " AND contact_a.id $excludeClause";
+ }
+ $sql = preg_replace("/^\s*SELECT /", "SELECT $addSelect, ", $searchSQL);
+}