From 4fd13075c1a1bda112fe11fdfe767616b4530693 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Sun, 20 Jun 2021 16:16:05 -0400 Subject: [PATCH] APIv4 - Support FK field lookups in create/update/save actions --- Civi/Api4/Generic/Traits/DAOActionTrait.php | 29 +++++++++++++++++++++ tests/phpunit/api/v4/Action/FkJoinTest.php | 7 ++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Civi/Api4/Generic/Traits/DAOActionTrait.php b/Civi/Api4/Generic/Traits/DAOActionTrait.php index af61135448..76df9951a4 100644 --- a/Civi/Api4/Generic/Traits/DAOActionTrait.php +++ b/Civi/Api4/Generic/Traits/DAOActionTrait.php @@ -164,6 +164,35 @@ trait DAOActionTrait { return $result; } + /** + * @inheritDoc + */ + protected function formatWriteValues(&$record) { + $this->resolveFKValues($record); + parent::formatWriteValues($record); + } + + /** + * Looks up an id based on some other property of an fk entity + * + * @param array $record + */ + private function resolveFKValues(array &$record): void { + foreach ($record as $key => $value) { + if (substr_count($key, '.') !== 1) { + continue; + } + [$fieldName, $fkField] = explode('.', $key); + $field = $this->entityFields()[$fieldName] ?? NULL; + if (!$field || empty($field['fk_entity'])) { + continue; + } + $fkDao = CoreUtil::getBAOFromApiName($field['fk_entity']); + $record[$fieldName] = \CRM_Core_DAO::getFieldValue($fkDao, $value, 'id', $fkField); + unset($record[$key]); + } + } + /** * @param array $params * @param int $entityId diff --git a/tests/phpunit/api/v4/Action/FkJoinTest.php b/tests/phpunit/api/v4/Action/FkJoinTest.php index d02ac67c28..efadad0475 100644 --- a/tests/phpunit/api/v4/Action/FkJoinTest.php +++ b/tests/phpunit/api/v4/Action/FkJoinTest.php @@ -173,17 +173,18 @@ class FkJoinTest extends UnitTestCase { ->addValue('name', uniqid('join3')) ->execute() ->first()['name']; - + // Create using pseudoconstant syntax (:name) $cid1 = Contact::create(FALSE) ->addValue('first_name', 'Aaa') ->addChain('tag1', EntityTag::create()->setValues(['entity_id' => '$id', 'tag_id:name' => $tag1])) ->addChain('tag2', EntityTag::create()->setValues(['entity_id' => '$id', 'tag_id:name' => $tag2])) ->execute() ->first()['id']; + // Create using fk syntax (.name) $cid2 = Contact::create(FALSE) ->addValue('first_name', 'Bbb') - ->addChain('tag1', EntityTag::create()->setValues(['entity_id' => '$id', 'tag_id:name' => $tag1])) - ->addChain('tag3', EntityTag::create()->setValues(['entity_id' => '$id', 'tag_id:name' => $tag3])) + ->addChain('tag1', EntityTag::create()->setValues(['entity_id' => '$id', 'tag_id.name' => $tag1])) + ->addChain('tag3', EntityTag::create()->setValues(['entity_id' => '$id', 'tag_id.name' => $tag3])) ->execute() ->first()['id']; $cid3 = Contact::create(FALSE) -- 2.25.1