diff --git a/Civi/Api4/Generic/Traits/DAOActionTrait.php b/Civi/Api4/Generic/Traits/DAOActionTrait.php index af611354480c2320c8082e248b86774715c7a329..76df9951a41d4b58eaaba7e34dd860be6bcaa49b 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 dcacfd0efa11c9e26bb08342a48a0e834f8fbf38..efadad04754499b6fbb57678d1d8a2f4e03d4a79 100644 --- a/tests/phpunit/api/v4/Action/FkJoinTest.php +++ b/tests/phpunit/api/v4/Action/FkJoinTest.php @@ -161,51 +161,52 @@ class FkJoinTest extends UnitTestCase { } public function testBridgeJoinTags() { - $tag1 = Tag::create()->setCheckPermissions(FALSE) + $tag1 = Tag::create(FALSE) ->addValue('name', uniqid('join1')) ->execute() ->first()['name']; - $tag2 = Tag::create()->setCheckPermissions(FALSE) + $tag2 = Tag::create(FALSE) ->addValue('name', uniqid('join2')) ->execute() ->first()['name']; - $tag3 = Tag::create()->setCheckPermissions(FALSE) + $tag3 = Tag::create(FALSE) ->addValue('name', uniqid('join3')) ->execute() ->first()['name']; - - $cid1 = Contact::create()->setCheckPermissions(FALSE) + // 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']; - $cid2 = Contact::create()->setCheckPermissions(FALSE) + // 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()->setCheckPermissions(FALSE) + $cid3 = Contact::create(FALSE) ->addValue('first_name', 'Ccc') ->execute() ->first()['id']; - $required = Contact::get()->setCheckPermissions(FALSE) + $required = Contact::get(FALSE) ->addJoin('Tag', TRUE, 'EntityTag') ->addSelect('first_name', 'tag.name') ->addWhere('id', 'IN', [$cid1, $cid2, $cid3]) ->execute(); $this->assertCount(4, $required); - $optional = Contact::get()->setCheckPermissions(FALSE) + $optional = Contact::get(FALSE) ->addJoin('Tag', FALSE, 'EntityTag', ['tag.name', 'IN', [$tag1, $tag2, $tag3]]) ->addSelect('first_name', 'tag.name') ->addWhere('id', 'IN', [$cid1, $cid2, $cid3]) ->execute(); $this->assertCount(5, $optional); - $grouped = Contact::get()->setCheckPermissions(FALSE) + $grouped = Contact::get(FALSE) ->addJoin('Tag', FALSE, 'EntityTag', ['tag.name', 'IN', [$tag1, $tag3]]) ->addSelect('first_name', 'COUNT(tag.name) AS tag_count') ->addWhere('id', 'IN', [$cid1, $cid2, $cid3]) @@ -215,7 +216,7 @@ class FkJoinTest extends UnitTestCase { $this->assertEquals(2, (int) $grouped[$cid2]['tag_count']); $this->assertEquals(0, (int) $grouped[$cid3]['tag_count']); - $reverse = Tag::get()->setCheckPermissions(FALSE) + $reverse = Tag::get(FALSE) ->addJoin('Contact', FALSE, 'EntityTag', ['contact.id', 'IN', [$cid1, $cid2, $cid3]]) ->addGroupBy('id') ->addSelect('name', 'COUNT(contact.id) AS contacts') @@ -226,7 +227,7 @@ class FkJoinTest extends UnitTestCase { } public function testBridgeJoinRelationshipContactActivity() { - $cid1 = Contact::create()->setCheckPermissions(FALSE) + $cid1 = Contact::create(FALSE) ->addValue('first_name', 'Aaa') ->addChain('activity', Activity::create() ->addValue('activity_type_id:name', 'Meeting') @@ -235,7 +236,7 @@ class FkJoinTest extends UnitTestCase { ) ->execute() ->first()['id']; - $cid2 = Contact::create()->setCheckPermissions(FALSE) + $cid2 = Contact::create(FALSE) ->addValue('first_name', 'Bbb') ->addChain('activity', Activity::create() ->addValue('activity_type_id:name', 'Phone Call') @@ -247,7 +248,7 @@ class FkJoinTest extends UnitTestCase { ) ->execute() ->first()['id']; - $cid3 = Contact::create()->setCheckPermissions(FALSE) + $cid3 = Contact::create(FALSE) ->addValue('first_name', 'Ccc') ->addChain('activity', Activity::create() ->addValue('activity_type_id:name', 'Meeting') diff --git a/tests/phpunit/api/v4/Entity/SystemTest.php b/tests/phpunit/api/v4/Entity/SystemTest.php index 11203e70ec8ad9a7f44e416875395997e30b0429..435c7cb98f37c088ff4f9c9bc964cd9074553ec7 100644 --- a/tests/phpunit/api/v4/Entity/SystemTest.php +++ b/tests/phpunit/api/v4/Entity/SystemTest.php @@ -50,7 +50,7 @@ class SystemTest extends UnitTestCase { $this->assertCount(1, $check); // Ensure cron check has not run - $this->assertCount(0, StatusPreference::get()->setCheckPermissions(FALSE)->addWhere('name', '=', 'checkLastCron')->execute()); + $this->assertCount(0, StatusPreference::get(FALSE)->addWhere('name', '=', 'checkLastCron')->execute()); // Will run on non-prod site with $includeDisabled. // Giving a more-specific name will run all checks with less-specific names too @@ -60,7 +60,7 @@ class SystemTest extends UnitTestCase { $this->assertEquals('Ok', $check['hook_civicrm_check']['title']); // We know the cron check has run because it would have left a record marked 'new' - $record = StatusPreference::get()->setCheckPermissions(FALSE)->addWhere('name', '=', 'checkLastCron')->execute()->first(); + $record = StatusPreference::get(FALSE)->addWhere('name', '=', 'checkLastCron')->execute()->first(); $this->assertEquals('new', $record['prefs']); // Restore env