From 57369d2330aa8e4f1b118108ab573cf11290372a Mon Sep 17 00:00:00 2001 From: eileen Date: Mon, 4 Dec 2017 18:10:01 +1300 Subject: [PATCH] CRM-21474 add support for setting non-required fields to 'null' When a field is not required in the database the 'null' should be pass through the pseudoconstant validation. Note the unit test on this is failing because the BAO is not respecting setting null. Follow up patch --- api/v3/Contact.php | 5 ----- api/v3/utils.php | 14 +++++++++++--- tests/phpunit/api/v3/ContactTest.php | 5 +++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/api/v3/Contact.php b/api/v3/Contact.php index 4f4912acd3..2f93c1b4b7 100644 --- a/api/v3/Contact.php +++ b/api/v3/Contact.php @@ -647,11 +647,6 @@ function _civicrm_api3_greeting_format_params($params) { } if ($greetingId) { - - if (!array_key_exists($greetingId, $greetings)) { - throw new API_Exception(ts('Invalid %1 greeting Id', array(1 => $key))); - } - if (!$customGreeting && ($greetingId == array_search('Customized', $greetings))) { throw new API_Exception(ts('Please provide a custom value for %1 greeting', array(1 => $key) diff --git a/api/v3/utils.php b/api/v3/utils.php index 8cd62eb150..3fed9d32a9 100644 --- a/api/v3/utils.php +++ b/api/v3/utils.php @@ -2280,7 +2280,7 @@ function _civicrm_api3_api_match_pseudoconstant(&$fieldValue, $entity, $fieldNam if (is_array($fieldValue)) { foreach ($fieldValue as &$value) { if (!is_array($value)) { - _civicrm_api3_api_match_pseudoconstant_value($value, $options, $fieldName); + _civicrm_api3_api_match_pseudoconstant_value($value, $options, $fieldName, CRM_Utils_Array::value('api.required', $fieldInfo)); } } // TODO: unwrap the call to implodePadded from the conditional and do it always @@ -2291,7 +2291,7 @@ function _civicrm_api3_api_match_pseudoconstant(&$fieldValue, $entity, $fieldNam } } else { - _civicrm_api3_api_match_pseudoconstant_value($fieldValue, $options, $fieldName); + _civicrm_api3_api_match_pseudoconstant_value($fieldValue, $options, $fieldName, CRM_Utils_Array::value('api.required', $fieldInfo)); } } @@ -2301,10 +2301,14 @@ function _civicrm_api3_api_match_pseudoconstant(&$fieldValue, $entity, $fieldNam * @param string $value field value * @param array $options array of options for this field * @param string $fieldName field name used in api call (not necessarily the canonical name) + * @param bool $isRequired + * Is this a required field or is 'null' an acceptable option. We allow 'null' last + * in case we have the weird situation of it being a valid option in which case our + * brains will probably explode. * * @throws API_Exception */ -function _civicrm_api3_api_match_pseudoconstant_value(&$value, $options, $fieldName) { +function _civicrm_api3_api_match_pseudoconstant_value(&$value, $options, $fieldName, $isRequired) { // If option is a key, no need to translate // or if no options are avaiable for pseudoconstant 'table' property if (array_key_exists($value, $options) || !$options) { @@ -2323,6 +2327,10 @@ function _civicrm_api3_api_match_pseudoconstant_value(&$value, $options, $fieldN $options = array_map("strtolower", $options); $newValue = array_search($newValue, $options); if ($newValue === FALSE) { + if ($value === 'null' && !$isRequired) { + // CiviMagic syntax for Nulling out the field - let it through. + return; + } throw new API_Exception("'$value' is not a valid option for field $fieldName", 2001, array('error_field' => $fieldName)); } $value = $newValue; diff --git a/tests/phpunit/api/v3/ContactTest.php b/tests/phpunit/api/v3/ContactTest.php index 08118db788..0e792c74fa 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -3621,6 +3621,11 @@ class api_v3_ContactTest extends CiviUnitTestCase { $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting')); $this->assertEquals('Dear Alan Mice', $contact['postal_greeting_display']); + // Set contact to have no postal greeting & check it is correct. + $this->callAPISuccess('Contact', 'create', array('id' => $contact['id'], 'postal_greeting_id' => 'null')); + $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $contact['id'], 'return' => 'postal_greeting')); + $this->assertEquals('', $contact['postal_greeting_display']); + //Cleanup $this->callAPISuccess('OptionValue', 'create', array('id' => $postalOption['id'], 'name' => 'Dear {contact.first_name}')); $this->customFieldDelete($ids['custom_field_id']); -- 2.25.1