CRM-16036 - _civicrm_api3_get_using_utils_sql - Pass SQL fragments as object
authorTim Otten <totten@civicrm.org>
Sun, 16 Aug 2015 04:28:44 +0000 (21:28 -0700)
committerTim Otten <totten@civicrm.org>
Sun, 16 Aug 2015 22:13:50 +0000 (15:13 -0700)
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)`).

api/v3/Activity.php
api/v3/Event.php
api/v3/utils.php

index f2bdf593b8349a08ef5770dac664f49785078342..e13ac5ea96061ebe4564a5d03a257c3b984835dd 100644 (file)
@@ -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']) {
index 9d1606f2feb5550a06a01ae3e8e3c20f3b193178..cfa9980143a2104913213a30be50ae24ba9de2df 100644 (file)
@@ -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');
index cbc1fa4274efe56778cbe3c8d6f04838d10a076b..479afac1b60bbe0f7b58e608d8ad5506d59408fd 100644 (file)
@@ -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);
   }
 }