From 2f69b203f2ba7e231123562e9e994d516dc24224 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Fri, 24 Jul 2020 21:44:13 -0400 Subject: [PATCH] APIv4 - Add keyword to select all custom fields --- Civi/Api4/Generic/DAOGetAction.php | 4 +++- Civi/Api4/Query/Api4SelectQuery.php | 15 +++++++++++++++ ang/api4Explorer/Explorer.js | 4 ++++ .../api/v4/Action/BasicCustomFieldTest.php | 12 ++++++++++-- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Civi/Api4/Generic/DAOGetAction.php b/Civi/Api4/Generic/DAOGetAction.php index 76b0d42337..9ad1d54adc 100644 --- a/Civi/Api4/Generic/DAOGetAction.php +++ b/Civi/Api4/Generic/DAOGetAction.php @@ -35,7 +35,9 @@ class DAOGetAction extends AbstractGetAction { use Traits\DAOActionTrait; /** - * Fields to return. Defaults to all non-custom fields `[*]`. + * Fields to return. Defaults to all non-custom fields `['*']`. + * + * The keyword `"custom.*"` selects all custom fields. So to select all core + custom fields, select `['*', 'custom.*']`. * * Use the dot notation to perform joins in the select clause, e.g. selecting `['*', 'contact.*']` from `Email::get()` * will select all fields for the email + all fields for the related contact. diff --git a/Civi/Api4/Query/Api4SelectQuery.php b/Civi/Api4/Query/Api4SelectQuery.php index ea8cad5f3f..5721e91968 100644 --- a/Civi/Api4/Query/Api4SelectQuery.php +++ b/Civi/Api4/Query/Api4SelectQuery.php @@ -187,10 +187,25 @@ class Api4SelectQuery { $select = array_merge(['id'], $select); } + // Expand the superstar 'custom.*' to select all fields in all custom groups + $customStar = array_search('custom.*', array_values($select), TRUE); + if ($customStar !== FALSE) { + $customGroups = civicrm_api4($this->getEntity(), 'getFields', [ + 'checkPermissions' => FALSE, + 'where' => [['custom_group', 'IS NOT NULL']], + ], ['custom_group' => 'custom_group']); + $customSelect = []; + foreach ($customGroups as $groupName) { + $customSelect[] = "$groupName.*"; + } + array_splice($select, $customStar, 1, $customSelect); + } + // Expand wildcards in joins (the api wrapper already expanded non-joined wildcards) $wildFields = array_filter($select, function($item) { return strpos($item, '*') !== FALSE && strpos($item, '.') !== FALSE && strpos($item, '(') === FALSE && strpos($item, ' ') === FALSE; }); + foreach ($wildFields as $item) { $pos = array_search($item, array_values($select)); $this->autoJoinFK($item); diff --git a/ang/api4Explorer/Explorer.js b/ang/api4Explorer/Explorer.js index 77bd333838..0dca04e3bc 100644 --- a/ang/api4Explorer/Explorer.js +++ b/ang/api4Explorer/Explorer.js @@ -416,6 +416,10 @@ addJoins($scope.fieldsAndJoinsAndFunctionsWithSuffixes, false, ['name', 'label']); addJoins($scope.fieldsAndJoinsAndFunctionsAndWildcards, true, ['name', 'label']); } + // Custom fields are supported if HAVING is + if (actionInfo.params.having) { + $scope.fieldsAndJoinsAndFunctionsAndWildcards.unshift({id: 'custom.*', text: 'custom.*', 'description': 'All custom fields'}); + } $scope.fieldsAndJoinsAndFunctionsAndWildcards.unshift({id: '*', text: '*', 'description': 'All core ' + $scope.entity + ' fields'}); }; diff --git a/tests/phpunit/api/v4/Action/BasicCustomFieldTest.php b/tests/phpunit/api/v4/Action/BasicCustomFieldTest.php index fbed754eeb..991f5609ff 100644 --- a/tests/phpunit/api/v4/Action/BasicCustomFieldTest.php +++ b/tests/phpunit/api/v4/Action/BasicCustomFieldTest.php @@ -140,10 +140,18 @@ class BasicCustomFieldTest extends BaseCustomValueTest { ->addWhere('MyContactFields.FavFood', '=', 'Cherry') ->execute() ->first(); - $this->assertArrayHasKey('MyContactFields.FavColor', $contact); $this->assertEquals('Red', $contact['MyContactFields.FavColor']); + // By default custom fields are not returned + $contact = Contact::get(FALSE) + ->addWhere('id', '=', $contactId1) + ->addWhere('MyContactFields.FavColor', '=', 'Red') + ->addWhere('MyContactFields.FavFood', '=', 'Cherry') + ->execute() + ->first(); + $this->assertArrayNotHasKey('MyContactFields.FavColor', $contact); + // Update 2nd set and ensure 1st hasn't changed Contact::update() ->addWhere('id', '=', $contactId1) @@ -166,7 +174,7 @@ class BasicCustomFieldTest extends BaseCustomValueTest { ->addValue('MyContactFields.FavColor', 'Blue') ->execute(); $contact = Contact::get(FALSE) - ->addSelect('MyContactFields.FavColor', 'MyContactFields2.FavColor', 'MyContactFields.FavFood', 'MyContactFields2.FavFood') + ->addSelect('custom.*') ->addWhere('id', '=', $contactId1) ->execute() ->first(); -- 2.25.1