APIv4 - Add 'match' param to save action
[civicrm-core.git] / Civi / Api4 / Generic / BasicSaveAction.php
CommitLineData
19b53e5b
C
1<?php
2
380f3545
TO
3/*
4 +--------------------------------------------------------------------+
41498ac5 5 | Copyright CiviCRM LLC. All rights reserved. |
380f3545 6 | |
41498ac5
TO
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
380f3545
TO
10 +--------------------------------------------------------------------+
11 */
12
19b53e5b
C
13namespace Civi\Api4\Generic;
14
15use Civi\API\Exception\NotImplementedException;
12e4505a 16use Civi\Api4\Utils\CoreUtil;
19b53e5b
C
17
18/**
58efbb45 19 * @inheritDoc
19b53e5b
C
20 */
21class BasicSaveAction extends AbstractSaveAction {
22
23 /**
24 * @var callable
9bafff7c 25 * Function(array $item, BasicCreateAction $thisAction): array
19b53e5b
C
26 */
27 private $setter;
28
29 /**
58efbb45 30 * Basic Save constructor.
19b53e5b
C
31 *
32 * @param string $entityName
33 * @param string $actionName
19b53e5b 34 * @param callable $setter
19b53e5b 35 */
29ab318b
CW
36 public function __construct($entityName, $actionName, $setter = NULL) {
37 parent::__construct($entityName, $actionName);
38 // Accept setter as 4th param for now, but emit deprecated warning
39 $this->setter = func_get_args()[3] ?? NULL;
40 if ($this->setter) {
41 \CRM_Core_Error::deprecatedWarning(__CLASS__ . ' constructor received $setter as 4th param; it should be the 3rd as the $select param has been removed');
42 }
43 else {
44 $this->setter = $setter;
45 }
19b53e5b
C
46 }
47
48 /**
49 * We pass the writeRecord function an array representing one item to write.
50 * We expect to get the same format back.
51 *
52 * @param \Civi\Api4\Generic\Result $result
53 */
54 public function _run(Result $result) {
12e4505a 55 $idField = CoreUtil::getIdFieldName($this->getEntityName());
961e974c 56 foreach ($this->records as &$record) {
19b53e5b 57 $record += $this->defaults;
961e974c 58 $this->formatWriteValues($record);
db11224f 59 $this->matchExisting($record);
961e974c
CW
60 }
61 $this->validateValues();
62 foreach ($this->records as $item) {
63 $result[] = $this->writeRecord($item);
19b53e5b
C
64 }
65 if ($this->reload) {
66 /** @var BasicGetAction $get */
3a8dc228 67 $get = \Civi\API\Request::create($this->getEntityName(), 'get', ['version' => 4]);
19b53e5b
C
68 $get
69 ->setCheckPermissions($this->getCheckPermissions())
12e4505a 70 ->addWhere($idField, 'IN', (array) $result->column($idField));
19b53e5b
C
71 $result->exchangeArray((array) $get->execute());
72 }
73 }
74
75 /**
76 * This Basic Save class can be used in one of two ways:
77 *
78 * 1. Use this class directly by passing a callable ($setter) to the constructor.
79 * 2. Extend this class and override this function.
80 *
81 * Either way, this function should return an array representing the one new object.
82 *
83 * @param array $item
84 * @return array
85 * @throws \Civi\API\Exception\NotImplementedException
86 */
87 protected function writeRecord($item) {
88 if (is_callable($this->setter)) {
32f72d83 89 $this->addCallbackToDebugOutput($this->setter);
19b53e5b
C
90 return call_user_func($this->setter, $item, $this);
91 }
92 throw new NotImplementedException('Setter function not found for api4 ' . $this->getEntityName() . '::' . $this->getActionName());
93 }
94
95}