APIv4 - Fix index interfering with HAVING
authorcolemanw <coleman@civicrm.org>
Tue, 14 Nov 2023 18:40:29 +0000 (13:40 -0500)
committercolemanw <coleman@civicrm.org>
Wed, 15 Nov 2023 19:42:14 +0000 (14:42 -0500)
It's not always safe to delete items from the SELECT clause... so let's not.
Fixes dev/core#4017

api/api.php
ext/afform/core/afform.php
tests/phpunit/api/v4/Action/SqlFunctionTest.php

index bc307f1596e41c824f2540fbc8275a4e5df8ace5..4fd54bcfd9656133668b2328fc8670eebfd5576e 100644 (file)
@@ -79,9 +79,9 @@ function civicrm_api4(string $entity, string $action, array $params = [], $index
   if ($index && is_array($index)) {
     $indexCol = reset($index);
     $indexField = key($index);
-    // Index array indicates only 1 or 2 fields need to be selected (except for oddball "Setting" api)
-    if ($entity !== 'Setting' && property_exists($apiCall, 'select')) {
-      $apiCall->setSelect([$indexCol]);
+    // Automatically add index fields(s) to the SELECT clause
+    if ($entity !== 'Setting' && method_exists($apiCall, 'addSelect')) {
+      $apiCall->addSelect($indexCol);
       if ($indexField && $indexField != $indexCol) {
         $apiCall->addSelect($indexField);
       }
index ad422e8aa16811ade84ed7dd7ae87a0178a65bbc..e0ecada9c99c677d020c31388753ed1d09059974 100644 (file)
@@ -588,7 +588,6 @@ function afform_civicrm_referenceCounts($dao, &$counts) {
     try {
       $displays = civicrm_api4('SearchDisplay', 'get', [
         'where' => [['saved_search_id', '=', $dao->id]],
-        'select' => 'name',
       ], ['name']);
       foreach ($displays as $displayName) {
         $clauses[] = ['search_displays', 'CONTAINS', $dao->name . '.' . $displayName];
index 232709eb0e7d9aff99c109b787fc7ddc5c0c439f..cc5d650459281c41ac752a36b55af77a3fb31d49 100644 (file)
@@ -174,19 +174,20 @@ class SqlFunctionTest extends Api4TestBase implements TransactionalInterface {
     $this->assertEquals(2, $result[0]['count']);
     $this->assertEquals(1, $result[1]['count']);
 
-    $result = Contribution::get(FALSE)
-      ->addGroupBy('contact_id')
-      ->addGroupBy('receive_date')
-      ->addSelect('contact_id')
-      ->addSelect('receive_date')
-      ->addSelect('SUM(total_amount)')
-      ->addOrderBy('receive_date')
-      ->addWhere('contact_id', '=', $cid)
-      ->addHaving('SUM(total_amount)', '>', 300)
-      ->execute();
+    $result = (array) civicrm_api4('Contribution', 'get', [
+      'checkPermissions' => FALSE,
+      'groupBy' => ['contact_id', 'receive_date'],
+      'select' => ['contact_id', 'DATE(receive_date)', 'SUM(total_amount)'],
+      'orderBy' => ['receive_date' => 'ASC'],
+      'where' => [
+        ['contact_id', '=', $cid],
+      ],
+      'having' => [
+        ['SUM(total_amount)', '>', 300],
+      ],
+    ], ['DATE:receive_date' => 'SUM:total_amount']);
     $this->assertCount(1, $result);
-    $this->assertStringStartsWith('2020-04-04', $result[0]['receive_date']);
-    $this->assertEquals(400, $result[0]['SUM:total_amount']);
+    $this->assertEquals(['2020-04-04' => 400], $result);
   }
 
   public function testComparisonFunctions(): void {