A bit less svn
[civicrm-core.git] / Civi / Api4 / Generic / BasicReplaceAction.php
index 31f12a44acad344f76a851bbf1b7fcee2da55620..ca4d03c13ab48f77367ea8426980e7ac6732a460 100644 (file)
  *
  * @package CRM
  * @copyright CiviCRM LLC https://civicrm.org/licensing
- * $Id$
- *
  */
 
 
 namespace Civi\Api4\Generic;
 
-use Civi\API\Exception\NotImplementedException;
-use Civi\Api4\Utils\ActionUtil;
-
 /**
- * Given a set of records, will appropriately update the database.
+ * Replaces an existing set of $ENTITIES with a new one.
+ *
+ * This will select a group of existing $ENTITIES based on the `where` parameter.
+ * Each will be compared with the $ENTITIES passed in as `records`:
+ *
+ *  - $ENTITIES in `records` that don't already exist will be created.
+ *  - Existing $ENTITIES that are included in `records` will be updated.
+ *  - Existing $ENTITIES that are omitted from `records` will be deleted.
  *
- * @method $this setRecords(array $records) Array of records.
+ * @method $this setRecords(array $records) Set array of records.
  * @method array getRecords()
- * @method $this setDefaults(array $defaults) Array of defaults.
+ * @method $this setDefaults(array $defaults) Set array of defaults.
  * @method array getDefaults()
  * @method $this setReload(bool $reload) Specify whether complete objects will be returned after saving.
  * @method bool getReload()
@@ -37,9 +39,9 @@ use Civi\Api4\Utils\ActionUtil;
 class BasicReplaceAction extends AbstractBatchAction {
 
   /**
-   * Array of records.
+   * Array of $ENTITY records.
    *
-   * Should be in the same format as returned by Get.
+   * Should be in the same format as returned by `Get`.
    *
    * @var array
    * @required
@@ -49,18 +51,23 @@ class BasicReplaceAction extends AbstractBatchAction {
   /**
    * Array of default values.
    *
-   * Will be merged into $records before saving.
+   * These defaults will be merged into every $ENTITY in `records` before saving.
+   * Values set in `records` will override these defaults if set in both places,
+   * but updating existing $ENTITIES will overwrite current values with these defaults.
+   *
+   * **Note:** Values from the `where` clause that use the `=` operator are _also_ treated as default values;
+   * those do not need to be repeated here.
    *
    * @var array
    */
   protected $defaults = [];
 
   /**
-   * Reload records after saving.
+   * Reload $ENTITIES after saving.
    *
-   * By default this api typically returns partial records containing only the fields
-   * that were updated. Set reload to TRUE to do an additional lookup after saving
-   * to return complete records.
+   * By default this action typically returns partial records containing only the fields
+   * that were updated. Set `reload` to `true` to do an additional lookup after saving
+   * to return complete values for every $ENTITY.
    *
    * @var bool
    */
@@ -89,36 +96,13 @@ class BasicReplaceAction extends AbstractBatchAction {
     $idField = $this->getSelect()[0];
     $toDelete = array_diff_key(array_column($items, NULL, $idField), array_flip(array_filter(\CRM_Utils_Array::collect($idField, $this->records))));
 
-    // Try to delegate to the Save action
-    try {
-      $saveAction = ActionUtil::getAction($this->getEntityName(), 'save');
-      $saveAction
-        ->setCheckPermissions($this->getCheckPermissions())
-        ->setReload($this->reload)
-        ->setRecords($this->records)
-        ->setDefaults($this->defaults);
-      $result->exchangeArray((array) $saveAction->execute());
-    }
-    // Fall back on Create/Update if Save doesn't exist
-    catch (NotImplementedException $e) {
-      foreach ($this->records as $record) {
-        $record += $this->defaults;
-        if (!empty($record[$idField])) {
-          $result[] = civicrm_api4($this->getEntityName(), 'update', [
-            'reload' => $this->reload,
-            'where' => [[$idField, '=', $record[$idField]]],
-            'values' => $record,
-            'checkPermissions' => $this->getCheckPermissions(),
-          ])->first();
-        }
-        else {
-          $result[] = civicrm_api4($this->getEntityName(), 'create', [
-            'values' => $record,
-            'checkPermissions' => $this->getCheckPermissions(),
-          ])->first();
-        }
-      }
-    }
+    $saveAction = \Civi\API\Request::create($this->getEntityName(), 'save', ['version' => 4]);
+    $saveAction
+      ->setCheckPermissions($this->getCheckPermissions())
+      ->setReload($this->reload)
+      ->setRecords($this->records)
+      ->setDefaults($this->defaults);
+    $result->exchangeArray((array) $saveAction->execute());
 
     if ($toDelete) {
       $result->deleted = (array) civicrm_api4($this->getEntityName(), 'delete', [