From c752d94bd3f4672379524e77e05bd3c8d65df099 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Sat, 28 Dec 2019 09:31:40 -0500 Subject: [PATCH] Allow values to be passed to api4 GetFields So far this only filters custom fields by contact type, but values is now being passed to allow more filtering. --- Civi/Api4/Action/CustomValue/GetFields.php | 2 +- Civi/Api4/Generic/BasicGetFieldsAction.php | 12 ++++++++++ Civi/Api4/Generic/DAOGetFieldsAction.php | 2 +- Civi/Api4/Service/Spec/SpecGatherer.php | 17 +++++++++---- ang/api4Explorer/Explorer.html | 2 +- ang/api4Explorer/Explorer.js | 10 ++++---- .../api/v4/Action/BaseCustomValueTest.php | 2 +- .../api/v4/Action/BasicCustomFieldTest.php | 24 ++++++++++++------- 8 files changed, 48 insertions(+), 23 deletions(-) diff --git a/Civi/Api4/Action/CustomValue/GetFields.php b/Civi/Api4/Action/CustomValue/GetFields.php index e063f7982f..c2ca32a1a8 100644 --- a/Civi/Api4/Action/CustomValue/GetFields.php +++ b/Civi/Api4/Action/CustomValue/GetFields.php @@ -32,7 +32,7 @@ class GetFields extends \Civi\Api4\Generic\DAOGetFieldsAction { $fields = $this->_itemsToGet('name'); /** @var \Civi\Api4\Service\Spec\SpecGatherer $gatherer */ $gatherer = \Civi::container()->get('spec_gatherer'); - $spec = $gatherer->getSpec('Custom_' . $this->getCustomGroup(), $this->getAction(), $this->includeCustom); + $spec = $gatherer->getSpec('Custom_' . $this->getCustomGroup(), $this->getAction(), $this->includeCustom, $this->values); return SpecFormatter::specToArray($spec->getFields($fields), $this->loadOptions); } diff --git a/Civi/Api4/Generic/BasicGetFieldsAction.php b/Civi/Api4/Generic/BasicGetFieldsAction.php index c0c851661b..5c2b0ccb11 100644 --- a/Civi/Api4/Generic/BasicGetFieldsAction.php +++ b/Civi/Api4/Generic/BasicGetFieldsAction.php @@ -30,6 +30,9 @@ use Civi\Api4\Utils\ActionUtil; * @method $this setLoadOptions(bool $value) * @method bool getLoadOptions() * @method $this setAction(string $value) + * @method $this addValue(string $value) + * @method $this setValues(array $values) + * @method array getValues() */ class BasicGetFieldsAction extends BasicGetAction { @@ -41,10 +44,19 @@ class BasicGetFieldsAction extends BasicGetAction { protected $loadOptions = FALSE; /** + * Fields will be returned appropriate to the specified action (get, create, delete, etc.) + * * @var string */ protected $action = 'get'; + /** + * Fields will be returned appropriate to the specified values (e.g. ['contact_type' => 'Individual']) + * + * @var array + */ + protected $values = []; + /** * To implement getFields for your own entity: * diff --git a/Civi/Api4/Generic/DAOGetFieldsAction.php b/Civi/Api4/Generic/DAOGetFieldsAction.php index e3a510b470..edf7684c65 100644 --- a/Civi/Api4/Generic/DAOGetFieldsAction.php +++ b/Civi/Api4/Generic/DAOGetFieldsAction.php @@ -51,7 +51,7 @@ class DAOGetFieldsAction extends BasicGetFieldsAction { if ($fields) { $this->includeCustom = strpos(implode('', $fields), '.') !== FALSE; } - $spec = $gatherer->getSpec($this->getEntityName(), $this->getAction(), $this->includeCustom); + $spec = $gatherer->getSpec($this->getEntityName(), $this->getAction(), $this->includeCustom, $this->values); return SpecFormatter::specToArray($spec->getFields($fields), $this->loadOptions); } diff --git a/Civi/Api4/Service/Spec/SpecGatherer.php b/Civi/Api4/Service/Spec/SpecGatherer.php index 8a91d09e90..d10c95ecf1 100644 --- a/Civi/Api4/Service/Spec/SpecGatherer.php +++ b/Civi/Api4/Service/Spec/SpecGatherer.php @@ -46,18 +46,19 @@ class SpecGatherer { * * @param string $entity * @param string $action - * @param $includeCustom + * @param bool $includeCustom + * @param array $values * * @return \Civi\Api4\Service\Spec\RequestSpec */ - public function getSpec($entity, $action, $includeCustom) { + public function getSpec($entity, $action, $includeCustom, $values = []) { $specification = new RequestSpec($entity, $action); // Real entities if (strpos($entity, 'Custom_') !== 0) { $this->addDAOFields($entity, $action, $specification); if ($includeCustom && array_key_exists($entity, \CRM_Core_SelectValues::customGroupExtends())) { - $this->addCustomFields($entity, $specification); + $this->addCustomFields($entity, $specification, $values); } } // Custom pseudo-entities @@ -114,12 +115,18 @@ class SpecGatherer { /** * @param string $entity * @param \Civi\Api4\Service\Spec\RequestSpec $specification + * @param array $values + * @throws \API_Exception */ - private function addCustomFields($entity, RequestSpec $specification) { - $extends = ($entity == 'Contact') ? ['Contact', 'Individual', 'Organization', 'Household'] : [$entity]; + private function addCustomFields($entity, RequestSpec $specification, $values = []) { + $extends = [$entity]; + if ($entity === 'Contact') { + $extends = !empty($values['contact_type']) ? [$values['contact_type'], 'Contact'] : ['Contact', 'Individual', 'Organization', 'Household']; + } $customFields = CustomField::get() ->setCheckPermissions(FALSE) ->addWhere('custom_group.extends', 'IN', $extends) + ->addWhere('custom_group.is_multiple', '=', '0') ->setSelect(['custom_group.name', 'custom_group_id', 'name', 'label', 'data_type', 'html_type', 'is_searchable', 'is_search_range', 'weight', 'is_active', 'is_view', 'option_group_id', 'default_value', 'date_format', 'time_format', 'start_date_years', 'end_date_years', 'help_pre', 'help_post']) ->execute(); diff --git a/ang/api4Explorer/Explorer.html b/ang/api4Explorer/Explorer.html index bbfd35b959..927513a5b9 100644 --- a/ang/api4Explorer/Explorer.html +++ b/ang/api4Explorer/Explorer.html @@ -74,7 +74,7 @@ values *
- +
diff --git a/ang/api4Explorer/Explorer.js b/ang/api4Explorer/Explorer.js index 28ca9ae116..982f618d3f 100644 --- a/ang/api4Explorer/Explorer.js +++ b/ang/api4Explorer/Explorer.js @@ -105,9 +105,9 @@ return container; } - function getFieldList(source) { + function getFieldList(action) { var fields = [], - fieldInfo = _.findWhere(getEntity().actions, {name: $scope.action}).fields; + fieldInfo = _.findWhere(getEntity().actions, {name: action}).fields; formatForSelect2(fieldInfo, fields, 'name', ['description', 'required', 'default_value']); return fields; } @@ -159,7 +159,7 @@ }; $scope.valuesFields = function() { - var fields = _.cloneDeep($scope.fields); + var fields = _.cloneDeep($scope.action === 'getFields' ? getFieldList($scope.params.action || 'get') : $scope.fields); // Disable fields that are already in use _.each($scope.params.values || [], function(val) { (_.findWhere(fields, {id: val[0]}) || {}).disabled = true; @@ -265,7 +265,7 @@ } if ($scope.action) { var actionInfo = _.findWhere(actions, {id: $scope.action}); - $scope.fields = getFieldList(); + $scope.fields = getFieldList($scope.action); if (_.contains(['get', 'update', 'delete', 'replace'], $scope.action)) { $scope.fieldsAndJoins = addJoins($scope.fields); } else { @@ -658,7 +658,7 @@ var ts = scope.ts = CRM.ts(), multi = _.includes(['IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN'], scope.data.op), entity = $routeParams.api4entity, - action = $routeParams.api4action; + action = scope.data.action || $routeParams.api4action; function destroyWidget() { var $el = $(element); diff --git a/tests/phpunit/api/v4/Action/BaseCustomValueTest.php b/tests/phpunit/api/v4/Action/BaseCustomValueTest.php index 2270e0ac3f..3ad87d3d5a 100644 --- a/tests/phpunit/api/v4/Action/BaseCustomValueTest.php +++ b/tests/phpunit/api/v4/Action/BaseCustomValueTest.php @@ -43,7 +43,7 @@ abstract class BaseCustomValueTest extends UnitTestCase { ], ]; - $this->dropByPrefix('civicrm_value_mycontact'); + $this->dropByPrefix('civicrm_value_my'); $this->cleanup($cleanup_params); } diff --git a/tests/phpunit/api/v4/Action/BasicCustomFieldTest.php b/tests/phpunit/api/v4/Action/BasicCustomFieldTest.php index b0f4d02be2..0c6162cb61 100644 --- a/tests/phpunit/api/v4/Action/BasicCustomFieldTest.php +++ b/tests/phpunit/api/v4/Action/BasicCustomFieldTest.php @@ -34,8 +34,8 @@ class BasicCustomFieldTest extends BaseCustomValueTest { $customGroup = CustomGroup::create() ->setCheckPermissions(FALSE) - ->addValue('name', 'MyContactFields') - ->addValue('extends', 'Contact') + ->addValue('name', 'MyIndividualFields') + ->addValue('extends', 'Individual') ->execute() ->first(); @@ -47,39 +47,45 @@ class BasicCustomFieldTest extends BaseCustomValueTest { ->addValue('data_type', 'String') ->execute(); + // Individual fields should show up when contact_type = null|Individual but not other contact types + $getFields = Contact::getFields()->setCheckPermissions(FALSE); + $this->assertContains('MyIndividualFields.FavColor', $getFields->execute()->column('name')); + $this->assertContains('MyIndividualFields.FavColor', $getFields->setValues(['contact_type' => 'Individual'])->execute()->column('name')); + $this->assertNotContains('MyIndividualFields.FavColor', $getFields->setValues(['contact_type' => 'Household'])->execute()->column('name')); + $contactId = Contact::create() ->setCheckPermissions(FALSE) ->addValue('first_name', 'Johann') ->addValue('last_name', 'Tester') ->addValue('contact_type', 'Individual') - ->addValue('MyContactFields.FavColor', 'Red') + ->addValue('MyIndividualFields.FavColor', 'Red') ->execute() ->first()['id']; $contact = Contact::get() ->setCheckPermissions(FALSE) ->addSelect('first_name') - ->addSelect('MyContactFields.FavColor') + ->addSelect('MyIndividualFields.FavColor') ->addWhere('id', '=', $contactId) - ->addWhere('MyContactFields.FavColor', '=', 'Red') + ->addWhere('MyIndividualFields.FavColor', '=', 'Red') ->execute() ->first(); - $this->assertEquals('Red', $contact['MyContactFields.FavColor']); + $this->assertEquals('Red', $contact['MyIndividualFields.FavColor']); Contact::update() ->addWhere('id', '=', $contactId) - ->addValue('MyContactFields.FavColor', 'Blue') + ->addValue('MyIndividualFields.FavColor', 'Blue') ->execute(); $contact = Contact::get() ->setCheckPermissions(FALSE) - ->addSelect('MyContactFields.FavColor') + ->addSelect('MyIndividualFields.FavColor') ->addWhere('id', '=', $contactId) ->execute() ->first(); - $this->assertEquals('Blue', $contact['MyContactFields.FavColor']); + $this->assertEquals('Blue', $contact['MyIndividualFields.FavColor']); } public function testWithTwoFields() { -- 2.25.1