api4 - Add civicrm_api4() and CRM.api4() entry-points
authorCiviCRM <info@civicrm.org>
Sun, 15 Sep 2019 03:48:43 +0000 (23:48 -0400)
committerTim Otten <totten@civicrm.org>
Sun, 15 Sep 2019 03:48:43 +0000 (23:48 -0400)
api/api.php
js/crm.ajax.js

index 5d67281e45816399b48ec2b34ebaedeeeea2ef85..43f2d735c7a133bbae0c5803907501427dbca410 100644 (file)
@@ -23,6 +23,48 @@ function civicrm_api($entity, $action, $params, $extra = NULL) {
   return \Civi::service('civi_api_kernel')->runSafe($entity, $action, $params, $extra);
 }
 
+/**
+ * Procedural wrapper for the OO api version 4.
+ *
+ * @param string $entity
+ * @param string $action
+ * @param array $params
+ * @param string|int $index
+ *   If $index is a string, the results array will be indexed by that key.
+ *   If $index is an integer, only the result at that index will be returned.
+ *
+ * @return \Civi\Api4\Generic\Result
+ * @throws \API_Exception
+ * @throws \Civi\API\Exception\NotImplementedException
+ */
+function civicrm_api4($entity, $action, $params = [], $index = NULL) {
+  $apiCall = \Civi\Api4\Utils\ActionUtil::getAction($entity, $action);
+  foreach ($params as $name => $param) {
+    $setter = 'set' . ucfirst($name);
+    $apiCall->$setter($param);
+  }
+  $result = $apiCall->execute();
+
+  // Index results by key
+  if ($index && is_string($index) && !CRM_Utils_Rule::integer($index)) {
+    $result->indexBy($index);
+  }
+  // Return result at index
+  if (CRM_Utils_Rule::integer($index)) {
+    $item = $result->itemAt($index);
+    if (is_null($item)) {
+      throw new \API_Exception("Index $index not found in api results");
+    }
+    // Attempt to return a Result object if item is array, otherwise just return the item
+    if (!is_array($item)) {
+      return $item;
+    }
+    $result->exchangeArray($item);
+
+  }
+  return $result;
+}
+
 /**
  * Version 3 wrapper for civicrm_api.
  *
index b64f33eec2c2e34beff9ac375974c9b74016de59..e3ff56d1a6383acbd5bcbfb7f310048918a9cfc3 100644 (file)
     });
   };
 
+  // result is an array, but in js, an array is also an object
+  // Assign all the metadata properties to it, mirroring the results arrayObject in php
+  function arrayObject(data) {
+    var result = data.values || [];
+    if (_.isArray(result)) {
+      delete(data.values);
+      _.assign(result, data);
+    }
+    return result;
+  }
+
+  CRM.api4 = function(entity, action, params, index) {
+    return new Promise(function(resolve, reject) {
+      if (typeof entity === 'string') {
+        $.post(CRM.url('civicrm/ajax/api4/' + entity + '/' + action), {
+          params: JSON.stringify(params),
+          index: index
+        })
+          .done(function (data) {
+            resolve(arrayObject(data));
+          })
+          .fail(function (data) {
+            reject(data.responseJSON);
+          });
+      } else {
+        $.post(CRM.url('civicrm/ajax/api4'), {
+          calls: JSON.stringify(entity)
+        })
+          .done(function(data) {
+            _.each(data, function(item, key) {
+              data[key] = arrayObject(item);
+            });
+            resolve(data);
+          })
+          .fail(function (data) {
+            reject(data.responseJSON);
+          });
+      }
+    });
+  };
+
   /**
    * AJAX api
    * @link http://wiki.civicrm.org/confluence/display/CRMDOC/AJAX+Interface#AJAXInterface-CRM.api3