CRM-17640 Update contribution api to do a sensible query when getcount is being invoked
authoreileen <emcnaughton@wikimedia.org>
Tue, 1 Dec 2015 13:56:20 +0000 (02:56 +1300)
committereileen <emcnaughton@wikimedia.org>
Tue, 1 Dec 2015 15:45:08 +0000 (04:45 +1300)
Without this patch contribution.getcount api does a full query with the full set of select fields and
the nasty joins those entail and only after doing that does it filter for count.

This patch re-uses the code in use for contact api query for contribution getcount

CRM/Contact/BAO/Query.php
CRM/Contribute/BAO/Query.php
api/v3/Contribution.php
api/v3/utils.php

index 5343c290d5d6699b8adf13b9c581320087a11ba8..798f730e8afb26f7def00f3c5eb42587666fbc83 100644 (file)
@@ -1320,7 +1320,7 @@ class CRM_Contact_BAO_Query {
         // we add distinct to get the right count for components
         // for the more complex result set, we use GROUP BY the same id
         // CRM-9630
-        $select = "SELECT count( DISTINCT {$this->_distinctComponentClause} )";
+        $select = "SELECT count( DISTINCT {$this->_distinctComponentClause} ) as rowCount";
       }
       else {
         $select = 'SELECT count(DISTINCT contact_a.id) as rowCount';
@@ -4239,7 +4239,8 @@ civicrm_relationship.is_permission_a_b = 0
    *   Return count obnly.
    * @param bool $skipPermissions
    *   Should permissions be ignored or should the logged in user's permissions be applied.
-   *
+   * @param int $mode
+   *   This basically correlates to the component.
    *
    * @return array
    */
@@ -4252,12 +4253,13 @@ civicrm_relationship.is_permission_a_b = 0
     $row_count = 25,
     $smartGroupCache = TRUE,
     $count = FALSE,
-    $skipPermissions = TRUE
+    $skipPermissions = TRUE,
+    $mode = 1
   ) {
 
     $query = new CRM_Contact_BAO_Query(
       $params, $returnProperties,
-      NULL, TRUE, FALSE, 1,
+      NULL, TRUE, FALSE, $mode,
       $skipPermissions,
       TRUE, $smartGroupCache
     );
@@ -4295,12 +4297,15 @@ civicrm_relationship.is_permission_a_b = 0
     }
     if ($row_count > 0 && $offset >= 0) {
       $offset = CRM_Utils_Type::escape($offset, 'Int');
-      $rowCount = CRM_Utils_Type::escape($row_count, 'Int');
+      $row_count = CRM_Utils_Type::escape($row_count, 'Int');
       $sql .= " LIMIT $offset, $row_count ";
     }
 
     $dao = CRM_Core_DAO::executeQuery($sql);
 
+    // @todo derive this from the component class rather than hard-code two options.
+    $entityIDField = ($mode == CRM_Contact_BAO_Query::MODE_CONTRIBUTE) ? 'contribution_id' : 'contact_id';
+
     $values = array();
     while ($dao->fetch()) {
       if ($count) {
@@ -4314,7 +4319,7 @@ civicrm_relationship.is_permission_a_b = 0
       if (!empty($convertedVals)) {
         $val = array_replace_recursive($val, $convertedVals);
       }
-      $values[$dao->contact_id] = $val;
+      $values[$dao->$entityIDField] = $val;
     }
     $dao->free();
     return array($values, $options);
index 99eab181fb7afecf49002c9ff12b6b4a860403eb..fa4cd6e952d6ded9480ee4077eb34bcb9d7e41b8 100644 (file)
@@ -775,12 +775,16 @@ class CRM_Contribute_BAO_Query {
    * @param CRM_Contact_BAO_Query $query
    */
   public static function initializeAnySoftCreditClause(&$query) {
-    if (self::isSoftCreditOptionEnabled($query->_params)) {
-      if ($query->_mode & CRM_Contact_BAO_Query::MODE_CONTRIBUTE) {
+
+    if ($query->_mode & CRM_Contact_BAO_Query::MODE_CONTRIBUTE) {
+      if (self::isSoftCreditOptionEnabled($query->_params)) {
         unset($query->_distinctComponentClause);
         $query->_rowCountClause = " count(civicrm_contribution.id)";
         $query->_groupByComponentClause = " GROUP BY contribution_search_scredit_combined.id, contribution_search_scredit_combined.contact_id, contribution_search_scredit_combined.scredit_id ";
       }
+      else {
+        $query->_distinctComponentClause = ' civicrm_contribution.id';
+      }
     }
   }
 
index 00aa5ccbdb78f79c026ee22f1c3adb8ad69a59ce..3003eb5f37ed214dd64a22469d199298fc9fa1df 100644 (file)
@@ -252,7 +252,19 @@ function civicrm_api3_contribution_get($params) {
     // format soft credit for backward compatibility
     _civicrm_api3_format_soft_credit($contribution[$dao->contribution_id]);
   }
-  return civicrm_api3_create_success($contribution, $params, 'Contribution', 'get', $dao);
+  return civicrm_api3_create_success($contribution, $params, 'Contribution', 'get');
+}
+
+/**
+ * Get number of contacts matching the supplied criteria.
+ *
+ * @param array $params
+ *
+ * @return int
+ */
+function civicrm_api3_contribution_getcount($params) {
+  $count = _civicrm_api3_get_using_query_object('Contribution', $params, array(), TRUE, CRM_Contact_BAO_Query::MODE_CONTRIBUTE);
+  return (int) $count;
 }
 
 /**
index 9601e583872d8fafc6d45e648560b0821ce087d1..1590bad76985f172123b181df5f465b0c369e4a1 100644 (file)
@@ -845,10 +845,12 @@ SELECT f.id, f.label, f.data_type,
  *   Array of options (so we can modify the filter).
  * @param bool $getCount
  *   Are we just after the count.
+ * @param int $mode
+ *   This basically correlates to the component.
  *
  * @return array
  */
-function _civicrm_api3_get_using_query_object($entity, $params, $additional_options = array(), $getCount = NULL) {
+function _civicrm_api3_get_using_query_object($entity, $params, $additional_options = array(), $getCount = NULL, $mode = 1, $defaultReturnProperties = NULL) {
   $lowercase_entity = _civicrm_api_get_entity_name_from_camel($entity);
   // Convert id to e.g. contact_id
   if (empty($params[$lowercase_entity . '_id']) && isset($params['id'])) {
@@ -867,7 +869,7 @@ function _civicrm_api3_get_using_query_object($entity, $params, $additional_opti
     CRM_Utils_Array::value('return', $additional_options, array())
   );
   if (empty($returnProperties)) {
-    $returnProperties = NULL;
+    $returnProperties = $defaultReturnProperties;
   }
   if (!empty($params['check_permissions'])) {
     // we will filter query object against getfields
@@ -905,7 +907,7 @@ function _civicrm_api3_get_using_query_object($entity, $params, $additional_opti
 
   $skipPermissions = !empty($params['check_permissions']) ? 0 : 1;
 
-  list($entities, $options) = CRM_Contact_BAO_Query::apiQuery(
+  list($entities) = CRM_Contact_BAO_Query::apiQuery(
     $newParams,
     $returnProperties,
     NULL,
@@ -914,7 +916,8 @@ function _civicrm_api3_get_using_query_object($entity, $params, $additional_opti
     $limit,
     $smartGroupCache,
     $getCount,
-    $skipPermissions
+    $skipPermissions,
+    $mode
   );
   if ($getCount) {
     // only return the count of contacts