APIv4 - Fix Setting api to work with index param
authorColeman Watts <coleman@civicrm.org>
Thu, 15 Apr 2021 19:36:55 +0000 (15:36 -0400)
committerColeman Watts <coleman@civicrm.org>
Thu, 15 Apr 2021 20:59:53 +0000 (16:59 -0400)
The api tries to force index params into the "Select" clause
which doesn't make sense for the oddball "Setting" api.

api/api.php
tests/phpunit/api/v4/Entity/SettingTest.php

index be1946db3735796f65dd091d9d3aece9908d98e6..795d3c0a341b99190b3338fe4d58770cf1f13e3c 100644 (file)
@@ -63,8 +63,8 @@ function civicrm_api4(string $entity, string $action, array $params = [], $index
   $indexField = $index && is_string($index) && !CRM_Utils_Rule::integer($index) ? $index : NULL;
   $removeIndexField = FALSE;
 
-  // If index field is not part of the select query, we add it here and remove it below
-  if ($indexField && !empty($params['select']) && is_array($params['select']) && !\Civi\Api4\Utils\SelectUtil::isFieldSelected($indexField, $params['select'])) {
+  // If index field is not part of the select query, we add it here and remove it below (except for oddball "Setting" api)
+  if ($indexField && !empty($params['select']) && is_array($params['select']) && $entity !== 'Setting' && !\Civi\Api4\Utils\SelectUtil::isFieldSelected($indexField, $params['select'])) {
     $params['select'][] = $indexField;
     $removeIndexField = TRUE;
   }
@@ -73,7 +73,8 @@ function civicrm_api4(string $entity, string $action, array $params = [], $index
   if ($index && is_array($index)) {
     $indexCol = reset($index);
     $indexField = key($index);
-    if (property_exists($apiCall, 'select')) {
+    // 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]);
       if ($indexField && $indexField != $indexCol) {
         $apiCall->addSelect($indexField);
index 0a3657028902fe00ee7087b2ae2d28fa48b52ac6..a50c00605ce5b69702447bad08dc5a08a25a62be 100644 (file)
@@ -57,4 +57,25 @@ class SettingTest extends UnitTestCase {
     $this->assertTrue(is_array($settings[0]['value']));
   }
 
+  /**
+   * Ensure settings work with the "index" mode.
+   */
+  public function testSettingsWithIndexParam() {
+    $settings = civicrm_api4('Setting', 'get', [], ['name' => 'value']);
+    $stringValues = FALSE;
+    $arrayValues = FALSE;
+    // With indexing by [name => value], keys should be string and values should be string/array
+    foreach ($settings as $name => $value) {
+      $this->assertTrue(is_string($name) && !is_numeric($name));
+      if (is_string($value)) {
+        $stringValues = TRUE;
+      }
+      elseif (is_array($value)) {
+        $arrayValues = TRUE;
+      }
+    }
+    $this->assertTrue($stringValues);
+    $this->assertTrue($arrayValues);
+  }
+
 }