From: Tim Otten Date: Sun, 16 Aug 2015 04:28:44 +0000 (-0700) Subject: CRM-16036 - _civicrm_api3_get_using_utils_sql - Pass SQL fragments as object X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=01c8287d8062f22d4ecadafbd97fc487375de960;p=civicrm-core.git CRM-16036 - _civicrm_api3_get_using_utils_sql - Pass SQL fragments as object This enables IDE goodies (autocomplete/drilldown/docs) and allows you to use CRM_Utils_SQL_Select's interpolate/escape/implode features (e.g. `foo.id IN (#idlist)`). --- diff --git a/api/v3/Activity.php b/api/v3/Activity.php index f2bdf593b8..e13ac5ea96 100644 --- a/api/v3/Activity.php +++ b/api/v3/Activity.php @@ -242,7 +242,7 @@ function civicrm_api3_activity_get($params) { } } else { - $extraSql = array(); + $sql = CRM_Utils_SQL_Select::fragment(); $options = civicrm_api3('ActivityContact', 'getoptions', array('field' => 'record_type_id')); $options = $options['values']; $activityContactOptions = array( @@ -252,15 +252,20 @@ function civicrm_api3_activity_get($params) { ); foreach ($activityContactOptions as $activityContactName => $activityContactValue) { if (!empty($params[$activityContactName])) { - $extraSql['join'][] = array( - 'activity_' . $activityContactName => ' - LEFT JOIN civicrm_activity_contact ac ON a.id = ac.activity_id AND ac.record_type_id = ' . (int) $activityContactValue, + // If the intent is to have multiple joins -- one for each relation -- then you would + // need different table aliases. Consider replacing 'ac' and passing in a '!alias' param, + // with a different value for each relation. + $sql->join( + 'activity_' . $activityContactName, + 'LEFT JOIN civicrm_activity_contact ac ON a.id = ac.activity_id AND ac.record_type_id = #typeId', + array('typeId' => $activityContactValue) ); - // Note that if we later need to change the int to an array we would need sql escaping. - $extraSql['where'] = array('activity_' . $activityContactName => 'ac.contact_id = ' . (int) $params[$activityContactName]); + $sql->where('ac.contact_id IN (#cid)', array( + 'cid' => $params[$activityContactName], + )); } } - $activities = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Activity', $extraSql); + $activities = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Activity', $sql); } $options = _civicrm_api3_get_options_from_params($params, FALSE, 'Activity', 'get'); if ($options['is_count']) { diff --git a/api/v3/Event.php b/api/v3/Event.php index 9d1606f2fe..cfa9980143 100644 --- a/api/v3/Event.php +++ b/api/v3/Event.php @@ -125,12 +125,12 @@ function civicrm_api3_event_get($params) { unset($params['return.max_results']); } - $extraSql = array(); + $sql = CRM_Utils_SQL_Select::fragment(); if (!empty($params['isCurrent'])) { - $extraSql['where'] = array('civicrm_event' => '(start_date >= CURDATE() || end_date >= CURDATE())'); + $sql->where('(start_date >= CURDATE() || end_date >= CURDATE())'); } - $events = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Event', $extraSql, TRUE); + $events = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, FALSE, 'Event', $sql, TRUE); $options = _civicrm_api3_get_options_from_params($params); if ($options['is_count']) { return civicrm_api3_create_success($events, $params, 'Event', 'get'); diff --git a/api/v3/utils.php b/api/v3/utils.php index cbc1fa4274..479afac1b6 100644 --- a/api/v3/utils.php +++ b/api/v3/utils.php @@ -470,11 +470,11 @@ function _civicrm_api3_store_values(&$fields, &$params, &$values) { * As passed into api get function. * @param bool $isFillUniqueFields * Do we need to ensure unique fields continue to be populated for this api? (backward compatibility). - * @param array $extraMysql + * @param CRM_Utils_SQL_Select|NULL $sqlFragment * * @return array */ -function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFields, $extraMysql) { +function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFields, $sqlFragment) { $dao = new $dao_name(); $entity = _civicrm_api_get_entity_name_from_dao($dao); @@ -699,19 +699,8 @@ function _civicrm_api3_get_using_utils_sql($dao_name, $params, $isFillUniqueFiel )); } }; - if (!empty($extraMysql)) { - foreach ($extraMysql as $type => $extraClauses) { - foreach ($extraClauses as $clauseKey => $clause) { - if ($type == 'join') { - foreach ($clause as $joinName => $join) { - $query->$type($joinName, $join); - } - } - else { - $query->$type($clause); - } - } - } + if (!empty($sqlFragment)) { + $query->merge($sqlFragment); } // order by @@ -1637,21 +1626,21 @@ function _civicrm_api3_check_required_fields($params, $daoName, $return = FALSE) * @param bool $returnAsSuccess * Return in api success format. * @param string $entity - * @param array $extraSql - * API specific queries eg for event isCurrent would be converted to - * $extraSql['where'] = array('civicrm_event' => array('(start_date >= CURDATE() || end_date >= CURDATE())')); + * @param CRM_Utils_SQL_Select|NULL $sql + * Extra SQL bits to add to the query. For filtering current events, this might be: + * CRM_Utils_SQL_Select::fragment()->where('(start_date >= CURDATE() || end_date >= CURDATE())'); * @param bool $uniqueFields * Should unique field names be returned (for backward compatibility) * * @return array */ -function _civicrm_api3_basic_get($bao_name, &$params, $returnAsSuccess = TRUE, $entity = "", $extraSql = array(), $uniqueFields = FALSE) { +function _civicrm_api3_basic_get($bao_name, &$params, $returnAsSuccess = TRUE, $entity = "", $sql = NULL, $uniqueFields = FALSE) { if ($returnAsSuccess) { - return civicrm_api3_create_success(_civicrm_api3_get_using_utils_sql($bao_name, $params, $uniqueFields, $extraSql), $params, $entity, 'get'); + return civicrm_api3_create_success(_civicrm_api3_get_using_utils_sql($bao_name, $params, $uniqueFields, $sql), $params, $entity, 'get'); } else { - return _civicrm_api3_get_using_utils_sql($bao_name, $params, $uniqueFields, $extraSql); + return _civicrm_api3_get_using_utils_sql($bao_name, $params, $uniqueFields, $sql); } }